]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
vect: Allow reduc_index != 1 for COND_OPs.
authorRobin Dapp <rdapp@ventanamicro.com>
Tue, 21 Nov 2023 11:51:12 +0000 (12:51 +0100)
committerRobin Dapp <rdapp@ventanamicro.com>
Tue, 21 Nov 2023 20:06:13 +0000 (21:06 +0100)
In PR112406 Tamar found another problem with COND_OP reductions.
I wrongly assumed that the reduction variable will always remain in
operand 1, just as we create the COND_OP in ifcvt.  But of course,
addition being commutative, we are free to swap operand 1 and 2 and we
end up with e.g.

 _ifc__60 = .COND_ADD (_2, _6, MADPictureC1_lsm.10_25, MADPictureC1_lsm.10_25);

which does not pass the asserts I put in place.

This patch removes this restriction and allows the reduction index to be
2 as well.

gcc/ChangeLog:

PR middle-end/112406

* tree-vect-loop.cc (vectorize_fold_left_reduction): Allow
reduction index != 1.
(vect_transform_reduction): Handle reduction index != 1.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/pr112406-2.c: New test.

gcc/testsuite/gcc.target/aarch64/pr112406-2.c [new file with mode: 0644]
gcc/tree-vect-loop.cc

diff --git a/gcc/testsuite/gcc.target/aarch64/pr112406-2.c b/gcc/testsuite/gcc.target/aarch64/pr112406-2.c
new file mode 100644 (file)
index 0000000..bb6e9cf
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { aarch64*-*-* } } } */
+/* { dg-options "-march=armv8-a+sve -Ofast" } */
+
+double MADPictureC1;
+extern int PictureRejected[];
+int PictureMAD_0, MADModelEstimator_n_windowSize_i, MADModelEstimator_n_windowSize_oneSampleQ;
+
+void MADModelEstimator_n_windowSize() {
+  int estimateX2 = 0;
+  for (; MADModelEstimator_n_windowSize_i; MADModelEstimator_n_windowSize_i++) {
+    if (MADModelEstimator_n_windowSize_oneSampleQ &&
+        !PictureRejected[MADModelEstimator_n_windowSize_i])
+      estimateX2 = 1;
+    if (!PictureRejected[MADModelEstimator_n_windowSize_i])
+      MADPictureC1 += PictureMAD_0;
+  }
+  if (estimateX2)
+    for (;;)
+      ;
+}
index a73a533beb1b90badf6a43b48649cb37e3d2c346..caaed977c89d56819ec993cf89513c6e2cee16d0 100644 (file)
@@ -7071,7 +7071,7 @@ vectorize_fold_left_reduction (loop_vec_info loop_vinfo,
     op0 = ops[1 - reduc_index];
   else
     {
-      op0 = ops[2];
+      op0 = ops[2 + (1 - reduc_index)];
       opmask = ops[0];
       gcc_assert (!slp_node);
     }
@@ -8456,7 +8456,9 @@ vect_transform_reduction (loop_vec_info loop_vinfo,
       gcc_assert (code == IFN_COND_ADD || code == IFN_COND_SUB
                  || code == IFN_COND_MUL || code == IFN_COND_AND
                  || code == IFN_COND_IOR || code == IFN_COND_XOR);
-      gcc_assert (op.num_ops == 4 && (op.ops[1] == op.ops[3]));
+      gcc_assert (op.num_ops == 4
+                 && (op.ops[reduc_index]
+                     == op.ops[internal_fn_else_index ((internal_fn) code)]));
     }
 
   bool masked_loop_p = LOOP_VINFO_FULLY_MASKED_P (loop_vinfo);
@@ -8499,12 +8501,14 @@ vect_transform_reduction (loop_vec_info loop_vinfo,
     {
       /* For a conditional operation pass the truth type as mask
         vectype.  */
-      gcc_assert (single_defuse_cycle && reduc_index == 1);
+      gcc_assert (single_defuse_cycle
+                 && (reduc_index == 1 || reduc_index == 2));
       vect_get_vec_defs (loop_vinfo, stmt_info, slp_node, ncopies,
-                        op.ops[0], &vec_oprnds0,
-                        truth_type_for (vectype_in),
-                        NULL_TREE, &vec_oprnds1, NULL_TREE,
-                        op.ops[2], &vec_oprnds2, NULL_TREE);
+                        op.ops[0], &vec_oprnds0, truth_type_for (vectype_in),
+                        reduc_index == 1 ? NULL_TREE : op.ops[1],
+                        &vec_oprnds1, NULL_TREE,
+                        reduc_index == 2 ? NULL_TREE : op.ops[2],
+                        &vec_oprnds2, NULL_TREE);
     }
 
   /* For single def-use cycles get one copy of the vectorized reduction