aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/dojump.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr98169.c29
2 files changed, 36 insertions, 1 deletions
diff --git a/gcc/dojump.c b/gcc/dojump.c
index 28b47b7..4c7fafe 100644
--- a/gcc/dojump.c
+++ b/gcc/dojump.c
@@ -1114,7 +1114,7 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
/* ... or if there is no libcall for it. */
|| code_to_optab (code) == unknown_optab))
{
- enum rtx_code first_code;
+ enum rtx_code first_code, orig_code = code;
bool and_them = split_comparison (code, mode, &first_code, &code);
/* If there are no NaNs, the first comparison should always fall
@@ -1122,6 +1122,12 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
if (!HONOR_NANS (mode))
gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
+ else if ((orig_code == EQ || orig_code == NE)
+ && rtx_equal_p (op0, op1))
+ /* Self-comparisons x == x or x != x can be optimized into
+ just x ord x or x nord x. */
+ code = orig_code == EQ ? ORDERED : UNORDERED;
+
else
{
profile_probability cprob
diff --git a/gcc/testsuite/gcc.target/i386/pr98169.c b/gcc/testsuite/gcc.target/i386/pr98169.c
new file mode 100644
index 0000000..b192731
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98169.c
@@ -0,0 +1,29 @@
+/* PR tree-optimization/98169 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-finite-math-only" } */
+/* { dg-final { scan-assembler-times "\tsetn\?p\t" 4 } } */
+/* { dg-final { scan-assembler-not "\tjn\?\[ep]\t" } } */
+
+int
+f1 (float a)
+{
+ return a == a;
+}
+
+int
+f2 (float a)
+{
+ return !__builtin_isnanf (a);
+}
+
+int
+f3 (double a)
+{
+ return a == a;
+}
+
+int
+f4 (double a)
+{
+ return !__builtin_isnan (a);
+}