copy. This saves at least one insn, more if register allocation can
eliminate the copy.
+ We cannot do this if the involved modes have more than one elements,
+ like for vector or complex modes.
+
We cannot do this if the destination of the first assignment is a
condition code register. We eliminate this case by making sure
the SET_DEST and SET_SRC have the same mode.
&& GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0))) == SIGN_EXTEND
&& (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0)))
== GET_MODE (SET_SRC (XVECEXP (newpat, 0, 0))))
+ && ! VECTOR_MODE_P (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0))))
+ && ! COMPLEX_MODE_P (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0))))
&& GET_CODE (XVECEXP (newpat, 0, 1)) == SET
&& rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1)),
XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0))
--- /dev/null
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-slp-vectorize -fno-vect-cost-model" } */
+/* { dg-additional-options "-msse4" { target sse4_runtime} } */
+
+int __attribute__((noipa)) addup(signed char *num) {
+ int val = num[0] + num[1] + num[2] + num[3];
+ if (num[3] >= 0)
+ val++;
+ return val;
+}
+
+int main(int, char *[])
+{
+ signed char num[4] = {1, 1, 1, -1};
+ if (addup(num) != 2)
+ __builtin_abort();
+ return 0;
+}