> From: Jamie Prescott <jpre...@yahoo.com> > 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
Found it. The reload function were called with X0_REG, that is a class containing only X0, and is in turn a subclass of X_REGS. So the test had to be changed to a REG_CLASS_X(rcls), to account all the classes storing 64bit registers. This was a bitch to diagnose. 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) && REG_CLASS_X(regclass))) return NO_REGS; switch (mode) { case DImode: case SFmode: case DFmode: return REG_CLASS_X(regclass) ? regclass: X_REGS; default: break; } return regclass; } - Jamie