Hi, This patch implemented optab_isfinite for SFDF and IEEE128 by test data class instructions.
Compared with previous version, the main change is to narrow down the predict for float operand according to review's advice. https://gcc.gnu.org/pipermail/gcc-patches/2024-May/652129.html Bootstrapped and tested on powerpc64-linux BE and LE with no regressions. Is it OK for trunk? Thanks Gui Haochen ChangeLog rs6000: Implement optab_isfinite for SFDF and IEEE128 gcc/ PR target/97786 * config/rs6000/vsx.md (isfinite<mode>2 for SFDF): New expand. (isfinite<mode>2 for IEEE128): New expand. gcc/testsuite/ PR target/97786 * gcc.target/powerpc/pr97786-4.c: New test. * gcc.target/powerpc/pr97786-5.c: New test. patch.diff diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 08cce11da60..95214d732f0 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -5331,6 +5331,28 @@ (define_expand "isinf<mode>2" DONE; }) +(define_expand "isfinite<mode>2" + [(use (match_operand:SI 0 "gpc_reg_operand")) + (use (match_operand:SFDF 1 "vsx_register_operand"))] + "TARGET_HARD_FLOAT && TARGET_P9_VECTOR" +{ + rtx tmp = gen_reg_rtx (SImode); + emit_insn (gen_xststdc<sd>p (tmp, operands[1], GEN_INT (0x70))); + emit_insn (gen_xorsi3 (operands[0], tmp, const1_rtx)); + DONE; +}) + +(define_expand "isfinite<mode>2" + [(use (match_operand:SI 0 "gpc_reg_operand")) + (use (match_operand:IEEE128 1 "vsx_register_operand"))] + "TARGET_HARD_FLOAT && TARGET_P9_VECTOR" +{ + rtx tmp = gen_reg_rtx (SImode); + emit_insn (gen_xststdcqp_<mode> (tmp, operands[1], GEN_INT (0x70))); + emit_insn (gen_xorsi3 (operands[0], tmp, const1_rtx)); + DONE; +}) + ;; The VSX Scalar Test Negative Quad-Precision (define_expand "xststdcnegqp_<mode>" [(set (match_dup 2) diff --git a/gcc/testsuite/gcc.target/powerpc/pr97786-4.c b/gcc/testsuite/gcc.target/powerpc/pr97786-4.c new file mode 100644 index 00000000000..01faa962bd5 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr97786-4.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_vsx } */ +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */ + +int test1 (double x) +{ + return __builtin_isfinite (x); +} + +int test2 (float x) +{ + return __builtin_isfinite (x); +} + +/* { dg-final { scan-assembler-not {\mfcmp} } } */ +/* { dg-final { scan-assembler-times {\mxststdcsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxststdcdp\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr97786-5.c b/gcc/testsuite/gcc.target/powerpc/pr97786-5.c new file mode 100644 index 00000000000..0e106b9f23a --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr97786-5.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ppc_float128_hw } */ +/* { dg-require-effective-target powerpc_vsx } */ +/* { dg-options "-O2 -mdejagnu-cpu=power9 -mabi=ieeelongdouble -Wno-psabi" } */ + +int test1 (long double x) +{ + return __builtin_isfinite (x); +} + +/* { dg-final { scan-assembler-not {\mxscmpuqp\M} } } */ +/* { dg-final { scan-assembler {\mxststdcqp\M} } } */