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.

Reply via email to