https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96698

            Bug ID: 96698
           Summary: aarch64: ICE during GIMPLE pass:vect
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yangyang305 at huawei dot com
  Target Milestone: ---

Hi, gcc-trunk ICEs when compiling the following testcase with -O3:

void test(int a, int* i) {
  for (; a < 5; ++a) {
    int b = 0;
    int c = 0;
    for (; b != -11; b--)
      for (int d = 0; d ==0; d++) {
        *i += c & a;
        c = b;
      }
  }
}

during GIMPLE pass: vect
/home/yangyang/Testcase/ICE-274/test.c: In function ‘test’:
/home/yangyang/Testcase/ICE-274/test.c:1:6: internal compiler error: in
vect_transform_stmt, at tree-vect-stmts.c:10940
    1 | void test(int a, int* i) {
      |      ^~~~
0xf229ab vect_transform_stmt(vec_info*, _stmt_vec_info*, gimple_stmt_iterator*,
_slp_tree*, _slp_instance*)
        ../../gcc/tree-vect-stmts.c:10940
0xf3cdcb vect_transform_loop(_loop_vec_info*, gimple*)
        ../../gcc/tree-vect-loop.c:8972
0xf5aafb try_vectorize_loop_1
        ../../gcc/tree-vectorizer.c:1093
0xf5b7b7 vectorize_loops()
        ../../gcc/tree-vectorizer.c:1230
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

There are two PHIs in the inner loop:

<bb 5> [local count: 719407024]:
  # b_26 = PHI <0(4), b_15(10)>
  # c_27 = PHI <0(4), b_26(10)>

# c_27 = PHI <0(4), b_26(10)> is detected to be a vectorizable nested cycle by
vect_is_simple_reduction,  which seems to be wrong. Also # b_26 = PHI <0(4),
b_15(10)> is marked as the reduc_def of # c_27 = PHI <0(4), b_26(10)>, so when
doing vect_transform_stmt for it, gcc tries to add args for the vector version
of  # b_26 = PHI <0(4), b_15(10)> which has not been generated yet, leading to
the ICE.

This  failure was introduced by the following commit:
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=4a8841c0413d52261a8d024577381582d07a866a

    tree-vect-loop.c (vect_is_simple_reduction): Simplify and allow stmts other
than GIMPLE_ASSIGN in nested cycles.

    2019-10-09  Richard Biener  <rguent...@suse.de>

    * tree-vect-loop.c (vect_is_simple_reduction): Simplify and
    allow stmts other than GIMPLE_ASSIGN in nested cycles.

    * gcc.dg/vect/vect-outer-call-1.c: New testcase.

It simplifies and refactors vect_is_simple_reduction to make sure to not reject
nested cycle vectorization just beacuse there are calls in the innermost loop.
However, the analysis of phi nodes is moved from above the analysis of nested
cycles to below the analysis of nested cycles,  which seems to be irrelevant to
the purpose of this commit and results in the ICE.

I have prepared the following patch to fix this problem, this patch simply
moves the analysis of phi nodes above the analysis of nested cycle. Bootstrap
and tested on both aarch64 and x86 Linux platform, no new regression witnessed.

diff -uprN a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -3348,28 +3348,6 @@ vect_is_simple_reduction (loop_vec_info loop_info,
stmt_vec_info phi_info,
        }
     }

-  /* If we are vectorizing an inner reduction we are executing that
-     in the original order only in case we are not dealing with a
-     double reduction.  */
-  if (nested_in_vect_loop && !inner_loop_of_double_reduc)
-    {
-      if (dump_enabled_p ())
-       report_vect_op (MSG_NOTE, def_stmt_info->stmt,
-                       "detected nested cycle: ");
-      return def_stmt_info;
-    }
-
-  /* If this isn't a nested cycle or if the nested cycle reduction value
-     is used ouside of the inner loop we cannot handle uses of the reduction
-     value.  */
-  if (nlatch_def_loop_uses > 1 || nphi_def_loop_uses > 1)
-    {
-      if (dump_enabled_p ())
-       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                        "reduction used in loop.\n");
-      return NULL;
-    }
-
   /* If DEF_STMT is a phi node itself, we expect it to have a single argument
      defined in the inner loop.  */
   if (gphi *def_stmt = dyn_cast <gphi *> (def_stmt_info->stmt))
@@ -3405,6 +3383,28 @@ vect_is_simple_reduction (loop_vec_info loop_info,
stmt_vec_info phi_info,
       return NULL;
     }

+  /* If we are vectorizing an inner reduction we are executing that
+     in the original order only in case we are not dealing with a
+     double reduction.  */
+  if (nested_in_vect_loop && !inner_loop_of_double_reduc)
+    {
+      if (dump_enabled_p ())
+       report_vect_op (MSG_NOTE, def_stmt_info->stmt,
+                       "detected nested cycle: ");
+      return def_stmt_info;
+    }
+
+  /* If this isn't a nested cycle or if the nested cycle reduction value
+     is used ouside of the inner loop we cannot handle uses of the reduction
+     value.  */
+  if (nlatch_def_loop_uses > 1 || nphi_def_loop_uses > 1)
+    {
+      if (dump_enabled_p ())
+       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                       "reduction used in loop.\n");
+      return NULL;
+    }

Reply via email to