https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127693
--- Comment #1 from Thiago Macieira <thiago at kde dot org> --- The following is the analysis done by the AI. I cannot verify the GIMPLE analysis, but the outer reasoning is sound: 1. While inlining `indexOf` into `f`, the inliner's function summary evaluates `__builtin_constant_p(s.m_size)` as true, because `m_size == 1` is known at the call site. The edge to `findString()` gets `predicate: (false)` and is redirected to `__builtin_unreachable()`. The `095i.inline` dump shows: ``` Introduced new external node (void __builtin_unreachable()/9). void __builtin_unreachable()/9 unreachable ... predicate: (false) ``` After IPA (`fixup_cfg3`) the body looks like this: ``` s = sought; s$m_size_12 = s.m_size; _13 = __builtin_constant_p (s$m_size_12); if (_13 != 0) goto <bb 5>; else goto <bb 7>; <bb 5>: if (s$m_size_12 == 1) goto <bb 6>; else goto <bb 7>; <bb 6>: _14 = findChar (_10); ... <bb 7>: __builtin_unreachable (); ``` 2. The later passes (FRE/VRP) never forward the value `1` into the loop-carried load `s.m_size`, so `vrp1` folds `__builtin_constant_p (s$m_size_12)` to 0. The only remaining path then leads to `__builtin_unreachable()`, and the function body is deleted. So the IPA-time evaluation of `__builtin_constant_p` and its later folding disagree. Either the inliner shouldn't turn the non-constant arm into `unreachable` unless it can guarantee the builtin will fold to 1, or the folding of a `__builtin_constant_p` whose predicate was already assumed true must be consistent with that. Adding `[[assume((unsigned long)m_size <= 0x3ffffffffffffffe)]]` in a `size()` accessor that `scan` calls makes the miscompile show up at `-O3` too. GCC emits `.ASSUME (fn, &sought)` and that blocks the same forwarding.
