aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaochen Gui <guihaoc@gcc.gnu.org>2024-08-15 13:38:22 +0800
committerHaochen Gui <guihaoc@gcc.gnu.org>2024-08-15 13:38:22 +0800
commit53945be1efb502f235d84ff67ceafe4a764b6e1c (patch)
tree0f5269c4da26a12d2f9b7de29bb010a4639061a6
parentd2e90c7d65749a02a20aca717ac47d02ef0b5d81 (diff)
downloadgcc-53945be1efb502f235d84ff67ceafe4a764b6e1c.zip
gcc-53945be1efb502f235d84ff67ceafe4a764b6e1c.tar.gz
gcc-53945be1efb502f235d84ff67ceafe4a764b6e1c.tar.bz2
rs6000: Implement optab_isinf for SFDF and IEEE128
gcc/ PR target/97786 * config/rs6000/rs6000.md (constant VSX_TEST_DATA_CLASS_NAN, VSX_TEST_DATA_CLASS_POS_INF, VSX_TEST_DATA_CLASS_NEG_INF, VSX_TEST_DATA_CLASS_POS_ZERO, VSX_TEST_DATA_CLASS_NEG_ZERO, VSX_TEST_DATA_CLASS_POS_DENORMAL, VSX_TEST_DATA_CLASS_NEG_DENORMAL): Define. (mode_attr sdq, vsx_altivec, wa_v, x): Define. (mode_iterator IEEE_FP): Define. * config/rs6000/vsx.md (isinf<mode>2): New expand. (expand xststdcqp_<mode>, xststdc<sd>p): Combine into... (expand xststdc_<mode>): ...this. (insn *xststdcqp_<mode>, *xststdc<sd>p): Combine into... (insn *xststdc_<mode>): ...this. * config/rs6000/rs6000-builtin.cc (rs6000_expand_builtin): Rename CODE_FOR_xststdcqp_kf as CODE_FOR_xststdc_kf, CODE_FOR_xststdcqp_tf as CODE_FOR_xststdc_tf. * config/rs6000/rs6000-builtins.def: Rename xststdcdp as xststdc_df, xststdcsp as xststdc_sf, xststdcqp_kf as xststdc_kf. gcc/testsuite/ PR target/97786 * gcc.target/powerpc/pr97786-1.c: New test. * gcc.target/powerpc/pr97786-2.c: New test.
-rw-r--r--gcc/config/rs6000/rs6000-builtin.cc4
-rw-r--r--gcc/config/rs6000/rs6000-builtins.def6
-rw-r--r--gcc/config/rs6000/rs6000.md35
-rw-r--r--gcc/config/rs6000/vsx.md58
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr97786-1.c22
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr97786-2.c17
6 files changed, 97 insertions, 45 deletions
diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 099cbc8..9bdbae1 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -3254,8 +3254,8 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
case CODE_FOR_xsiexpqpf_kf:
icode = CODE_FOR_xsiexpqpf_tf;
break;
- case CODE_FOR_xststdcqp_kf:
- icode = CODE_FOR_xststdcqp_tf;
+ case CODE_FOR_xststdc_kf:
+ icode = CODE_FOR_xststdc_tf;
break;
case CODE_FOR_xscmpexpqp_eq_kf:
icode = CODE_FOR_xscmpexpqp_eq_tf;
diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index 5b513a7..0e9dc05 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -2554,11 +2554,11 @@
const signed int \
__builtin_vsx_scalar_test_data_class_dp (double, const int<7>);
- VSTDCDP xststdcdp {}
+ VSTDCDP xststdc_df {}
const signed int \
__builtin_vsx_scalar_test_data_class_sp (float, const int<7>);
- VSTDCSP xststdcsp {}
+ VSTDCSP xststdc_sf {}
const signed int __builtin_vsx_scalar_test_neg_dp (double);
VSTDCNDP xststdcnegdp {}
@@ -2727,7 +2727,7 @@
const signed int __builtin_vsx_scalar_test_data_class_qp (_Float128, \
const int<7>);
- VSTDCQP xststdcqp_kf {}
+ VSTDCQP xststdc_kf {}
const signed int __builtin_vsx_scalar_test_neg_qp (_Float128);
VSTDCNQP xststdcnegqp_kf {}
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index d352a14..267affa 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -54,6 +54,20 @@
])
;;
+;; Test data class mask bits
+;;
+
+(define_constants
+ [(VSX_TEST_DATA_CLASS_NAN 0x40)
+ (VSX_TEST_DATA_CLASS_POS_INF 0x20)
+ (VSX_TEST_DATA_CLASS_NEG_INF 0x10)
+ (VSX_TEST_DATA_CLASS_POS_ZERO 0x8)
+ (VSX_TEST_DATA_CLASS_NEG_ZERO 0x4)
+ (VSX_TEST_DATA_CLASS_POS_DENORMAL 0x2)
+ (VSX_TEST_DATA_CLASS_NEG_DENORMAL 0x1)
+ ])
+
+;;
;; UNSPEC usage
;;
@@ -605,6 +619,10 @@
(define_mode_attr sd [(SF "s") (DF "d")
(V4SF "s") (V2DF "d")])
+; A generic s/d/q attribute, for sp/dp/qp for example.
+(define_mode_attr sdq [(SF "s") (DF "d")
+ (TF "q") (KF "q")])
+
; "s" or nothing, for fmuls/fmul for example.
(define_mode_attr s [(SF "s") (DF "")])
@@ -616,6 +634,23 @@
(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
(TF "FLOAT128_IEEE_P (TFmode)")])
+; Iterator for IEEE floating point
+(define_mode_iterator IEEE_FP [SFDF IEEE128])
+
+; "vsx/altivec_register_operand", for IEEE_FP predicates
+(define_mode_attr fp_register_op [(SF "vsx_register_operand")
+ (DF "vsx_register_operand")
+ (TF "altivec_register_operand")
+ (KF "altivec_register_operand")])
+
+; "wa" or "v", for IEEE_FP constraints
+(define_mode_attr wa_v [(SF "wa") (DF "wa")
+ (TF "v") (KF "v")])
+
+; "x" or nothing, for IEEE_FP
+(define_mode_attr x [(SF "x") (DF "x")
+ (TF "") (KF "")])
+
; Iterator for 128-bit floating point
(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
(IF "TARGET_FLOAT128_TYPE")
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 7892477..3a6afd1 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -5339,36 +5339,15 @@
"xscmpexpqp %0,%1,%2"
[(set_attr "type" "fpcompare")])
-;; VSX Scalar Test Data Class Quad-Precision
-;; (Expansion for scalar_test_data_class (__ieee128, int))
-;; (Has side effect of setting the lt bit if operand 1 is negative,
-;; setting the eq bit if any of the conditions tested by operand 2
-;; are satisfied, and clearing the gt and undordered bits to zero.)
-(define_expand "xststdcqp_<mode>"
- [(set (match_dup 3)
- (compare:CCFP
- (unspec:IEEE128
- [(match_operand:IEEE128 1 "altivec_register_operand" "v")
- (match_operand:SI 2 "u7bit_cint_operand" "n")]
- UNSPEC_VSX_STSTDC)
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (eq:SI (match_dup 3)
- (const_int 0)))]
- "TARGET_P9_VECTOR"
-{
- operands[3] = gen_reg_rtx (CCFPmode);
-})
-
-;; VSX Scalar Test Data Class Double- and Single-Precision
+;; VSX Scalar Test Data Class Quad-/Double-/Single-Precision
;; (The lt bit is set if operand 1 is negative. The eq bit is set
;; if any of the conditions tested by operand 2 are satisfied.
;; The gt and unordered bits are cleared to zero.)
-(define_expand "xststdc<sd>p"
+(define_expand "xststdc_<mode>"
[(set (match_dup 3)
(compare:CCFP
- (unspec:SFDF
- [(match_operand:SFDF 1 "vsx_register_operand" "wa")
+ (unspec:IEEE_FP
+ [(match_operand:IEEE_FP 1 "<fp_register_op>" "<wa_v>")
(match_operand:SI 2 "u7bit_cint_operand" "n")]
UNSPEC_VSX_STSTDC)
(match_dup 4)))
@@ -5381,6 +5360,16 @@
operands[4] = CONST0_RTX (SImode);
})
+(define_expand "isinf<mode>2"
+ [(use (match_operand:SI 0 "gpc_reg_operand"))
+ (use (match_operand:IEEE_FP 1 "<fp_register_op>"))]
+ "TARGET_HARD_FLOAT && TARGET_P9_VECTOR"
+{
+ int mask = VSX_TEST_DATA_CLASS_POS_INF | VSX_TEST_DATA_CLASS_NEG_INF;
+ emit_insn (gen_xststdc_<mode> (operands[0], operands[1], GEN_INT (mask)));
+ DONE;
+})
+
;; The VSX Scalar Test Negative Quad-Precision
(define_expand "xststdcnegqp_<mode>"
[(set (match_dup 2)
@@ -5416,27 +5405,16 @@
operands[3] = CONST0_RTX (SImode);
})
-(define_insn "*xststdcqp_<mode>"
+(define_insn "*xststdc_<mode>"
[(set (match_operand:CCFP 0 "" "=y")
(compare:CCFP
- (unspec:IEEE128
- [(match_operand:IEEE128 1 "altivec_register_operand" "v")
+ (unspec:IEEE_FP
+ [(match_operand:IEEE_FP 1 "<fp_register_op>" "<wa_v>")
(match_operand:SI 2 "u7bit_cint_operand" "n")]
UNSPEC_VSX_STSTDC)
(const_int 0)))]
"TARGET_P9_VECTOR"
- "xststdcqp %0,%1,%2"
- [(set_attr "type" "fpcompare")])
-
-(define_insn "*xststdc<sd>p"
- [(set (match_operand:CCFP 0 "" "=y")
- (compare:CCFP
- (unspec:SFDF [(match_operand:SFDF 1 "vsx_register_operand" "wa")
- (match_operand:SI 2 "u7bit_cint_operand" "n")]
- UNSPEC_VSX_STSTDC)
- (match_operand:SI 3 "zero_constant" "j")))]
- "TARGET_P9_VECTOR"
- "xststdc<sd>p %0,%x1,%2"
+ "xststdc<sdq>p %0,%<x>1,%2"
[(set_attr "type" "fpcompare")])
;; VSX Vector Extract Exponent Double and Single Precision
diff --git a/gcc/testsuite/gcc.target/powerpc/pr97786-1.c b/gcc/testsuite/gcc.target/powerpc/pr97786-1.c
new file mode 100644
index 0000000..3951770
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr97786-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-require-effective-target powerpc_vsx } */
+
+int test1 (double x)
+{
+ return __builtin_isinf (x);
+}
+
+int test2 (float x)
+{
+ return __builtin_isinf (x);
+}
+
+int test3 (float x)
+{
+ return __builtin_isinff (x);
+}
+
+/* { dg-final { scan-assembler-not {\mfcmp} } } */
+/* { dg-final { scan-assembler-times {\mxststdcsp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxststdcdp\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr97786-2.c b/gcc/testsuite/gcc.target/powerpc/pr97786-2.c
new file mode 100644
index 0000000..cea2d0dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr97786-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -mabi=ieeelongdouble -Wno-psabi" } */
+/* { dg-require-effective-target powerpc_vsx } */
+
+int test1 (long double x)
+{
+ return __builtin_isinf (x);
+}
+
+int test2 (long double x)
+{
+ return __builtin_isinfl (x);
+}
+
+/* { dg-final { scan-assembler-not {\mxscmpuqp\M} } } */
+/* { dg-final { scan-assembler-times {\mxststdcqp\M} 2 } } */