diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-05-21 10:39:50 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-05-21 10:39:50 +0200 |
commit | f1c777f40aa0b6941efc7440495a8d7e0cc2a1bb (patch) | |
tree | 53fbb4793efdf8a510bcf20a937509018caa33b2 /gcc/ada/gcc-interface/trans.c | |
parent | f53aff92acef9d5291ffed72995adc33e91fa209 (diff) | |
download | gcc-f1c777f40aa0b6941efc7440495a8d7e0cc2a1bb.zip gcc-f1c777f40aa0b6941efc7440495a8d7e0cc2a1bb.tar.gz gcc-f1c777f40aa0b6941efc7440495a8d7e0cc2a1bb.tar.bz2 |
tree-optimization: Improve spaceship_replacement [PR94589]
On Wed, May 19, 2021 at 01:30:31PM -0400, Jason Merrill via Gcc-patches wrote:
> Here, when genericizing lexicographical_compare_three_way, we haven't yet
> walked the operands, so (a == a) still sees ADDR_EXPR <a>, but this is after
> we've changed the type of a to REFERENCE_TYPE. When we try to fold (a == a)
> by constexpr evaluation, the constexpr code doesn't understand trying to
> take the address of a reference, and we end up crashing.
>
> Fixed by avoiding constexpr evaluation in genericize_spaceship, by using
> fold_build2 instead of build_new_op on scalar operands. Class operands
> should have been expanded during parsing.
Unfortunately this slightly changed the IL and spaceship_replacement no
longer pattern matches it.
Here are 3 improvements that make it match:
1) as mentioned in the comment above spaceship_replacement, for
strong_ordering, we are pattern matching something like:
x == y ? 0 : x < y ? -1 : 1;
and for partial_ordering
x == y ? 0 : x < y ? -1 : x > y ? 1 : 2;
but given the == comparison done first and the other comparisons only
if == was false, we actually don't care if the other comparisons
are < vs. <= (or > vs. >=), provided the operands of the comparison
are the same; we know == is false when doing those and < vs. <= or
> vs. >= have the same behavior for NaNs too
2) when y is an integral constant, we should treat x < 5 equivalently
to x <= 4 etc.
3) the code punted if cond2_phi_edge wasn't a EDGE_TRUE_VALUE edge, but
as the new IL shows, that isn't really needed; given 1) that
> and >= are equivalent in the code, any of swapping the comparison
operands, changing L[TE]_EXPR to G[TE]_EXPR or vice versa or
swapping the EDGE_TRUE_VALUE / EDGE_FALSE_VALUE bits on the edges
reverses one of the two comparisons
2021-05-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94589
* tree-ssa-phiopt.c (spaceship_replacement): For integral rhs1 and
rhs2, treat x <= 4 equivalently to x < 5 etc. In cmp1 and cmp2 (if
not the same as cmp3) treat <= the same as < and >= the same as >.
Don't require that cond2_phi_edge is true edge, instead take
false/true edges into account based on cmp1/cmp2 comparison kinds.
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
0 files changed, 0 insertions, 0 deletions