aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHu, Lin1 <lin1.hu@intel.com>2024-09-02 10:24:31 +0800
committerHaochen Jiang <haochen.jiang@intel.com>2024-09-02 10:24:31 +0800
commit86f5031c804220274a9bbebd26b8ebf47a2207ac (patch)
treea4318ed7c083e733ef8c69f3ffa0c7dcc6e1681e
parentb1f9fbb6da1a3ced57c3668cecc9f9449e1b237e (diff)
downloadgcc-86f5031c804220274a9bbebd26b8ebf47a2207ac.zip
gcc-86f5031c804220274a9bbebd26b8ebf47a2207ac.tar.gz
gcc-86f5031c804220274a9bbebd26b8ebf47a2207ac.tar.bz2
i386: Optimize ordered and nonequal
Currently, when we input !__builtin_isunordered (a, b) && (a != b), gcc will emit ucomiss %xmm1, %xmm0 movl $1, %ecx setp %dl setnp %al cmovne %ecx, %edx andl %edx, %eax movzbl %al, %eax In fact, xorl %eax, %eax ucomiss %xmm1, %xmm0 setne %al is better. gcc/ChangeLog: * match.pd: Optimize (and ordered non-equal) to (not (or unordered equal)) gcc/testsuite/ChangeLog: * gcc.target/i386/optimize_one.c: New test.
-rw-r--r--gcc/match.pd3
-rw-r--r--gcc/testsuite/gcc.target/i386/optimize_one.c9
2 files changed, 12 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index be21153..4298e89 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6651,6 +6651,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(ltgt @0 @0)
(if (!flag_trapping_math || !tree_expr_maybe_nan_p (@0))
{ constant_boolean_node (false, type); }))
+(simplify
+ (bit_and (ordered @0 @1) (ne @0 @1))
+ (bit_not (uneq @0 @1)))
/* x == ~x -> false */
/* x != ~x -> true */
diff --git a/gcc/testsuite/gcc.target/i386/optimize_one.c b/gcc/testsuite/gcc.target/i386/optimize_one.c
new file mode 100644
index 0000000..62728d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/optimize_one.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mfpmath=sse" } */
+/* { dg-final { scan-assembler-times "comi" 1 } } */
+/* { dg-final { scan-assembler-times "set" 1 } } */
+
+int is_ordered_or_nonequal_sh (float a, float b)
+{
+ return !__builtin_isunordered (a, b) && (a != b);
+}