diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2023-02-13 11:38:45 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2023-02-13 11:38:45 +0000 |
commit | 7d5a935070ed4a49e947a64b2391a1f5fa9b8f66 (patch) | |
tree | c74a6121b29d19d3b19e411d67937a7adf91abf7 /gcc/debug.cc | |
parent | 1e191d19b5c182c9e919ca2a331e52b68132f7ac (diff) | |
download | gcc-7d5a935070ed4a49e947a64b2391a1f5fa9b8f66.zip gcc-7d5a935070ed4a49e947a64b2391a1f5fa9b8f66.tar.gz gcc-7d5a935070ed4a49e947a64b2391a1f5fa9b8f66.tar.bz2 |
ifcvt: Fix regression in aarch64/fcsel_1.c
aarch64/fcsel_1.c contains:
double
f_2 (double a, double b, double c, double d)
{
if (a > b)
return c;
else
return d;
}
which started failing in the GCC 12 timeframe. When it passed,
the RTL had the form:
[A]
(set (reg ret) (reg c))
(set (pc) (if_then_else (gt ...) (label_ref ret) (pc)))
edge to ret, fallthru to else
else:
(set (reg ret) (reg d))
fallthru to ret
ret:
...exit...
i.e. a branch around. Now the RTL has form:
[B]
(set (reg ret) (reg d))
(set (pc) (if_then_else (gt ...) (label_ref then) (pc)))
edge to then, fallthru to ret
ret:
...exit...
then:
(set (reg ret) (reg c))
edge to ret
i.e. a branch out.
Both are valid, of course, and there's no easy way to predict
which we'll get. But ifcvt canonicalises its representation on:
if (cond) goto fallthru else goto non-fallthru
That is, it canoncalises on the branch-around case for half-diamonds.
It therefore wants to invert the comparison in [B] to get:
if (...) goto ret else goto then
But that isn't possible for strict FP gt, so the optimisation fails.
Canonicalising on the branch-around case seems like the wrong choice for
half diamonds. The natural way of expressing a conditional branch is
for the label_ref to be the "then" destination and pc to be the "else"
destination. And the natural choice of condition seems to be the one
under which extra stuff *is* done, rather than the one under which extra
stuff *isn't* done. But that decision goes back at least 20 years and
it doesn't seem like a good idea to change it in stage 4.
This patch instead allows the internal structure to store the
condition in inverted form. For simplicity it handles only
conditional moves, which is the one case that is needed
to fix the known regression. (There are probably unknown
regressions too, but still.)
gcc/
* ifcvt.h (noce_if_info::cond_inverted): New field.
* ifcvt.cc (cond_move_convert_if_block): Swap the then and else
values when cond_inverted is true.
(noce_find_if_block): Allow the condition to be inverted when
handling conditional moves.
Diffstat (limited to 'gcc/debug.cc')
0 files changed, 0 insertions, 0 deletions