Re: [PATCH v2] gimple-fold: fix follow_outer_ssa_edges for undefined overflow cases [PR126313]
Richard Biener <[email protected]> Sat, 1 Aug 2026 08:15:13 +0200
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
> Am 01.08.2026 um 07:42 schrieb Andrea Pinski <[email protected]>: > > ifcombine uses match and match will use in some cases the global > range causing wrong code as the range of the ssa name might be based > on the outer condition. > The case in the bug report is: > ``` > > # RANGE [irange] int [0, 255] MASK 0xff VALUE 0x0 > _2 = (int) a.0_1; > if (_2 > 1) > goto <bb 4>; [59.00%] > else > goto <bb 3>; [41.00%] > > <bb 3> [local count: 440234144]: > # RANGE [irange] int [0, 1] MASK 0x1 VALUE 0x0 > _8 = (int) a.0_1; > if (_2 > _8) > goto <bb 4>; [50.00%] > else > goto <bb 5>; [50.00%] > ``` > So this was `(_2 <= 1 && _2 <= _8) ? goto 5 else; goto 4;` > This starts by combnining `_2 <= 1 && _2 <= _8` into `_2 <= min(1, _8)`. > But since _8 has a range of [0,1], match invokes the pattern that was added > in r14-868-gb06cfb62229f to giving `_2 <= (_8 & 1)` and then since _8 has a > range of [0,1], that expression simpifies into `_2 < _8` which is wrong. > as _2 is the same as _8. So we end up with not taking the condition any more. > > The problem comes follow_outer_ssa_edges is used to save off the global range > but we return early if the variable had a type where overflow is undefined as we > can't temporary rewrite it. So the fix is to swap around the saving the off > the global range before returning early. > > Bootstrapped and tested on x86_64-linux-gnu with no regressions. Ok Richard > PR tree-optimization/126313 > > gcc/ChangeLog: > > * gimple-fold.cc (follow_outer_ssa_edges): Swap around returning > for undefined overflow and saving off the global range. > > gcc/testsuite/ChangeLog: > > * gcc.dg/torture/pr126313.c: New test. > > Signed-off-by: Andrea Pinski <[email protected]> > --- > gcc/gimple-fold.cc | 13 ++++++------ > gcc/testsuite/gcc.dg/torture/pr126313.c | 27 +++++++++++++++++++++++++ > 2 files changed, 34 insertions(+), 6 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr126313.c > > diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc > index fdb9b419766..24041466108 100644 > --- a/gcc/gimple-fold.cc > +++ b/gcc/gimple-fold.cc > @@ -7677,17 +7677,18 @@ follow_outer_ssa_edges (tree val) > && (def_bb == fosa_bb > || dominated_by_p (CDI_DOMINATORS, fosa_bb, def_bb)))) > return val; > - /* We cannot temporarily rewrite stmts with undefined overflow > - behavior, so avoid expanding them. */ > - if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (val)) > - || POINTER_TYPE_P (TREE_TYPE (val))) > - && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (val))) > - return NULL_TREE; > flow_sensitive_info_storage storage; > storage.save_and_clear (val); > /* If the definition does not dominate fosa_bb temporarily reset > flow-sensitive info. */ > fosa_unwind->safe_push (std::make_pair (val, storage)); > + /* We cannot temporarily rewrite stmts with undefined overflow > + behavior, so avoid expanding them. But still save off the > + flow-sensitive info as we might be using the ssa name as the leaf. */ > + if ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (val)) > + || POINTER_TYPE_P (TREE_TYPE (val))) > + && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (val))) > + return NULL_TREE; > return val; > } > return val; > diff --git a/gcc/testsuite/gcc.dg/torture/pr126313.c b/gcc/testsuite/gcc.dg/torture/pr126313.c > new file mode 100644 > index 00000000000..f4b754775fd > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr126313.c > @@ -0,0 +1,27 @@ > +/* { dg-do run } */ > +/* PR tree-optimization/126313 */ > +unsigned char a = 3; > +short b, c, d; > +int e; > +static inline > +char(f)(signed char g, signed char p2) { > + return p2 == 0 || g && p2 == 1 ? 0 : g % p2; > +} > +static inline > +unsigned i(short g) { > + d = g; > + return c; > +} > +static inline > +void fn3(signed char g, int p2) { > + if (!(1 >= p2 && p2 <= g)) > + e = b | i(f(1, p2) > 0xE151060F); > + else { > + { d = p2; } > + } > +} > +int main() { > + fn3(a, a); > + if (d != 0) > + __builtin_abort (); > +} > -- > 2.43.0 >