diff options
author | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-19 22:37:33 +0000 |
---|---|---|
committer | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-19 22:37:33 +0000 |
commit | 2d5ee2b9035db2414ae3535db18550c1d90e52fd (patch) | |
tree | 5e637e4c0de219dabaa221d54e60d5940317137c /gcc/config/rs6000 | |
parent | 28323099addac7faac9e5ca78a2a43ddcbb1e819 (diff) |
[gcc]
2015-03-19 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/65240
* config/rs6000/predicates.md (easy_fp_constant): Remove special
-ffast-math handling that kept non-0 constants live in the RTL
until reload. Remove logic testing the number of instructions it
took to create a constant in a GPR that was never used, due to a
test for soft-float earlier.
(memory_fp_constant): Delete, no longer used.
* config/rs6000/rs6000.md (mov<MODE>_hardfloat): Remove
alternatives for loading non-0 constants into GPRs for hard
floating point that is no longer needed due to changes in
easy_fp_constant. Add support for loading 0.0 into GPRs.
(mov<mode>_hardfloat32): Likewise.
(mov<mode>_hardfloat64): Likewise.
(mov<mode>_64bit_dm): Likewise.
(movtd_64bit_nodm): Likewise.
(pre-reload move FP constant define_split): Delete define_split,
since it is no longer used.
(extenddftf2_internal): Remove GHF constraints that are not valid
for extenddftf2.
[gcc/testsuite]
2015-03-19 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/65240
* gcc/testsuite/g++.dg/pr65240.h: Add tests for PR 65240.
* gcc/testsuite/g++.dg/pr65240-1.C: Likewise.
* gcc/testsuite/g++.dg/pr65240-2.C: Likewise.
* gcc/testsuite/g++.dg/pr65240-3.C: Likewise.
* gcc/testsuite/g++.dg/pr65240-4.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221524 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/predicates.md | 88 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 61 |
2 files changed, 37 insertions, 112 deletions
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index b491e407e73..6abb40b5cff 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -432,9 +432,6 @@ (define_predicate "easy_fp_constant" (match_code "const_double") { - long k[4]; - REAL_VALUE_TYPE rv; - if (GET_MODE (op) != mode || (!SCALAR_FLOAT_MODE_P (mode) && mode != DImode)) return 0; @@ -446,8 +443,7 @@ return 1; /* The constant 0.0 is easy under VSX. */ - if ((mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode) - && VECTOR_UNIT_VSX_P (DFmode) && op == CONST0_RTX (mode)) + if (TARGET_VSX && SCALAR_FLOAT_MODE_P (mode) && op == CONST0_RTX (mode)) return 1; if (DECIMAL_FLOAT_MODE_P (mode)) @@ -464,82 +460,28 @@ return 0; #endif + /* If we have real FPRs, consider floating point constants hard (other than + 0.0 under VSX), so that the constant gets pushed to memory during the + early RTL phases. This has the advantage that double precision constants + that can be represented in single precision without a loss of precision + will use single precision loads. */ + switch (mode) { case TFmode: - if (TARGET_E500_DOUBLE) - return 0; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k); - - return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1 - && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1 - && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1 - && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1); - case DFmode: - /* Force constants to memory before reload to utilize - compress_float_constant. - Avoid this when flag_unsafe_math_optimizations is enabled - because RDIV division to reciprocal optimization is not able - to regenerate the division. */ - if (TARGET_E500_DOUBLE - || (!reload_in_progress && !reload_completed - && !flag_unsafe_math_optimizations)) - return 0; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_DOUBLE (rv, k); - - return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1 - && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1); - case SFmode: - /* Force constants to memory before reload to utilize - compress_float_constant. - Avoid this when flag_unsafe_math_optimizations is enabled - because RDIV division to reciprocal optimization is not able - to regenerate the division. */ - if (!reload_in_progress && !reload_completed - && !flag_unsafe_math_optimizations) - return 0; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_SINGLE (rv, k[0]); - - return num_insns_constant_wide (k[0]) == 1; - - case DImode: - return (num_insns_constant (op, DImode) <= 2); - - case SImode: - return 1; - - default: - gcc_unreachable (); - } -}) + return 0; -;; Return 1 if the operand must be loaded from memory. This is used by a -;; define_split to insure constants get pushed to the constant pool before -;; reload. If -ffast-math is used, easy_fp_constant will allow move insns to -;; have constants in order not interfere with reciprocal estimation. However, -;; with -mupper-regs support, these constants must be moved to the constant -;; pool before register allocation. + case DImode: + return (num_insns_constant (op, DImode) <= 2); -(define_predicate "memory_fp_constant" - (match_code "const_double") -{ - if (TARGET_VSX && op == CONST0_RTX (mode)) - return 0; + case SImode: + return 1; - if (!TARGET_HARD_FLOAT || !TARGET_FPRS - || (mode == SFmode && !TARGET_SINGLE_FLOAT) - || (mode == DFmode && !TARGET_DOUBLE_FLOAT)) - return 0; - - return 1; + default: + gcc_unreachable (); + } }) ;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 001884cbe58..aec696e385a 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -8048,8 +8048,8 @@ }") (define_insn "mov<mode>_hardfloat" - [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,<f32_lr>,<f32_sm>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h,!r,!r") - (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,<f32_lm>,<f32_sr>,Z,<f32_av>,r,<f32_dm>,r,h,0,G,Fn"))] + [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_sm>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h") + (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_sr>,Z,<f32_av>,r,<f32_dm>,r,h,0"))] "(gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode)) && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)" @@ -8060,6 +8060,7 @@ fmr %0,%1 xxlor %x0,%x1,%x1 xxlxor %x0,%x0,%x0 + li %0,0 <f32_li> <f32_si> <f32_lv> @@ -8068,11 +8069,9 @@ mfvsrwz %0,%x1 mt%0 %1 mf%1 %0 - nop - # - #" - [(set_attr "type" "*,load,store,fp,vecsimple,vecsimple,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8")]) + nop" + [(set_attr "type" "*,load,store,fp,vecsimple,vecsimple,integer,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*") + (set_attr "length" "4")]) (define_insn "*mov<mode>_softfloat" [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h") @@ -8186,9 +8185,12 @@ ;; since the D-form version of the memory instructions does not need a GPR for ;; reloading. +;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, +;; except for 0.0 which can be created on VSX with an xor instruction. + (define_insn "*mov<mode>_hardfloat32" - [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,Y,r,!r,!r,!r,!r") - (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,r,Y,r,G,H,F"))] + [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r") + (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" @@ -8203,11 +8205,9 @@ # # # - # - # #" - [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,two,fp,fp,*") - (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8,12,16")]) + [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,two,store,load,two") + (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8")]) (define_insn "*mov<mode>_softfloat32" [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r") @@ -8225,8 +8225,8 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*mov<mode>_hardfloat64" - [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,<f64_dm>") - (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,r,Y,r,r,h,0,G,H,F,wg,r,<f64_dm>,r"))] + [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>") + (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" @@ -8238,21 +8238,19 @@ stxsd%U0x %x1,%y0 xxlor %x0,%x1,%x1 xxlxor %x0,%x0,%x0 + li %0,0 std%U0%X0 %1,%0 ld%U1%X1 %0,%1 mr %0,%1 mt%0 %1 mf%1 %0 nop - # - # - # mftgpr %0,%1 mffgpr %0,%1 mfvsrd %0,%x1 mtvsrd %x0,%1" - [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,*,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr,mftgpr,mffgpr") - (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4,4,4")]) + [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr") + (set_attr "length" "4")]) (define_insn "*mov<mode>_softfloat64" [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h") @@ -8289,7 +8287,7 @@ (define_insn_and_split "*mov<mode>_64bit_dm" [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r,r,wm") - (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jYGHF,r,wm,r"))] + (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN) && (gpc_reg_operand (operands[0], <MODE>mode) @@ -8302,7 +8300,7 @@ (define_insn_and_split "*movtd_64bit_nodm" [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r") - (match_operand:TD 1 "input_operand" "d,m,d,j,r,jYGHF,r"))] + (match_operand:TD 1 "input_operand" "d,m,d,j,r,jY,r"))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN && (gpc_reg_operand (operands[0], TDmode) || gpc_reg_operand (operands[1], TDmode))" @@ -8314,7 +8312,7 @@ (define_insn_and_split "*mov<mode>_32bit" [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r") - (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jYGHF,r"))] + (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r"))] "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64 && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" @@ -8336,21 +8334,6 @@ { rs6000_split_multireg_move (operands[0], operands[1]); DONE; } [(set_attr "length" "20,20,16")]) -;; If we are using -ffast-math, easy_fp_constant assumes all constants are -;; 'easy' in order to allow for reciprocal estimation. Make sure the constant -;; is in the constant pool before reload occurs. This simplifies accessing -;; scalars in the traditional Altivec registers. - -(define_split - [(set (match_operand:SFDF 0 "register_operand" "") - (match_operand:SFDF 1 "memory_fp_constant" ""))] - "TARGET_<MODE>_FPR && flag_unsafe_math_optimizations - && !reload_in_progress && !reload_completed && !lra_in_progress" - [(set (match_dup 0) (match_dup 2))] -{ - operands[2] = validize_mem (force_const_mem (<MODE>mode, operands[1])); -}) - (define_expand "extenddftf2" [(set (match_operand:TF 0 "nonimmediate_operand" "") (float_extend:TF (match_operand:DF 1 "input_operand" "")))] @@ -8382,7 +8365,7 @@ (define_insn_and_split "*extenddftf2_internal" [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,d,&d,r") - (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,rmGHF"))) + (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,rm"))) (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,m,d,n"))] "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT |