The C99 quiet comparison builtins -- __builtin_isgreater, isgreaterequal,
isless, islessequal, islessgreater and isunordered -- must not raise the
Invalid exception on a quiet NaN, so on VFP they must use the quiet compare
vcmp rather than the signaling vcmpe.  This was fixed in GCC 10 by
r10-6245 -- per Andrew Pinski's analysis in the PR (comment #5,
"I think this was fixed ... and maybe a few others") -- the FP
comparison rework that picks CCFPmode for the
unordered-relation codes); add a regression test that checks no vcmpe is
emitted for any of these predicates in both SFmode and DFmode.

gcc/testsuite/ChangeLog:

        PR target/52258
        * gcc.target/arm/pr52258.c: New test.

Signed-off-by: Dominic P <[email protected]>
---

This patch was prepared with the assistance of an AI coding tool.  Every line of
code, every test and every measurement was written, reviewed and verified by the
author, who takes responsibility for the patch; the Signed-off-by above 
certifies
the Developer Certificate of Origin.

 gcc/testsuite/gcc.target/arm/pr52258.c | 30 ++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/arm/pr52258.c

diff --git a/gcc/testsuite/gcc.target/arm/pr52258.c 
b/gcc/testsuite/gcc.target/arm/pr52258.c
new file mode 100644
index 000000000..67d471bf2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr52258.c
@@ -0,0 +1,30 @@
+/* PR target/52258: the C99 quiet floating-point predicates (isgreater,
+   isgreaterequal, isless, islessequal, islessgreater, isunordered) must not
+   raise the Invalid exception on a quiet NaN, so on VFP they have to use the
+   quiet compare vcmp, never the signaling compare vcmpe.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_fp_dp_ok } */
+/* { dg-skip-if "need fp instructions" { *-*-* } { "-mfloat-abi=soft" } { "" } 
} */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_fp_dp } */
+
+#define TEST(NAME, TYPE, BUILTIN)                      \
+  int NAME##_rr (TYPE a, TYPE b) { return BUILTIN (a, b); }    \
+  int NAME##_rc (TYPE a) { return BUILTIN (a, 0); }
+
+#define TEST_TYPE(SUF, TYPE)                           \
+  TEST (ge_##SUF, TYPE, __builtin_isgreaterequal)      \
+  TEST (gt_##SUF, TYPE, __builtin_isgreater)           \
+  TEST (le_##SUF, TYPE, __builtin_islessequal)         \
+  TEST (lt_##SUF, TYPE, __builtin_isless)              \
+  TEST (lg_##SUF, TYPE, __builtin_islessgreater)       \
+  TEST (un_##SUF, TYPE, __builtin_isunordered)
+
+TEST_TYPE (sf, float)
+TEST_TYPE (df, double)
+
+/* Every one of these predicates is quiet, so no signaling compare may be
+   emitted.  */
+/* { dg-final { scan-assembler-not "vcmpe" } } */
+/* { dg-final { scan-assembler "vcmp\\.f32" } } */
+/* { dg-final { scan-assembler "vcmp\\.f64" } } */
-- 
2.55.0

Reply via email to