]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Optimize ordered and nonequal
authorHu, Lin1 <lin1.hu@intel.com>
Mon, 2 Sep 2024 02:24:31 +0000 (10:24 +0800)
committerHaochen Jiang <haochen.jiang@intel.com>
Mon, 2 Sep 2024 02:24:31 +0000 (10:24 +0800)
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.

gcc/match.pd
gcc/testsuite/gcc.target/i386/optimize_one.c [new file with mode: 0644]

index be211535a49feb7195aad3a7fea73eb9eb5230a4..4298e89dad6dd3220334b5fc49c3c221da0059d1 100644 (file)
@@ -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 (file)
index 0000000..62728d3
--- /dev/null
@@ -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);
+}