[gcc(refs/users/meissner/heads/work043)] Load SF/DF constants with ISA 3.1 XXSPLTIDP
Michael Meissner
meissner@gcc.gnu.org
Tue Mar 30 20:26:32 GMT 2021
https://gcc.gnu.org/g:709a91c7d105444e06496f4cbba0fa612dab05f4
commit 709a91c7d105444e06496f4cbba0fa612dab05f4
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Tue Mar 30 16:26:11 2021 -0400
Load SF/DF constants with ISA 3.1 XXSPLTIDP
This patch uses the XXSPLTIDP instruction to load up SFmode/DFmode constants
that can be expressed exactly as single precision constants. Denormal values
are not allowed, since these are undefined in the ISA.
gcc/
2021-03-30 Michael Meissner <meissner@linux.ibm.com>
* config/rs6000/constraint.md (eF constraint): New constraint.
* config/rs6000/predicates.md (xxspltidp_operand): New predicate.
(easy_fp_constant): Constants that we can load with XXSPLTIDP are
considered easy constants.
* config/rs6000/rs6000.md (SF/DF load constant splitter): New
splitter for constants loaded with XXSPLTIDP.
(xxspltidp<mode>): New insn to emit XXSPLTIDP.
(movsf_hardfloat): Add support for loading constants with
XXSPLTIDP.
(mov<mode>_hardfloat32): Add support for loading constants with
XXSPLTIDP.
(mov<mode>_hardfloat64): Add support for loading constants with
XXSPLTIDP.
Diff:
---
gcc/config/rs6000/constraints.md | 4 ++
gcc/config/rs6000/predicates.md | 36 ++++++++++++++++
gcc/config/rs6000/rs6000.md | 91 ++++++++++++++++++++++++++++++++--------
3 files changed, 113 insertions(+), 18 deletions(-)
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index 561ce9797af..47f161df82e 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -229,6 +229,10 @@
(and (match_code "const_double")
(match_test "num_insns_constant (op, mode) == 3")))
+(define_constraint "eF"
+ "A floating point constant that can be loaded with XXSPLTIDP."
+ (match_operand 0 "xxspltidp_operand"))
+
;; Memory constraints
; Actually defined in common.md:
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 0c5d7a096f3..089a2597ce7 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -565,6 +565,37 @@
(ior (match_operand 0 "vsx_register_operand")
(match_operand 0 "reg_or_logical_cint_operand")))
+;; Return 1 if operand is a SF/DF CONST_DOUBLE that can be loaded via the ISA
+;; 3.1 XXSPLTIDP instruction. This function has to check, if the immediate
+;; specifies a single-precision denormal value (i.e., bits 1:8 equal to 0 and
+;; bits 9:31 not equal to 0), since the result is undefined in the hardware.
+(define_predicate "xxspltidp_operand"
+ (match_code "const_double")
+{
+ long value;
+
+ if (!TARGET_POWER10 || !TARGET_VSX)
+ return 0;
+
+ if (mode != SFmode && mode != DFmode)
+ return 0;
+
+ if (!CONST_DOUBLE_P (op))
+ return 0;
+
+ const struct real_value *rv = CONST_DOUBLE_REAL_VALUE (op);
+ if (!exact_real_truncate (SFmode, rv))
+ return 0;
+
+ REAL_VALUE_TO_TARGET_SINGLE (*rv, value);
+
+ /* Test for SFmode denormal (exponent is 0, mantissa field is non-zero). */
+ if (((value & 0x7F800000) == 0) && ((value & 0x7FFFFF) != 0))
+ return 0;
+
+ return 1;
+})
+
;; Return 1 if operand is a CONST_DOUBLE that can be set in a register
;; with no more than one instruction per word.
(define_predicate "easy_fp_constant"
@@ -601,6 +632,11 @@
if (TARGET_VSX && op == CONST0_RTX (mode))
return 1;
+ /* If we have the ISA 3.1 XXSPLTIDP instruction, see if the constant can
+ be loaded with that instruction. */
+ if (xxspltidp_operand (op, mode))
+ return 1;
+
/* Otherwise consider floating point constants hard, so that the
constant gets pushed to memory during the early RTL phases. This
has the advantage that double precision constants that can be
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 5df9eb7500d..1bbb17bef7d 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7530,6 +7530,32 @@
DONE;
})
+;; Convert a load of a SFmode/DFmode constant to use the ISA 3.1 XXSPLTIDP
+;; instruction if we can. We don't do this for 0.0 to allow the move patterns
+;; to generate the smaller XXSPLTIB/VSPLTISW/XXLXOR to zero the register.
+(define_split
+ [(set (match_operand:SFDF 0 "vsx_register_operand")
+ (match_operand:SFDF 1 "xxspltidp_operand"))]
+ "TARGET_POWER10 && TARGET_VSX && operands[1] != CONST0_RTX (<MODE>mode)"
+ [(set (match_dup 0)
+ (unspec:SFDF [(match_dup 2)] UNSPEC_XXSPLTID))]
+{
+ long value;
+ const struct real_value *rv = CONST_DOUBLE_REAL_VALUE (operands[1]);
+ REAL_VALUE_TO_TARGET_SINGLE (*rv, value);
+ operands[2] = GEN_INT (value);
+})
+
+(define_insn "*xxspltidp<mode>"
+ [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
+ (unspec:SFDF [(match_operand 1 "const_int_operand" "n")]
+ UNSPEC_XXSPLTID))]
+ "TARGET_POWER10 && TARGET_VSX"
+ "xxspltidp %x0,%1"
+ [(set_attr "type" "vecperm")
+ (set_attr "prefixed" "yes")
+ (set_attr "prefixed_prepend_p" "no")])
+
(define_split
[(set (match_operand:FMOVE32 0 "gpc_reg_operand")
(match_operand:FMOVE32 1 "const_double_operand"))]
@@ -7563,17 +7589,17 @@
;;
;; LWZ LFS LXSSP LXSSPX STFS STXSSP
;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
-;; MR MT<x> MF<x> NOP
+;; MR MT<x> MF<x> NOP XXSPLTIDP
(define_insn "movsf_hardfloat"
[(set (match_operand:SF 0 "nonimmediate_operand"
"=!r, f, v, wa, m, wY,
Z, m, wa, !r, f, wa,
- !r, *c*l, !r, *h")
+ !r, *c*l, !r, *h, wa")
(match_operand:SF 1 "input_operand"
"m, m, wY, Z, f, v,
wa, r, j, j, f, wa,
- r, r, *h, 0"))]
+ r, r, *h, 0, eF"))]
"(register_operand (operands[0], SFmode)
|| register_operand (operands[1], SFmode))
&& TARGET_HARD_FLOAT
@@ -7595,15 +7621,24 @@
mr %0,%1
mt%0 %1
mf%1 %0
- nop"
+ nop
+ #"
[(set_attr "type"
"load, fpload, fpload, fpload, fpstore, fpstore,
fpstore, store, veclogical, integer, fpsimple, fpsimple,
- *, mtjmpr, mfjmpr, *")
+ *, mtjmpr, mfjmpr, *, vecperm")
(set_attr "isa"
"*, *, p9v, p8v, *, p9v,
p8v, *, *, *, *, *,
- *, *, *, *")])
+ *, *, *, *, p10")
+ (set_attr "prefixed"
+ "*, *, *, *, *, *,
+ *, *, *, *, *, *,
+ *, *, *, *, yes")
+ (set_attr "prefixed_prepend_p"
+ "*, *, *, *, *, *,
+ *, *, *, *, *, *,
+ *, *, *, *, no")])
;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
;; FMR MR MT%0 MF%1 NOP
@@ -7863,18 +7898,18 @@
;; STFD LFD FMR LXSD STXSD
;; LXSD STXSD XXLOR XXLXOR GPR<-0
-;; LWZ STW MR
+;; LWZ STW MR XXSPLTIDP
(define_insn "*mov<mode>_hardfloat32"
[(set (match_operand:FMOVE64 0 "nonimmediate_operand"
"=m, d, d, <f64_p9>, wY,
<f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
- Y, r, !r")
+ Y, r, !r, wa")
(match_operand:FMOVE64 1 "input_operand"
"d, m, d, wY, <f64_p9>,
Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
- r, Y, r"))]
+ r, Y, r, eF"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT
&& (gpc_reg_operand (operands[0], <MODE>mode)
|| gpc_reg_operand (operands[1], <MODE>mode))"
@@ -7891,20 +7926,29 @@
#
#
#
+ #
#"
[(set_attr "type"
"fpstore, fpload, fpsimple, fpload, fpstore,
fpload, fpstore, veclogical, veclogical, two,
- store, load, two")
+ store, load, two, vecperm")
(set_attr "size" "64")
(set_attr "length"
"*, *, *, *, *,
*, *, *, *, 8,
- 8, 8, 8")
+ 8, 8, 8, *")
(set_attr "isa"
"*, *, *, p9v, p9v,
p7v, p7v, *, *, *,
- *, *, *")])
+ *, *, *, p10")
+ (set_attr "prefixed"
+ "*, *, *, *, *,
+ *, *, *, *, *,
+ *, *, *, yes")
+ (set_attr "prefixed_prepend_p"
+ "*, *, *, *, *,
+ *, *, *, *, *,
+ *, *, *, no")])
;; STW LWZ MR G-const H-const F-const
@@ -7931,19 +7975,19 @@
;; STFD LFD FMR LXSD STXSD
;; LXSDX STXSDX XXLOR XXLXOR LI 0
;; STD LD MR MT{CTR,LR} MF{CTR,LR}
-;; NOP MFVSRD MTVSRD
+;; NOP MFVSRD MTVSRD XXSPLTIDP
(define_insn "*mov<mode>_hardfloat64"
[(set (match_operand:FMOVE64 0 "nonimmediate_operand"
"=m, d, d, <f64_p9>, wY,
<f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
YZ, r, !r, *c*l, !r,
- *h, r, <f64_dm>")
+ *h, r, <f64_dm>, wa")
(match_operand:FMOVE64 1 "input_operand"
"d, m, d, wY, <f64_p9>,
Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
r, YZ, r, r, *h,
- 0, <f64_dm>, r"))]
+ 0, <f64_dm>, r, eF"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT
&& (gpc_reg_operand (operands[0], <MODE>mode)
|| gpc_reg_operand (operands[1], <MODE>mode))"
@@ -7965,18 +8009,29 @@
mf%1 %0
nop
mfvsrd %0,%x1
- mtvsrd %x0,%1"
+ mtvsrd %x0,%1
+ #"
[(set_attr "type"
"fpstore, fpload, fpsimple, fpload, fpstore,
fpload, fpstore, veclogical, veclogical, integer,
store, load, *, mtjmpr, mfjmpr,
- *, mfvsr, mtvsr")
+ *, mfvsr, mtvsr, vecperm")
(set_attr "size" "64")
(set_attr "isa"
"*, *, *, p9v, p9v,
p7v, p7v, *, *, *,
*, *, *, *, *,
- *, p8v, p8v")])
+ *, p8v, p8v, p10")
+ (set_attr "prefixed"
+ "*, *, *, *, *,
+ *, *, *, *, *,
+ *, *, *, *, *,
+ *, *, *, yes")
+ (set_attr "prefixed_prepend_p"
+ "*, *, *, *, *,
+ *, *, *, *, *,
+ *, *, *, *, *,
+ *, *, *, no")])
;; STD LD MR MT<SPR> MF<SPR> G-const
;; H-const F-const Special
More information about the Gcc-cvs
mailing list