aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/dojump.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr98212.c21
2 files changed, 38 insertions, 0 deletions
diff --git a/gcc/dojump.c b/gcc/dojump.c
index 4c7fafe..b12bcea 100644
--- a/gcc/dojump.c
+++ b/gcc/dojump.c
@@ -1168,6 +1168,23 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
profile_probability first_prob = prob.split (cprob);
do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
size, NULL, if_true_label, first_prob);
+ if (orig_code == NE && can_compare_p (UNEQ, mode, ccp_jump))
+ {
+ /* x != y can be split into x unord y || x ltgt y
+ or x unord y || !(x uneq y). The latter has the
+ advantage that both comparisons are non-signalling and
+ so there is a higher chance that the RTL optimizations
+ merge the two comparisons into just one. */
+ code = UNEQ;
+ prob = prob.invert ();
+ if (! if_false_label)
+ {
+ if (! dummy_label)
+ dummy_label = gen_label_rtx ();
+ if_false_label = dummy_label;
+ }
+ std::swap (if_false_label, if_true_label);
+ }
}
}
}
diff --git a/gcc/testsuite/gcc.target/i386/pr98212.c b/gcc/testsuite/gcc.target/i386/pr98212.c
new file mode 100644
index 0000000..b8ed023
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98212.c
@@ -0,0 +1,21 @@
+/* PR rtl-optimization/98212 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mfpmath=sse -mno-avx" } */
+/* { dg-final { scan-assembler-times "\tucomiss\t" 2 } } */
+/* { dg-final { scan-assembler-not "\tcomiss\t" } } */
+
+void foo (void);
+
+void
+bar (float a, float b)
+{
+ if (a != b)
+ foo ();
+}
+
+void
+baz (float a, float b)
+{
+ if (a == b)
+ foo ();
+}