When we pattern recognize integer multiplication with a constant
and need a conversion to unsigned we fail to set the appropriate
unsigned vector type on the pattern stmt so it gets the vector
type of the signed result.  This confuses code dealing with UB
for reduction vectorization but will also result in wrong-code
in the non-reduction case.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

        PR tree-optimization/125646
        * tree-vect-patterns.cc (vect_synth_mult_by_constant): Assign
        vector type to the pattern def sequence stmts.

        * gcc.dg/vect/pr125646.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/pr125646.c | 17 +++++++++++++++++
 gcc/tree-vect-patterns.cc            |  8 ++++----
 2 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr125646.c

diff --git a/gcc/testsuite/gcc.dg/vect/pr125646.c 
b/gcc/testsuite/gcc.dg/vect/pr125646.c
new file mode 100644
index 00000000000..223b98cd081
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr125646.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-fre -fno-tree-forwprop" } */
+
+int a;
+int main()
+{
+  int c = 1;
+  while (1)
+    {
+      a = 2 * a;
+      c = -1 - 1 / c;
+      if (!c)
+       break;
+      a = -2 * a;
+    }
+  return 0;
+}
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 5f5e3fb6201..393b7e5eb7a 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -4396,7 +4396,7 @@ vect_synth_mult_by_constant (vec_info *vinfo, tree op, 
tree val,
     {
       tree tmp_op = vect_recog_temp_ssa_var (multtype, NULL);
       stmt = gimple_build_assign (tmp_op, CONVERT_EXPR, op);
-      append_pattern_def_seq (vinfo, stmt_vinfo, stmt);
+      append_pattern_def_seq (vinfo, stmt_vinfo, stmt, vectype);
       op = tmp_op;
     }
 
@@ -4478,7 +4478,7 @@ vect_synth_mult_by_constant (vec_info *vinfo, tree op, 
tree val,
         but rather return it directly.  */
 
       if ((i < alg.ops - 1) || needs_fixup || cast_to_unsigned_p)
-       append_pattern_def_seq (vinfo, stmt_vinfo, stmt);
+       append_pattern_def_seq (vinfo, stmt_vinfo, stmt, vectype);
       accumulator = accum_tmp;
     }
   if (variant == negate_variant)
@@ -4487,7 +4487,7 @@ vect_synth_mult_by_constant (vec_info *vinfo, tree op, 
tree val,
       stmt = gimple_build_assign (accum_tmp, NEGATE_EXPR, accumulator);
       accumulator = accum_tmp;
       if (cast_to_unsigned_p)
-       append_pattern_def_seq (vinfo, stmt_vinfo, stmt);
+       append_pattern_def_seq (vinfo, stmt_vinfo, stmt, vectype);
     }
   else if (variant == add_variant)
     {
@@ -4495,7 +4495,7 @@ vect_synth_mult_by_constant (vec_info *vinfo, tree op, 
tree val,
       stmt = gimple_build_assign (accum_tmp, PLUS_EXPR, accumulator, op);
       accumulator = accum_tmp;
       if (cast_to_unsigned_p)
-       append_pattern_def_seq (vinfo, stmt_vinfo, stmt);
+       append_pattern_def_seq (vinfo, stmt_vinfo, stmt, vectype);
     }
   /* Move back to a signed if needed.  */
   if (cast_to_unsigned_p)
-- 
2.51.0

Reply via email to