diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2025-05-09 17:45:27 +0200 |
---|---|---|
committer | Eric Botcazou <ebotcazou@adacore.com> | 2025-05-09 19:24:49 +0200 |
commit | 6683f2cd1ce07fc8470b19dc3c1578b3e0645c25 (patch) | |
tree | 3470dcceba1aa8e99bc501f7071ac4688d66dc98 /gcc/c/c-parser.cc | |
parent | 89ca647487b596cf1dda14075224d000fa542897 (diff) | |
download | gcc-6683f2cd1ce07fc8470b19dc3c1578b3e0645c25.zip gcc-6683f2cd1ce07fc8470b19dc3c1578b3e0645c25.tar.gz gcc-6683f2cd1ce07fc8470b19dc3c1578b3e0645c25.tar.bz2 |
Fix wrong optimization of complex boolean expression
The VRP2 pass turns:
# prephitmp_3 = PHI <0(4)>
_1 = prephitmp_3 == 0;
_5 = stretch_14(D) ^ 1;
_39 = _1 & _5;
_40 = _39 | last_20(D);
into
_5 = stretch_14(D) ^ 1;
_42 = ~stretch_14(D);
_39 = _42;
_40 = last_20(D) | _39;
using the following step:
Folding statement: _1 = prephitmp_3 == 0;
Queued stmt for removal. Folds to: 1
Folding statement: _5 = stretch_14(D) ^ 1;
Not folded
Folding statement: _39 = _1 & _5;
gimple_simplified to _42 = ~stretch_14(D);
_39 = _42 & 1;
Folded into: _39 = _42;
Folding statement: _40 = _39 | last_20(D);
Folded into: _40 = last_20(D) | _39;
but stretch_14 is a 8-bit boolean so the two forms are not equivalent, that
is to say dropping the "& 1" is wrong. It's another instance of the issue:
https://gcc.gnu.org/pipermail/gcc-patches/2020-November/558537.html
Here it's the reverse case: the bitwise NOT (~) is treated as logical by the
machinery in range-op.cc but the bitwise AND (&) is *not* treated as logical
by that of vr-values.cc, leading to the same problematic outcome.
gcc/
* vr-values.cc (simplify_using_ranges::simplify) <BIT_AND_EXPR>:
Do not call simplify_bit_ops_using_ranges for boolean types whose
precision is not 1.
gcc/testsuite/
* gnat.dg/opt106.adb: New test.
* gnat.dg/opt106_pkg1.ads, gnat.dg/opt106_pkg1.adb: New helper.
* gnat.dg/opt106_pkg2.ads, gnat.dg/opt106_pkg2.adb: Likewise.
Diffstat (limited to 'gcc/c/c-parser.cc')
0 files changed, 0 insertions, 0 deletions