https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126313
--- Comment #13 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The trunk branch has been updated by Andrea Pinski <[email protected]>: https://gcc.gnu.org/g:8adc3726fe0c256f4ad36ba1c7d978261118e2f5 commit r17-2865-g8adc3726fe0c256f4ad36ba1c7d978261118e2f5 Author: Andrea Pinski <[email protected]> Date: Fri Jul 24 12:49:54 2026 -0700 gimple-fold: fix follow_outer_ssa_edges for undefined overflow cases [PR126313] 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. 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]>
