From 5bd71df7c144b6de57713db5d1080b6505a9d5b4 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 28 Apr 2026 01:51:40 +0800 Subject: [PATCH] Prevent ICE in SSA range propagation when CFG contains self- loops Replace self-loop assumptions in ssa_range_prop terminator handling with guards that skip range insertion when successor is in the same block. Add a UI regression test for issue #155836 to ensure optimized builds no longer ICE. Fixes #155836 Constraint: Keep propagation behavior unchanged for non- self-loop edges Rejected: Keep assert_ne! and special-case only Assert arm | still leaves SwitchInt self-loop paths vulnerable Confidence: high Scope-risk: narrow Reversibility: clean Directive: Do not reintroduce block-inequality assertions in terminator propagation without proving CFG invariants after simplification Tested: ./x.py check compiler/rustc_mir_transform; ./x.py test tests/ui/mir/ssa-range-prop-self-loop-155836.rs Not-tested: Broader SwitchInt multi-target stress cases --- .../rustc_mir_transform/src/ssa_range_prop.rs | 28 +++++++++++-------- .../ui/mir/ssa-range-prop-self-loop-155836.rs | 13 +++++++++ 2 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 tests/ui/mir/ssa-range-prop-self-loop-155836.rs diff --git a/compiler/rustc_mir_transform/src/ssa_range_prop.rs b/compiler/rustc_mir_transform/src/ssa_range_prop.rs index 97ba07d900960..9f9a74d4bd237 100644 --- a/compiler/rustc_mir_transform/src/ssa_range_prop.rs +++ b/compiler/rustc_mir_transform/src/ssa_range_prop.rs @@ -164,10 +164,11 @@ impl<'tcx> MutVisitor<'tcx> for RangeSet<'tcx, '_, '_> { { let successor = Location { block: *target, statement_index: 0 }; if location.dominates(successor, &self.dominators) { - assert_ne!(location.block, successor.block); - let val = *expected as u128; - let range = WrappingRange { start: val, end: val }; - self.insert_range(place, successor, range); + if location.block != successor.block { + let val = *expected as u128; + let range = WrappingRange { start: val, end: val }; + self.insert_range(place, successor, range); + } } } TerminatorKind::SwitchInt { discr, targets } @@ -188,7 +189,9 @@ impl<'tcx> MutVisitor<'tcx> for RangeSet<'tcx, '_, '_> { } let successor = Location { block: target, statement_index: 0 }; if self.unique_predecessors.contains(successor.block) { - assert_ne!(location.block, successor.block); + if location.block == successor.block { + continue; + } let range = WrappingRange { start: val, end: val }; self.insert_range(place, successor, range); } @@ -201,13 +204,14 @@ impl<'tcx> MutVisitor<'tcx> for RangeSet<'tcx, '_, '_> { && let [val] = targets.all_values() && self.unique_predecessors.contains(otherwise.block) { - assert_ne!(location.block, otherwise.block); - let range = if val.get() == 0 { - WrappingRange { start: 1, end: 1 } - } else { - WrappingRange { start: 0, end: 0 } - }; - self.insert_range(place, otherwise, range); + if location.block != otherwise.block { + let range = if val.get() == 0 { + WrappingRange { start: 1, end: 1 } + } else { + WrappingRange { start: 0, end: 0 } + }; + self.insert_range(place, otherwise, range); + } } } _ => {} diff --git a/tests/ui/mir/ssa-range-prop-self-loop-155836.rs b/tests/ui/mir/ssa-range-prop-self-loop-155836.rs new file mode 100644 index 0000000000000..9e7df9adca909 --- /dev/null +++ b/tests/ui/mir/ssa-range-prop-self-loop-155836.rs @@ -0,0 +1,13 @@ +// Regression test for . +// Ensure SSA range propagation does not ICE on self-loops. +//@ compile-flags: -C opt-level=2 +//@ check-pass + +#![crate_type = "lib"] + +pub fn trigger(b: usize) -> usize { + while 0 != 2 { + b % b; + } + b +}