> From: Jamie Prescott <jpre...@yahoo.com> > To: gcc@gcc.gnu.org > Sent: Friday, May 15, 2009 4:16:30 PM > Subject: Re: Different reload behavior from 4.3.3 to 4.4 > > > > From: Jamie Prescott > > To: gcc@gcc.gnu.org > > Sent: Friday, May 15, 2009 3:28:18 PM > > Subject: Different reload behavior from 4.3.3 to 4.4 > > > > > > In my VM, the X_REGS class is a generic 64bit regsiter class that can hold > > both 64bit DImode and 64bit DFmode. > > Such class does not allow direct constant loading, so in 4.3.3 I had: > > > > enum reg_class > > xxx_preferred_reload_class(rtx x, enum reg_class regclass) > > { > > enum machine_mode mode = GET_MODE(x); > > > > if (regclass == NO_REGS || > > ((GET_CODE(x) == CONST_INT || > > GET_CODE(x) == CONST_DOUBLE) && regclass == X_REGS)) > > return NO_REGS; > > switch (mode) { > > case DImode: > > case SFmode: > > case DFmode: > > return X_REGS; > > default: > > break; > > } > > > > return regclass; > > } > > > > This was working fine with 4.3.3, while with 4.4 I get an error like if GCC > was > > trying > > to load a const_int directly anyway: > > > > ./csrc/test_sha512.c:294: error: insn does not satisfy its constraints: > > (insn 870 869 43 2 ./csrc/test_sha512.c:200 (set (reg:DI 55 x0) > > (const_int 7640891576956012808 [0x6a09e667f3bcc908])) 31 {movdi} > (nil)) > > ./csrc/test_sha512.c:294: internal compiler error: in > > reload_cse_simplify_operands, at postreload.c:396 > > Strange thing, this works: > > <<<<<<<< > extern int loola(long long); > > int noola(void) > { > return loola(19291291912LL); > } > > >>>>>>>> > $LC0: > qword 19291291912 > _noola: > push r8 > lea $LC0,r8 > ldr.q r8,x0 > call _loola > pop r8 > ret > > > While this chokes: > > <<<<<<<<< > struct ff { > long long ll[4]; > }; > > void noola(struct ff *p) > { > p->ll[0] = 19291291912LL; > } > > >>>>>>>>> > ainl.c: In function 'noola': > ainl.c:11: error: insn does not satisfy its constraints: > (insn 17 16 6 2 ainl.c:10 (set (reg:DI 55 x0) > (const_int 19291291912 [0x47dd9c108])) 31 {movdi} (nil)) > ainl.c:11: internal compiler error: in reload_cse_simplify_operands, at > postreload.c:396
This is the output of the IRA pass: Reloads for insn # 6 Reload 0: reload_in (SI) = (symbol_ref/u:SI ("*$LC0") [flags 0x2]) GENERAL_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1) reload_in_reg: (symbol_ref/u:SI ("*$LC0") [flags 0x2]) reload_reg_rtx: (reg:SI 8 r8) Reload 1: reload_out (DI) = (mem/s:DI (reg/v/f:SI 0 r0 [orig:124 p ] [124]) [3 <variable>.ll+0 S8 A64]) NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional reload_out_reg: (mem/s:DI (reg/v/f:SI 0 r0 [orig:124 p ] [124]) [3 <variable>.ll+0 S8 A64]) Reload 2: reload_in (DI) = (mem/u/c/i:DI (symbol_ref/u:SI ("*$LC0") [flags 0x2]) [3 S8 A64]) X_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine reload_in_reg: (const_int 19291291912 [0x47dd9c108]) reload_reg_rtx: (reg:DI 55 x0) deleting insn with uid = 2. It created the label ($LC0) where to store the DI value, but then it gets a "can't combine" and drops it. And it goes for a reload_in_reg directly. Even from the insns, it generates the load of the $LC0 symbol address to r8 for a reload that never happens. Instead, a move-CONST_INT-to-reg is generated, that 'movdi' can't handle. (insn 16 3 17 2 ainl.c:10 (set (reg:SI 8 r8) (symbol_ref/u:SI ("*$LC0") [flags 0x2])) 28 {*movsi_internal} (nil)) (insn 17 16 6 2 ainl.c:10 (set (reg:DI 55 x0) (const_int 19291291912 [0x47dd9c108])) 31 {movdi} (nil)) (insn 6 17 14 2 ainl.c:10 (set (mem/s:DI (reg/v/f:SI 0 r0 [orig:124 p ] [124]) [3 <variable>.ll+0 S8 A64]) (reg:DI 55 x0)) 31 {movdi} (nil)) Any suggestions, or things that changed in 4.4 vs. 4.3.3 I should be aware of, are very much welcome ... - Jamie