aboutsummaryrefslogtreecommitdiff
path: root/gcc/dojump.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-12-10 11:46:08 +0100
committerJakub Jelinek <jakub@redhat.com>2020-12-10 11:46:08 +0100
commit66dea8899df6475d5cb289491dbbff307c16c1a7 (patch)
tree4bea67d1dcec9e6977298d72c1d0abbaa6f80dd6 /gcc/dojump.c
parenta2a17ae7d85e420db5fe0c7ab2f59a470e2c7a78 (diff)
downloadgcc-66dea8899df6475d5cb289491dbbff307c16c1a7.zip
gcc-66dea8899df6475d5cb289491dbbff307c16c1a7.tar.gz
gcc-66dea8899df6475d5cb289491dbbff307c16c1a7.tar.bz2
dojump: Optimize a == a or a != a [PR98169]
If the backend doesn't have floating point EQ or NE comparison, dojump.c splits it into ORDERED && UNEQ or UNORDERED || LTGT. If both comparison operands are the same, we know the result of the second comparison though, a == b is equivalent to a ord b and a != b is equivalent to a unord b, and thus can just use ORDERED or UNORDERED. On the testcase, this changes f1: - ucomiss %xmm0, %xmm0 - movl $1, %eax - jp .L3 - jne .L3 - ret - .p2align 4,,10 - .p2align 3 -.L3: xorl %eax, %eax + ucomiss %xmm0, %xmm0 + setnp %al and f3: - ucomisd %xmm0, %xmm0 - movl $1, %eax - jp .L8 - jne .L8 - ret - .p2align 4,,10 - .p2align 3 -.L8: xorl %eax, %eax + ucomisd %xmm0, %xmm0 + setnp %al while keeping the same code for f2 and f4. 2020-12-10 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/98169 * dojump.c (do_compare_rtx_and_jump): Don't split self-EQ/NE comparisons, just use ORDERED or UNORDERED. * gcc.target/i386/pr98169.c: New test.
Diffstat (limited to 'gcc/dojump.c')
-rw-r--r--gcc/dojump.c8
1 files changed, 7 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