aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2025-05-09 17:45:27 +0200
committerEric Botcazou <ebotcazou@adacore.com>2025-05-09 19:24:49 +0200
commit6683f2cd1ce07fc8470b19dc3c1578b3e0645c25 (patch)
tree3470dcceba1aa8e99bc501f7071ac4688d66dc98 /gcc/c
parent89ca647487b596cf1dda14075224d000fa542897 (diff)
downloadgcc-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')
0 files changed, 0 insertions, 0 deletions