The ICE happens when building Newlib with the GCN compiler: during GIMPLE pass: vect In file included from src/accel_newlib-mainline/newlib/libc/stdlib/l64a.c:24: src/accel_newlib-mainline/newlib/libc/include/stdlib.h: In function 'l64a': src/accel_newlib-mainline/newlib/libc/include/stdlib.h:195:9: internal compiler error: in vect_peel_nonlinear_iv_init, at tree-vect-loop.cc:9420 195 | char * l64a (long __input); | ^~~~
Hi, This does not contain enough information for me to try to reproduce the issue. Can you give me the full target triple, compile flag and how the compiler was configured? A reproducer would be helpful too.
Created attachment 56958 [details] Reduced testcase ( $ amdgcn-amdhsa-gcc -g -O2 inp5.i -march=gfx900 during GIMPLE pass: vect inp5.i: In function '_l64a_r': inp5.i:4:1: internal compiler error: in vect_peel_nonlinear_iv_init, at tree-vect-loop.cc:9420 4 | _l64a_r (struct _reent *rptr, | ^~~~~~~ 0x94cc17 vect_peel_nonlinear_iv_init(gimple**, tree_node*, tree_node*, tree_node*, vect_induction_op_type) /net/build5-fossa-cs/scratch/tburnus/fsf.mainline.x86_64-linux-gnu-amdgcn/src/gcc-mainline/gcc/tree-vect-loop.cc:9420 0x148bb04 vect_update_ivs_after_vectorizer src/gcc-mainline/gcc/tree-vect-loop-manip.cc:2267 0x1498153 vect_do_peeling(_loop_vec_info*, tree_node*, tree_node*, tree_node**, tree_node**, tree_node**, int, bool, bool, tree_node**) src/gcc-mainline/gcc/tree-vect-loop-manip.cc:3399 0x148714e vect_transform_loop(_loop_vec_info*, gimple*) src/gcc-mainline/gcc/tree-vect-loop.cc:11911 0x14c9544 vect_transform_loops src/gcc-mainline/gcc/tree-vectorizer.cc:1006 0x14c9bc3 try_vectorize_loop_1 src/gcc-mainline/gcc/tree-vectorizer.cc:1152 0x14c9bc3 try_vectorize_loop src/gcc-mainline/gcc/tree-vectorizer.cc:1182 0x14ca224 execute src/gcc-mainline/gcc/tree-vectorizer.cc:1298 * * * Breakpoint 1, vect_peel_nonlinear_iv_init (stmts=0x7fffffffd698, init_expr=0x7ffff7a56948, skip_niters=0x7ffff7bb8798, step_expr=0x7ffff7a64ba0, induction_type=vect_step_op_shr) at src/gcc-mainline/gcc/tree-vect-loop.cc:9420 9420 gcc_assert (TREE_CODE (skip_niters) == INTEGER_CST); (gdb) p debug_tree(skip_niters) <ssa_name 0x7ffff7bb8798 type <integer_type 0x7ffff7b5e3f0 public unsigned SI size <integer_cst 0x7ffff7a64768 constant 32> unit-size <integer_cst 0x7ffff7a64780 constant 4> align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff7b5e3f0 precision:32 min <integer_cst 0x7ffff7b752d0 0> max <integer_cst 0x7ffff7a64b28 4294967295>> def_stmt GIMPLE_NOP version:54> $2 = void
Thanks, taking a look.
Hmm so can't seem to reproduce it with x86_64 or aarch64. let me build a --target=amdgcn-amdhsa
While higher at the call stack: #3 0x000000000148714f in vect_transform_loop (loop_vinfo=loop_vinfo@entry=0x350f2a0, loop_vectorized_call=loop_vectorized_call@entry=0x0) at src/gcc-mainline/gcc/tree-vect-loop.cc:11911 11911 epilogue = vect_do_peeling (loop_vinfo, niters, nitersm1, &niters_vector, (gdb) p debug_tree(niters) <integer_cst 0x7ffff7bb2030 type <integer_type 0x7ffff7b5e3f0> constant 6> One level down: #2 0x0000000001498154 in vect_do_peeling (loop_vinfo=loop_vinfo@entry=0x350f2a0, niters=<optimized out>, niters@entry=0x7ffff7bb2030, nitersm1=nitersm1@entry=0x7ffff7bb2c78, niters_vector=niters_vector@entry=0x7fffffffda60, step_vector=step_vector@entry=0x7fffffffda68, niters_vector_mult_vf_var=niters_vector_mult_vf_var@entry=0x7fffffffda70, th=<optimized out>, check_profitability=<optimized out>, niters_no_overflow=<optimized out>, advance=<optimized out>) at src/gcc-mainline/gcc/tree-vect-loop-manip.cc:3399 3399 vect_update_ivs_after_vectorizer (loop_vinfo, niters_vector_mult_vf, where niters_vector_mult_vf is ssa_name that fails in the assert. The variable seems to be generated a few lines up in the same function (line 3375 and following): if (!integer_onep (*step_vector)) { /* On exit from the loop we will have an easy way of calcalating NITERS_VECTOR / STEP * STEP. Install a dummy definition until then. */ niters_vector_mult_vf = make_ssa_name (TREE_TYPE (*niters_vector)); SSA_NAME_DEF_STMT (niters_vector_mult_vf) = gimple_build_nop (); *niters_vector_mult_vf_var = niters_vector_mult_vf; } else vect_gen_vector_loop_niters_mult_vf (loop_vinfo, *niters_vector, &niters_vector_mult_vf);
and for that condition, we have: 3375 if (!integer_onep (*step_vector)) (gdb) p debug_tree(*step_vector) <integer_cst 0x7ffff7bb2f48 type <integer_type 0x7ffff7b5e3f0> constant 8>
ok, managed to reproduce using a cross cc1. This seems to happen because the vectorizer decides to use partial vectors to vectorize the loop and the target picks a nonlinear induction step which we can't support for early breaks. The attached patch fixes it by rejecting these kind of inductions when partial vectors are forced. I'll submit the patch for when maintainers are back from holidays.
Created attachment 56959 [details] nonlinear IV
*** Bug 113169 has been marked as a duplicate of this bug. ***
Patch submitted
(In reply to Tamar Christina from comment #7) > This seems to happen because the vectorizer decides to use partial vectors > to vectorize the loop and the target picks a nonlinear induction step which > we can't support for early breaks. In which hook is this selected? I'm not aware of this being a deliberate choice we made...
(In reply to Andrew Stubbs from comment #11) > (In reply to Tamar Christina from comment #7) > > This seems to happen because the vectorizer decides to use partial vectors > > to vectorize the loop and the target picks a nonlinear induction step which > > we can't support for early breaks. > > In which hook is this selected? > > I'm not aware of this being a deliberate choice we made... I haven't looked into why on the target we get a nonlinear induction (mostly because I don't know much about the target). I however wasn't able to reproduce it on SVE and x86_64 even when forcing partial vectors. So I guess it's more accurate to say "something about the target" is making the vectorizer pick a nonlinear induction. most likely missing support for something. Note that the testcase does work if partial vectors is turned off. So It should work fine if the vectorizer retries without partial vectors. waiting for Richi to come back from holiday to review the patch and should be fixed.
The master branch has been updated by Tamar Christina <tnfchris@gcc.gnu.org>: https://gcc.gnu.org/g:cbf569486b2decbde0308f9f4d0f0837e4cfefd9 commit r14-7036-gcbf569486b2decbde0308f9f4d0f0837e4cfefd9 Author: Tamar Christina <tamar.christina@arm.com> Date: Tue Jan 9 11:16:16 2024 +0000 middle-end: rejects loops with nonlinear inductions and early breaks [PR113163] We can't support nonlinear inductions other than neg when vectorizing early breaks and iteration count is known. For early break we currently require a peeled epilog but in these cases we can't compute the remaining values. gcc/ChangeLog: PR middle-end/113163 * tree-vect-loop-manip.cc (vect_can_peel_nonlinear_iv_p): Reject non-linear inductions that aren't supported. gcc/testsuite/ChangeLog: PR middle-end/113163 * gcc.target/gcn/pr113163.c: New test.
Fixed, thanks for the report.