https://gcc.gnu.org/g:53945be1efb502f235d84ff67ceafe4a764b6e1c
commit r15-2925-g53945be1efb502f235d84ff67ceafe4a764b6e1c Author: Haochen Gui <guih...@gcc.gnu.org> Date: Thu Aug 15 13:38:22 2024 +0800 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. Diff: --- gcc/config/rs6000/rs6000-builtin.cc | 4 +- gcc/config/rs6000/rs6000-builtins.def | 6 +-- gcc/config/rs6000/rs6000.md | 35 +++++++++++++++++ gcc/config/rs6000/vsx.md | 58 +++++++++------------------- gcc/testsuite/gcc.target/powerpc/pr97786-1.c | 22 +++++++++++ gcc/testsuite/gcc.target/powerpc/pr97786-2.c | 17 ++++++++ 6 files changed, 97 insertions(+), 45 deletions(-) diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc index 099cbc82245..9bdbae1ecf9 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 5b513a7ef2b..0e9dc05dbcf 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 d352a1431ad..267affa5057 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -53,6 +53,20 @@ (FRAME_POINTER_REGNUM 110) ]) +;; +;; 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 7892477fa92..3a6afd13c16 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 00000000000..3951770f65b --- /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 00000000000..cea2d0dd48e --- /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 } } */