This patch fixes PR 59054, which is a bug I introduced in early October, when I added initial patches for allowing DFmode values in the traditional Altivec registers on ISA 2.06, and SFmode values on ISA 2.07. This patch eliminates the constraints that allowed DImode values to go into the Altivec registers, but had the result that for 0, the register allocator might choose to allocate a floating point register instead of a GPR register, and then has to store the value on the stack and reload (on ISA 2.06) or use direct move (on ISA 2.07) to get the value in a register.
I have tested this with a bootstrap and make check on subversion id 204367 with the fix from subversion id 204272 (fortran keyword problem). At present, I can't check it against the top of the trunk, due to PR 59009 (libsanitizer breaking powerpc64-linux-gnu builds). There were no regressions with the bootstrap or with make check. This patch also fixes the 64-bit failure in gcc.dg/stack-usage-1.c if you build the compiler using the --with-cpu=power7 option. In addition, I have included fixes for two other problems in my October changes. The first change only shows up when DFmode can go in the traditional Altivec registers, in that I used %x on a CR register. The second change is in conversion of SFmode to DFmode, I used the wrong constraints. Are these patches ok to install? I would prefer to check in the patches right now, but I can also wait until PR 59009 is fixed. [gcc] 2013-11-11 Michael Meissner <meiss...@linux.vnet.ibm.com> PR target/59054 * config/rs6000/rs6000.md (movdi_internal32): Eliminate constraints that would allow DImode into the traditional Altivec registers, but cause undesirable code generation when loading 0 as a constant. (movdi_internal32): Likewise. (cmp<mode>_fpr): Do not use %x for CR register output. (extendsfdf2_fpr): Fix constraints when -mallow-upper-df and -mallow-upper-sf debug switches are used. [gcc/testsuite] 2013-11-11 Michael Meissner <meiss...@linux.vnet.ibm.com> PR target/59054 * gcc.target/powerpc/pr59054.c: New test. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460, USA email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (revision 204267) +++ gcc/config/rs6000/rs6000.md (working copy) @@ -5226,7 +5226,7 @@ (define_insn "*cmp<mode>_fpr" "TARGET_<MODE>_FPR" "@ fcmpu %0,%1,%2 - xscmpudp %x0,%x1,%x2" + xscmpudp %0,%x1,%x2" [(set_attr "type" "fpcompare")]) ;; Floating point conversions @@ -5237,8 +5237,8 @@ (define_expand "extendsfdf2" "") (define_insn_and_split "*extendsfdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wy,?wy,wv") - (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wz,Z")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wv") + (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "@ # @@ -5360,7 +5360,7 @@ (define_insn "copysign<mode>3_fcpsgn" "TARGET_<MODE>_FPR && TARGET_CMPB" "@ fcpsgn %0,%2,%1 - xscpsgn<VSs> %x0,%x2,%x1" + xscpsgn<Fvsx> %x0,%x2,%x1" [(set_attr "type" "fp")]) ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a @@ -10081,8 +10081,8 @@ (define_insn "p8_mfvsrd_4_disf" ;; Use of fprs is disparaged slightly otherwise reload prefers to reload ;; a gpr into a fpr instead of reloading an invalid 'Y' address (define_insn "*movdi_internal32" - [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r,?wa") - (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF,O"))] + [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r") + (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))] "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" @@ -10093,8 +10093,7 @@ (define_insn "*movdi_internal32" stfd%U0%X0 %1,%0 lfd%U1%X1 %0,%1 fmr %0,%1 - # - xxlxor %x0,%x0,%x0" + #" [(set_attr_alternative "type" [(const_string "store") (const_string "load") @@ -10114,8 +10113,7 @@ (define_insn "*movdi_internal32" (const_string "fpload_u") (const_string "fpload"))) (const_string "fp") - (const_string "*") - (const_string "vecsimple")])]) + (const_string "*")])]) (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -10146,8 +10144,8 @@ (define_split { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) (define_insn "*movdi_internal64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,?Z,?wv,?wa,r,*h,*h,?wa,r,?*wg,r,?*wm") - (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,wv,Z,wa,*h,r,0,O,*wg,r,*wm,r"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wm") + (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wm,r"))] "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" @@ -10161,13 +10159,9 @@ (define_insn "*movdi_internal64" stfd%U0%X0 %1,%0 lfd%U1%X1 %0,%1 fmr %0,%1 - stxsd%U0x %x1,%y0 - lxsd%U1x %x0,%y1 - xxlor %x0,%x1,%x1 mf%1 %0 mt%0 %1 nop - xxlxor %x0,%x0,%x0 mftgpr %0,%1 mffgpr %0,%1 mfvsrd %0,%x1 @@ -10206,24 +10200,14 @@ (define_insn "*movdi_internal64" (const_string "fpload_u") (const_string "fpload"))) (const_string "fp") - (if_then_else - (match_test "update_indexed_address_mem (operands[0], VOIDmode)") - (const_string "fpstore_ux") - (const_string "fpstore")) - (if_then_else - (match_test "update_indexed_address_mem (operands[1], VOIDmode)") - (const_string "fpload_ux") - (const_string "fpload")) - (const_string "vecsimple") (const_string "mfjmpr") (const_string "mtjmpr") (const_string "*") - (const_string "vecsimple") (const_string "mftgpr") (const_string "mffgpr") (const_string "mftgpr") (const_string "mffgpr")]) - (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4,4,4,4")]) + (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4")]) ;; Generate all one-bits and clear left or right. ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber. Index: gcc/testsuite/gcc.target/powerpc/pr59054.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/pr59054.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/pr59054.c (revision 0) @@ -0,0 +1,9 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-mcpu=power7 -O0 -m64" } */ + +long foo (void) { return 0; } + +/* { dg-final { scan-assembler-not "xxlor" } } */ +/* { dg-final { scan-assembler-not "stfd" } } */