You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Loops with i != end previously kept their per-iteration bounds checks while the equivalent < / > forms did not, because loop cloning bailed on GT_NE.
Recognize GT_NE with stride exactly +/-1 as an increasing or decreasing loop in NaturalLoopIterInfo, extend optDeriveLoopCloningConditions to emit the right per-access and zero-trip conditions for GT_NE, and add a new "init RELOP end" cloning condition so that a misordered init (which for GT_NE would wrap the IV through the type rather than exit at the first test) falls back to the slow path. Builds on #129176 which fixes the latent decreasing-loop soundness gap.
A follow-on change to assertion prop / range check will catch the remaining NE-loop BCE cases that fall outside loop cloning (e.g. loops the cloning heuristic rejects).
Loops with `i != end` previously kept their per-iteration bounds
checks while the equivalent `<` / `>` forms did not, because loop
cloning bailed on GT_NE.
Recognize GT_NE with stride exactly +/-1 as an increasing or decreasing
loop in NaturalLoopIterInfo, extend optDeriveLoopCloningConditions to
emit the right per-access and zero-trip conditions for GT_NE, and add a
new "init RELOP end" cloning condition so that a misordered init (which
for GT_NE would wrap the IV through the type rather than exit at the
first test) falls back to the slow path. Builds on dotnet#129176 which fixes
the latent decreasing-loop soundness gap.
A follow-on change to assertion prop / range check will catch the
remaining NE-loop BCE cases that fall outside loop cloning (e.g. loops
the cloning heuristic rejects).
Contributes to dotnet#84697.
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR extends CoreCLR JIT loop cloning analysis to treat certain i != limit loops (specifically stride ±1) as monotonic increasing/decreasing loops, enabling the same cloning-based bounds-check elimination previously available for ordered relational loop conditions.
Changes:
Recognize GT_NE loop tests as clonable when the induction variable step is exactly +1 or -1 (NaturalLoopIterInfo::IsIncreasingLoop/IsDecreasingLoop).
Update loop-cloning condition derivation to accept GT_NE, emit appropriate zero-trip/per-access guards, and add an extra init-vs-limit ordering guard for GT_NE.
Add a new JIT regression test covering != loops across arrays/strings/spans, including soundness scenarios.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
File
Description
src/coreclr/jit/loopcloning.cpp
Extends cloning-condition derivation to handle GT_NE loops (stride ±1) with additional guards for safety.
src/coreclr/jit/flowgraph.cpp
Classifies GT_NE + stride ±1 loops as increasing/decreasing in NaturalLoopIterInfo.
src/tests/JIT/Regression/Regression_o_3.csproj
Includes the new regression test source file in the JIT regression project.
Loops with `i != end` previously kept their per-iteration bounds checks
while the equivalent `<` / `>` forms did not, because loop cloning
bailed on GT_NE.
Recognize GT_NE with stride exactly +/-1 as an increasing or decreasing
loop in NaturalLoopIterInfo, extend optDeriveLoopCloningConditions to
emit the right per-access and zero-trip conditions for GT_NE, and add a
new "init RELOP end" cloning condition so that a misordered init (which
for GT_NE would wrap the IV through the type rather than exit at the
first test) falls back to the slow path. Builds on #129176 which fixes
the latent decreasing-loop soundness gap.
A follow-on change to assertion prop / range check will catch the
remaining NE-loop BCE cases that fall outside loop cloning (e.g. loops
the cloning heuristic rejects).
Contributes to #84697.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Loops with
i != endpreviously kept their per-iteration bounds checks while the equivalent</>forms did not, because loop cloning bailed on GT_NE.Recognize GT_NE with stride exactly +/-1 as an increasing or decreasing loop in NaturalLoopIterInfo, extend optDeriveLoopCloningConditions to emit the right per-access and zero-trip conditions for GT_NE, and add a new "init RELOP end" cloning condition so that a misordered init (which for GT_NE would wrap the IV through the type rather than exit at the first test) falls back to the slow path. Builds on #129176 which fixes the latent decreasing-loop soundness gap.
A follow-on change to assertion prop / range check will catch the remaining NE-loop BCE cases that fall outside loop cloning (e.g. loops the cloning heuristic rejects).
Contributes to #84697.