]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/119640 - ICE with vectorized shift placement
authorRichard Biener <rguenther@suse.de>
Mon, 7 Apr 2025 09:27:19 +0000 (11:27 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 7 Apr 2025 11:12:34 +0000 (13:12 +0200)
When the whole shift is invariant but the shift amount needs
to be converted and a vector shift used we can mess up placement
of vector stmts because we do not make SLP scheduling aware of
the need to insert code for it.  The following mitigates this
by more conservative placement of such code in vectorizable_shift.

PR tree-optimization/119640
* tree-vect-stmts.cc (vectorizable_shift): Always insert code
for one of our SLP operands before the code for the vector
shift itself.

* gcc.dg/vect/pr119640.c: New testcase.

gcc/testsuite/gcc.dg/vect/pr119640.c [new file with mode: 0644]
gcc/tree-vect-stmts.cc

diff --git a/gcc/testsuite/gcc.dg/vect/pr119640.c b/gcc/testsuite/gcc.dg/vect/pr119640.c
new file mode 100644 (file)
index 0000000..8872817
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-funswitch-loops" } */
+
+int save, mask_nbits;
+
+void execute(long imm)
+{
+  long shift = 0;
+  int destReg[4];
+  for (unsigned i = 0; i < 4; i++)
+    {
+      if (imm)
+       shift = 1ULL << mask_nbits;
+      destReg[i] = shift;
+      save = destReg[0];
+    }
+}
index 3005ae6eaaea6e039278c5a85c58318013f11007..7f874354e75e8d4d3a7196df4e9b559ac641827c 100644 (file)
@@ -6750,13 +6750,16 @@ vectorizable_shift (vec_info *vinfo,
     {
       if (was_scalar_shift_arg)
        {
-         /* If the argument was the same in all lanes create
-            the correctly typed vector shift amount directly.  */
+         /* If the argument was the same in all lanes create the
+            correctly typed vector shift amount directly.  Note
+            we made SLP scheduling think we use the original scalars,
+            so place the compensation code next to the shift which
+            is conservative.  See PR119640 where it otherwise breaks.  */
          op1 = fold_convert (TREE_TYPE (vectype), op1);
          op1 = vect_init_vector (vinfo, stmt_info, op1, TREE_TYPE (vectype),
-                                 !loop_vinfo ? gsi : NULL);
+                                 gsi);
          vec_oprnd1 = vect_init_vector (vinfo, stmt_info, op1, vectype,
-                                        !loop_vinfo ? gsi : NULL);
+                                        gsi);
          vec_oprnds1.create (slp_node->vec_stmts_size);
          for (k = 0; k < slp_node->vec_stmts_size; k++)
            vec_oprnds1.quick_push (vec_oprnd1);