https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70904
Vladimir Makarov <vmakarov at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |vmakarov at gcc dot gnu.org --- Comment #3 from Vladimir Makarov <vmakarov at gcc dot gnu.org> --- (In reply to Jiong Wang from comment #2) > (In reply to Zdenek Sojka from comment #0) > > Created attachment 38393 [details] > > reduced testcase > > > > Compiler output: > > $ aarch64-unknown-linux-gnu-gcc -O -fno-split-wide-types testcase.c > > testcase.c: In function 'foo': > > testcase.c:8:1: internal compiler error: Max. number of generated reload > > insns per insn is achieved (90) > > > > } > > ^ > > 0x9dafa9 lra_constraints(bool) > > /repo/gcc-trunk/gcc/lra-constraints.c:4440 > > 0x9c63dc lra(_IO_FILE*) > > /repo/gcc-trunk/gcc/lra.c:2290 > > 0x96de19 do_reload > > /repo/gcc-trunk/gcc/ira.c:5425 > > 0x96de19 execute > > /repo/gcc-trunk/gcc/ira.c:5609 > > From rtl dump, reload is trying to insert the following reload insn > > r93:OI = r80:OI > > r93 is with general register class and r80 is with vector register > class. r93 was created to meet the constraint inside insn 17, and was to > replace the vector register r80 inside the subreg, as vector register > can't be used as index register. > > (insn 17 11 20 2 (set (mem:SI (plus:DI (sign_extract:DI (mult:DI (subreg:DI > (reg:OI 80 [ D.2754 ]) 0) > (const_int 4 [0x4])) > (const_int 34 [0x22]) > (const_int 0 [0])) > (reg/f:DI 83)) [1 *_9+0 S4 A32]) > (const_int 0 [0])) bug-1.c:7 49 {*movsi_aarch64} > > reload here is trying to reload the inner register r80 instead of the whole > subreg, > thus creating a new "OImode (vector register)" to "OImode (general register" > move > which can't be supported in hardware and caused further endless reload. > > For mode with size bigger than word_mode, there won't be "mov" between > two registers with different classes, but there normally will be "mov" > which transfers element of vector register into the general register, and > this normally will be a subreg. > > So I think we should teach reload about this to reload the whole subreg > if above conditions met. > > Comments? > > (CCed RA maintainer Vlad) > > diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c > index 14d5f1d..0ca7a7d 100644 > --- a/gcc/lra-constraints.c > +++ b/gcc/lra-constraints.c > @@ -1307,7 +1307,15 @@ process_addr_reg (rtx *loc, bool check_only_p, > rtx_insn **before, rtx_insn **aft > > subreg_p = GET_CODE (*loc) == SUBREG; > if (subreg_p) > - loc = &SUBREG_REG (*loc); > + { > + reg = SUBREG_REG (*loc); > + mode = GET_MODE (reg); > + > + if (in_class_p (reg, cl, &new_class) > + || GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode)) > + loc = &SUBREG_REG (*loc); > + } > + > reg = *loc; > mode = GET_MODE (reg); > if (! REG_P (reg)) In general the patch looks ok for me. It is probably the right place to fix it. I'd add a comment for condition of checking the mode size and use ptr_mode instead of word_mode. With these changes the patch is ok for me. Of course, you need to test it also on x86-64 (especially on GCC testsuite). Even if it looks ok to me, the reality can be different because LRA/reload works with many target details whose interaction is very hard to predict. Jiong, thank you for working on this PR.