https://gcc.gnu.org/g:7dab38c9d7104ea701a60ef71837695f24aec86b
commit r17-4029-g7dab38c9d7104ea701a60ef71837695f24aec86b Author: Aldy Hernandez <[email protected]> Date: Thu Sep 3 08:24:38 2026 +0000 phiopt: clear the range info of hoisted adjacent loads hoist_adjacent_loads moves the two loads from under the condition of the diamond into its head, but keeps the range info computed for them under the condition. Clear it. A follow-up patch to range_from_readonly_load takes the range of a load from a constant aggregate from its index: struct S { int a, b; }; static const struct S sa[4] = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; if (i < 2) r = sa[i].a; /* [1, 3] here, [1, 7] before the if */ else r = sa[i].b; if (sa[i].a > 3) /* folds to false */ ... Nothing on trunk gives a load a range that depends on where it sits, so the wrong code cannot be exercised on its own. The testcase comes with the follow-on patch that provides this functionality, which generates wrong code without this patch: chicken and egg :). -fhoist-adjacent-loads is off by default, so nothing changes without it. With it enabled the assembly over a corpus of .ii files from a stage1 bootstrap is identical, though the transformation never fires there; a hand-written case that does hoist also generates identical code. Tested on ppc64le Linux. gcc/ChangeLog: * tree-ssa-phiopt.cc (hoist_adjacent_loads): Clear the range info of the hoisted loads. Diff: --- gcc/tree-ssa-phiopt.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index 6e17d21b58c0..7203f4d29c88 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -4569,6 +4569,10 @@ hoist_adjacent_loads (basic_block bb0, basic_block bb1, gsi_move_to_bb_end (&gsi2, bb0); gsi2 = gsi_for_stmt (def2); gsi_move_to_bb_end (&gsi2, bb0); + /* Clear range info from the defs we've moved from under the + condition. */ + reset_flow_sensitive_info (gimple_assign_lhs (def1)); + reset_flow_sensitive_info (gimple_assign_lhs (def2)); statistics_counter_event (cfun, "hoisted loads", 1); if (dump_file && (dump_flags & TDF_DETAILS))
