public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/meissner/heads/work017)] Power10: Add support for IEEE 128-bit fp cmove.
@ 2020-09-15 14:57 Michael Meissner
0 siblings, 0 replies; only message in thread
From: Michael Meissner @ 2020-09-15 14:57 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:10f42dc8a4b5e71f95b13c9ca4f7d5a942615061
commit 10f42dc8a4b5e71f95b13c9ca4f7d5a942615061
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Tue Sep 15 10:51:46 2020 -0400
Power10: Add support for IEEE 128-bit fp cmove.
gcc/
2020-09-15 Michael Meissner <meissner@linux.ibm.com>
* config/rs6000/rs6000.c (have_compare_and_set_mask): Add IEEE
128-bit floating point types.
* config/rs6000/rs6000.md (FPMASK): New iterator.
(FPMASK2): New iterator.
(Fv mode attribute): Add KFmode and TFmode.
(mov<FPMASK:mode><FPMASK2:mode>cc_fpmask): Replace
mov<SFDF:mode><SFDF2:mode>cc_p9. Add IEEE 128-bit fp support.
(mov<FPMASK:mode><FPMASK2:mode>cc_invert_fpmask): Replace
mov<SFDF:mode><SFDF2:mode>cc_invert_p9. Add IEEE 128-bit fp
support.
(fpmask<mode>): Add IEEE 128-bit fp support.
(xxsel<mode>): Add IEEE 128-bit fp support.
gcc/testsuite/
2020-09-15 Michael Meissner <meissner@linux.ibm.com>
* gcc.target/powerpc/float128-cmove.c: New test.
* gcc.target/powerpc/float128-minmax-3.c: New test.
Diff:
---
gcc/config/rs6000/rs6000.c | 8 +-
gcc/config/rs6000/rs6000.md | 101 +++++++++++++--------
gcc/testsuite/gcc.target/powerpc/float128-cmove.c | 93 +++++++++++++++++++
.../gcc.target/powerpc/float128-minmax-3.c | 15 +++
4 files changed, 176 insertions(+), 41 deletions(-)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 305dc662cc7..99fa0e7f0ca 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -15057,8 +15057,8 @@ rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
return 1;
}
-/* Possibly emit the xsmaxcdp and xsmincdp instructions to emit a maximum or
- minimum with "C" semantics.
+/* Possibly emit the xsmaxc{dp,qp} and xsminc{dp,qp} instructions to emit a
+ maximum or minimum with "C" semantics.
Unless you use -ffast-math, you can't use these instructions to replace
conditions that implicitly reverse the condition because the comparison
@@ -15194,6 +15194,10 @@ have_compare_and_set_mask (machine_mode mode)
case DFmode:
return TARGET_P9_MINMAX;
+ case KFmode:
+ case TFmode:
+ return FLOAT128_MINMASK_FPMASK_P (mode);
+
default:
break;
}
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 96907ef5c6f..41aa2164616 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -564,6 +564,19 @@
; And again, for when we need two FP modes in a pattern.
(define_mode_iterator SFDF2 [SF DF])
+; SFmode, DFmode, KFmode, or TFmode that supports the set compare mask
+; instruction.
+(define_mode_iterator FPMASK [SF
+ DF
+ (KF "FLOAT128_MINMASK_FPMASK_P (KFmode)")
+ (TF "FLOAT128_MINMASK_FPMASK_P (TFmode)")])
+
+; SFmode, DFmode, KFmode, or TFmode. when we need two FP modes in a pattern.
+(define_mode_iterator FPMASK2 [SF
+ DF
+ (KF "FLOAT128_MINMASK_FPMASK_P (KFmode)")
+ (TF "FLOAT128_MINMASK_FPMASK_P (TFmode)")])
+
; A generic s/d attribute, for sp/dp for example.
(define_mode_attr sd [(SF "s") (DF "d")
(V4SF "s") (V2DF "d")])
@@ -597,8 +610,13 @@
; SF/DF constraint for arithmetic on VSX registers using instructions added in
; ISA 2.06 (power7). This includes instructions that normally target DF mode,
; but are used on SFmode, since internally SFmode values are kept in the DFmode
-; format.
-(define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
+; format. Also include IEEE 128-bit instructions which are restricted to the
+; Altivec registers.
+(define_mode_attr Fv [(SF "wa")
+ (DF "wa")
+ (DI "wa")
+ (KF "v")
+ (TF "v")])
; Which isa is needed for those float instructions?
(define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
@@ -5285,10 +5303,10 @@
;; Floating point conditional move
(define_expand "mov<mode>cc"
- [(set (match_operand:SFDF 0 "gpc_reg_operand")
- (if_then_else:SFDF (match_operand 1 "comparison_operator")
- (match_operand:SFDF 2 "gpc_reg_operand")
- (match_operand:SFDF 3 "gpc_reg_operand")))]
+ [(set (match_operand:FPMASK 0 "gpc_reg_operand")
+ (if_then_else:FPMASK (match_operand 1 "comparison_operator")
+ (match_operand:FPMASK 2 "gpc_reg_operand")
+ (match_operand:FPMASK 3 "gpc_reg_operand")))]
"TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
{
if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
@@ -5308,15 +5326,15 @@
"fsel %0,%1,%2,%3"
[(set_attr "type" "fp")])
-(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
- [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
- (if_then_else:SFDF
+(define_insn_and_split "*mov<FPMASK:mode><FPMASK2:mode>cc_fpmask"
+ [(set (match_operand:FPMASK 0 "vsx_register_operand" "=<FPMASK:Fv>")
+ (if_then_else:FPMASK
(match_operator:CCFP 1 "fpmask_comparison_operator"
- [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
- (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
- (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
- (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
- (clobber (match_scratch:V2DI 6 "=0,&wa"))]
+ [(match_operand:FPMASK2 2 "vsx_register_operand" "<FPMASK2:Fv>")
+ (match_operand:FPMASK2 3 "vsx_register_operand" "<FPMASK2:Fv>")])
+ (match_operand:FPMASK 4 "vsx_register_operand" "<FPMASK:Fv>")
+ (match_operand:FPMASK 5 "vsx_register_operand" "<FPMASK:Fv>")))
+ (clobber (match_scratch:V2DI 6 "=&<FPMASK2:Fv>"))]
"TARGET_P9_MINMAX"
"#"
""
@@ -5325,10 +5343,10 @@
(match_dup 7)
(match_dup 8)))
(set (match_dup 0)
- (if_then_else:SFDF (ne (match_dup 6)
- (match_dup 8))
- (match_dup 4)
- (match_dup 5)))]
+ (if_then_else:FPMASK (ne (match_dup 6)
+ (match_dup 8))
+ (match_dup 4)
+ (match_dup 5)))]
{
if (GET_CODE (operands[6]) == SCRATCH)
operands[6] = gen_reg_rtx (V2DImode);
@@ -5340,15 +5358,15 @@
(set_attr "type" "vecperm")])
;; Handle inverting the fpmask comparisons.
-(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
- [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
- (if_then_else:SFDF
+(define_insn_and_split "*mov<FPMASK:mode><FPMASK2:mode>cc_invert_fpmask"
+ [(set (match_operand:FPMASK 0 "vsx_register_operand" "=<FPMASK:Fv>")
+ (if_then_else:FPMASK
(match_operator:CCFP 1 "invert_fpmask_comparison_operator"
- [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
- (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
- (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
- (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
- (clobber (match_scratch:V2DI 6 "=0,&wa"))]
+ [(match_operand:FPMASK2 2 "vsx_register_operand" "<FPMASK2:Fv>")
+ (match_operand:FPMASK2 3 "vsx_register_operand" "<FPMASK2:Fv>")])
+ (match_operand:FPMASK 4 "vsx_register_operand" "<FPMASK:Fv>")
+ (match_operand:FPMASK 5 "vsx_register_operand" "<FPMASK:Fv>")))
+ (clobber (match_scratch:V2DI 6 "=&<FPMASK2:Fv>"))]
"TARGET_P9_MINMAX"
"#"
"&& 1"
@@ -5357,10 +5375,10 @@
(match_dup 7)
(match_dup 8)))
(set (match_dup 0)
- (if_then_else:SFDF (ne (match_dup 6)
- (match_dup 8))
- (match_dup 5)
- (match_dup 4)))]
+ (if_then_else:FPMASK (ne (match_dup 6)
+ (match_dup 8))
+ (match_dup 5)
+ (match_dup 4)))]
{
rtx op1 = operands[1];
enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
@@ -5377,23 +5395,28 @@
(set_attr "type" "vecperm")])
(define_insn "*fpmask<mode>"
- [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
+ [(set (match_operand:V2DI 0 "vsx_register_operand" "=<Fv>")
(if_then_else:V2DI
(match_operator:CCFP 1 "fpmask_comparison_operator"
- [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
- (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
+ [(match_operand:FPMASK 2 "vsx_register_operand" "<Fv>")
+ (match_operand:FPMASK 3 "vsx_register_operand" "<Fv>")])
(match_operand:V2DI 4 "all_ones_constant" "")
(match_operand:V2DI 5 "zero_constant" "")))]
"TARGET_P9_MINMAX"
- "xscmp%V1dp %x0,%x2,%x3"
+{
+ return (FLOAT128_IEEE_P (<MODE>mode)
+ ? "xscmp%V1qp %0,%2,%3"
+ : "xscmp%V1dp %x0,%x2,%x3");
+}
[(set_attr "type" "fpcompare")])
(define_insn "*xxsel<mode>"
- [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
- (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
- (match_operand:V2DI 2 "zero_constant" ""))
- (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
- (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
+ [(set (match_operand:FPMASK 0 "vsx_register_operand" "=wa")
+ (if_then_else:FPMASK
+ (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
+ (match_operand:V2DI 2 "zero_constant" ""))
+ (match_operand:FPMASK 3 "vsx_register_operand" "wa")
+ (match_operand:FPMASK 4 "vsx_register_operand" "wa")))]
"TARGET_P9_MINMAX"
"xxsel %x0,%x4,%x3,%x1"
[(set_attr "type" "vecmove")])
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-cmove.c b/gcc/testsuite/gcc.target/powerpc/float128-cmove.c
new file mode 100644
index 00000000000..639d5a77087
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-cmove.c
@@ -0,0 +1,93 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+/* { dg-final { scan-assembler {\mxscmpeq[dq]p\M} } } */
+/* { dg-final { scan-assembler {\mxxpermdi\M} } } */
+/* { dg-final { scan-assembler {\mxxsel\M} } } */
+/* { dg-final { scan-assembler-not {\mxscmpu[dq]p\M} } } */
+/* { dg-final { scan-assembler-not {\mfcmp[uo]\M} } } */
+/* { dg-final { scan-assembler-not {\mfsel\M} } } */
+
+/* This series of tests tests whether you can do a conditional move where the
+ test is one floating point type, and the result is another floating point
+ type.
+
+ If the comparison type is SF/DFmode, and the move type is IEEE 128-bit
+ floating point, we have to duplicate the mask in the lower 64-bits with
+ XXPERMDI because XSCMPEQDP clears the bottom 64-bits of the mask register.
+
+ Going the other way (IEEE 128-bit comparsion, 64-bit move) is fine as the
+ mask word will be 128-bits. */
+
+float
+eq_f_d (float a, float b, double x, double y)
+{
+ return (x == y) ? a : b;
+}
+
+double
+eq_d_f (double a, double b, float x, float y)
+{
+ return (x == y) ? a : b;
+}
+
+float
+eq_f_f128 (float a, float b, __float128 x, __float128 y)
+{
+ return (x == y) ? a : b;
+}
+
+double
+eq_d_f128 (double a, double b, __float128 x, __float128 y)
+{
+ return (x == y) ? a : b;
+}
+
+__float128
+eq_f128_f (__float128 a, __float128 b, float x, float y)
+{
+ return (x == y) ? a : b;
+}
+
+__float128
+eq_f128_d (__float128 a, __float128 b, double x, double y)
+{
+ return (x != y) ? a : b;
+}
+
+float
+ne_f_d (float a, float b, double x, double y)
+{
+ return (x != y) ? a : b;
+}
+
+double
+ne_d_f (double a, double b, float x, float y)
+{
+ return (x != y) ? a : b;
+}
+
+float
+ne_f_f128 (float a, float b, __float128 x, __float128 y)
+{
+ return (x != y) ? a : b;
+}
+
+double
+ne_d_f128 (double a, double b, __float128 x, __float128 y)
+{
+ return (x != y) ? a : b;
+}
+
+__float128
+ne_f128_f (__float128 a, __float128 b, float x, float y)
+{
+ return (x != y) ? a : b;
+}
+
+__float128
+ne_f128_d (__float128 a, __float128 b, double x, double y)
+{
+ return (x != y) ? a : b;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-minmax-3.c b/gcc/testsuite/gcc.target/powerpc/float128-minmax-3.c
new file mode 100644
index 00000000000..6f7627c0f2a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-minmax-3.c
@@ -0,0 +1,15 @@
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+#ifndef TYPE
+#define TYPE _Float128
+#endif
+
+/* Test that the fminf128/fmaxf128 functions generate if/then/else and not a
+ call. */
+TYPE f128_min (TYPE a, TYPE b) { return (a < b) ? a : b; }
+TYPE f128_max (TYPE a, TYPE b) { return (b > a) ? b : a; }
+
+/* { dg-final { scan-assembler {\mxsmaxcqp\M} } } */
+/* { dg-final { scan-assembler {\mxsmincqp\M} } } */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-09-15 14:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-15 14:57 [gcc(refs/users/meissner/heads/work017)] Power10: Add support for IEEE 128-bit fp cmove Michael Meissner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).