This was discovered while playing around with LRA, but of course I regstrapped this using the existing reload pass.
Constraint "U" is a register constraint, that accepts either a pseudo or an even numbered hard register. But it is bogus, and in fact unnecessary. First, it isn't marked as a "define_register_constraint" so it doesn't properly represent a register class. Second, and more importantly in my opinion, this check is not the job of a constraint. Any piece of code in the compiler (be it in IRA, LRA, or traditional reload) which would assign a hard register will do so correctly because HARD_REGNO_MODE_OK() ensures that this requirement is met for 64-bit values when generating 32-bit code. Therefore remove "U" and just use plain "r". FWIW the trouble this caused with LRA is that we had an expression like: (set (mem:DI %sfp -8) (reg:DI PSEUDO)) and with optimizations disabled LRA allocated a spill stack slot and thus turned this into: (set (mem:DI %sfp -8) (mem:DI %sfp -32)) The originally matched alternative of *movdi_insn_sp32 used constraints "T" for output (8-byte aligned memory) and this register constraint "U" for input. However in the new form with the pseudo replaced with a spill slot, LRA can't tell that this instruction can be reloaded. This is because "U" doesn't evaluate to a register class when LRA makes the check using REG_CLASS_FROM_CONSTRAINT, instead it gets NO_REGS, and it therefore won't set "winreg" and we'll abort. Committed to master. * config/sparc/constraints.md ("U"): Delete. * config/sparc/sparc.md: Use 'r' constraint instead of 'U'. * config/sparc/sync.md: Likewise. --- gcc/ChangeLog | 8 +++++++- gcc/config/sparc/constraints.md | 9 --------- gcc/config/sparc/sparc.md | 16 ++++++++-------- gcc/config/sparc/sync.md | 4 ++-- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 47a7a4e..d6751b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,7 +1,13 @@ +2012-10-25 David S. Miller <da...@davemloft.net> + + * config/sparc/constraints.md ("U"): Delete. + * config/sparc/sparc.md: Use 'r' constraint instead of 'U'. + * config/sparc/sync.md: Likewise. + 2012-10-25 Lawrence Crowl <cr...@google.com> * hash-table.h: Add usage documentation. - (template struct typed_free_remove): Clarify documentation. + (template struct typed_free_remove): Clarify documentation. Rename template parameter. (struct typed_noop_remove): Likewise. (descriptor concept): Change typedef T to value_type. diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md index ffe5304..1d99d4b 100644 --- a/gcc/config/sparc/constraints.md +++ b/gcc/config/sparc/constraints.md @@ -138,15 +138,6 @@ (match_code "mem") (match_test "memory_ok_for_ldd (op)"))) -;; Not needed in 64-bit mode -(define_constraint "U" - "Pseudo-register or hard even-numbered integer register" - (and (match_test "TARGET_ARCH32") - (match_code "reg") - (ior (match_test "REGNO (op) < FIRST_PSEUDO_REGISTER") - (not (match_test "reload_in_progress && reg_renumber [REGNO (op)] < 0"))) - (match_test "register_ok_for_ldd (op)"))) - ;; Equivalent to 'T' but available in 64-bit mode (define_memory_constraint "W" "Memory reference for 'e' constraint floating-point register" diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index f604f46..4a44078 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -1595,9 +1595,9 @@ (define_insn "*movdi_insn_sp32" [(set (match_operand:DI 0 "nonimmediate_operand" - "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b") + "=T,o,T,r,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b") (match_operand:DI 1 "input_operand" - " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))] + " J,J,r,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))] "! TARGET_ARCH64 && (register_operand (operands[0], DImode) || register_or_zero_operand (operands[1], DImode))" @@ -2302,8 +2302,8 @@ }) (define_insn "*movdf_insn_sp32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o") - (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,r,T, f, *r, o,o") + (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,r,o#F,*roF,*rG,f"))] "! TARGET_ARCH64 && (register_operand (operands[0], DFmode) || register_or_zero_or_all_ones_operand (operands[1], DFmode))" @@ -2541,8 +2541,8 @@ }) (define_insn "*movtf_insn_sp32" - [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r") - (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,r, r") + (match_operand:TF 1 "input_operand" " G,oe,e,rG,o,roG"))] "! TARGET_ARCH64 && (register_operand (operands[0], TFmode) || register_or_zero_operand (operands[1], TFmode))" @@ -7911,8 +7911,8 @@ (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")]) (define_insn "*mov<VM64:mode>_insn_sp32" - [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r") - (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))] + [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,r,T, o,*r") + (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,r,*r,*r"))] "TARGET_VIS && ! TARGET_ARCH64 && (register_operand (operands[0], <VM64:MODE>mode) diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md index d11f663..302cd74 100644 --- a/gcc/config/sparc/sync.md +++ b/gcc/config/sparc/sync.md @@ -115,7 +115,7 @@ }) (define_insn "atomic_loaddi_1" - [(set (match_operand:DI 0 "register_operand" "=U,?*f") + [(set (match_operand:DI 0 "register_operand" "=r,?*f") (unspec:DI [(match_operand:DI 1 "memory_operand" "m,m")] UNSPEC_ATOMIC))] "!TARGET_ARCH64" @@ -144,7 +144,7 @@ (define_insn "atomic_storedi_1" [(set (match_operand:DI 0 "memory_operand" "=m,m,m") (unspec:DI - [(match_operand:DI 1 "register_or_v9_zero_operand" "J,U,?*f")] + [(match_operand:DI 1 "register_or_v9_zero_operand" "J,r,?*f")] UNSPEC_ATOMIC))] "!TARGET_ARCH64" "@ -- 1.7.12.2.dirty