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))

Reply via email to