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; + }