case VEC_WIDEN_MULT_ODD_EXPR:
case VEC_WIDEN_LSHIFT_HI_EXPR:
case VEC_WIDEN_LSHIFT_LO_EXPR:
+ case VEC_WIDEN_PLUS_HI_EXPR:
+ case VEC_WIDEN_PLUS_LO_EXPR:
+ case VEC_WIDEN_MINUS_HI_EXPR:
+ case VEC_WIDEN_MINUS_LO_EXPR:
case VEC_PERM_EXPR:
case VEC_DUPLICATE_EXPR:
case VEC_SERIES_EXPR:
case WIDEN_MULT_EXPR:
case WIDEN_MULT_PLUS_EXPR:
case WIDEN_MULT_MINUS_EXPR:
+ case WIDEN_PLUS_EXPR:
+ case WIDEN_MINUS_EXPR:
if (SCALAR_INT_MODE_P (GET_MODE (op0))
&& SCALAR_INT_MODE_P (mode))
{
op1 = simplify_gen_unary (ZERO_EXTEND, mode, op1, inner_mode);
else
op1 = simplify_gen_unary (SIGN_EXTEND, mode, op1, inner_mode);
+ if (TREE_CODE (exp) == WIDEN_PLUS_EXPR)
+ return simplify_gen_binary (PLUS, mode, op0, op1);
+ else if (TREE_CODE (exp) == WIDEN_MINUS_EXPR)
+ return simplify_gen_binary (MINUS, mode, op0, op1);
op0 = simplify_gen_binary (MULT, mode, op0, op1);
if (TREE_CODE (exp) == WIDEN_MULT_EXPR)
return op0;
--- /dev/null
+// PR debug/108967
+// { dg-do compile }
+
+struct F { unsigned short r[8]; };
+extern void foo (F);
+
+static inline F
+bar (F a, F b)
+{
+ for (int i = 0; i < 8; ++i)
+ a.r[i] = a.r[i] + b.r[i] < (unsigned short) -1 ? a.r[i] + b.r[i] : (unsigned short) -1;
+ return a;
+}
+
+static inline void
+baz (F v)
+{
+ foo (v);
+}
+
+void
+qux (F a, F b)
+{
+ F c = bar (a, b);
+ baz (c);
+}
+
+static inline F
+corge (F a, F b)
+{
+ for (int i = 0; i < 8; ++i)
+ a.r[i] = a.r[i] - b.r[i] > 0 ? a.r[i] - b.r[i] : 0;
+ return a;
+}
+
+void
+garply (F a, F b)
+{
+ F c = corge (a, b);
+ baz (c);
+}