https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127401
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |pinskia at gcc dot gnu.org
Ever confirmed|0 |1
Last reconfirmed| |2026-09-15
Status|UNCONFIRMED |NEW
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed. This is because hoist_adjacent_loads speculates a bool load without
appropriately rewriting it (or disallowing such speculation).
LLM:
The miscompilation of obj/gcc/t.c occurred because the hoist_adjacent_loads
pass in gcc/tree-ssa-phiopt.cc speculatively hoisted adjacent loads from a
conditional diamond pattern to the entry block. In the testcase:
- s->b (represented as 2 in memory via a union) was only loaded inside the
else branch of if (c).
- When c = 1 and d = 1, s->b was not supposed to be loaded in the abstract
machine.
- However, hoist_adjacent_loads hoisted both s->a and s->b into the entry
block unconditionally.
- Since s->b was now unconditionally loaded, a subsequent phiopt pass
simplified the PHI q_9 = PHI <1(bb with d != 0), s_b(bb with d == 0)> to a
bitwise OR d | s_b.
- Because the compiler assumes any boolean type value is strictly in the
range [0, 1], it executed the OR directly on the speculatively loaded
invalid value 2. This resulted in 1 | 2 = 3 instead of 1, causing the
final
output of 1 * 16 + 3 = 19 instead of 17.