diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-12-10 11:46:08 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-12-10 11:46:08 +0100 |
commit | 66dea8899df6475d5cb289491dbbff307c16c1a7 (patch) | |
tree | 4bea67d1dcec9e6977298d72c1d0abbaa6f80dd6 /gcc/dojump.c | |
parent | a2a17ae7d85e420db5fe0c7ab2f59a470e2c7a78 (diff) | |
download | gcc-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.c | 8 |
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 |