https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70904
Jiong Wang <jiwang at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |vmakarov at redhat dot com --- Comment #2 from Jiong Wang <jiwang at gcc dot gnu.org> --- (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))