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
{{ message }}
Repository navigation
JIT generates redundant mov for inline ++i (pre-increment) #129532
This is not what this issue is talking about but why is this loop cloned? There are no bounds checks. Maybe I am missunderstanding what loop cloning does. It wasn't cloned previously. @AndyAyersMS
We get:
Would it make sense to first do all rangechecks opts and stuff and only at the very end if we still have BOUNDS_CHECK_Rng clone the loop.
Sometimes yes, sometimes no. The cloning is itself an enabling optimization for other phases. In general there is no silver bullet for this phase ordering problem.
I did some digging and found out that Roslyn emits dup for inline (uint)++i, which the JIT importer (importer.cpp, CEE_DUP handler) materializes as a temp via lvaGrabTemp. This temp is again used in storing the value to i and in indexing the array. So the interval is kept alive past the STORE_LCL_VAR.
Activity
dotnet-policy-service commentedon Jun 17, 2026
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.
BoyBaykiller commentedon Jun 17, 2026
This is not what this issue is talking about but why is this loop cloned? There are no bounds checks. Maybe I am missunderstanding what loop cloning does. It wasn't cloned previously. @AndyAyersMS
We get:
While I would have expected this (with
DOTNET_JitCloneLoops=0to repro):AndyAyersMS commentedon Jun 18, 2026
My guess is that we cloned to get rid of the bounds check and then were also able to get rid of the bounds check in the slow loop via other means.
Often when that happens we're also able to optimize away the slow loop so we end up more or less with your after picture. But evidently not so here.
Feel free to investigate further. I could be wrong.
BoyBaykiller commentedon Jun 18, 2026
Would it make sense to first do all rangechecks opts and stuff and only at the very end if we still have
BOUNDS_CHECK_Rngclone the loop.jakobbotsch commentedon Jun 18, 2026
Sometimes yes, sometimes no. The cloning is itself an enabling optimization for other phases. In general there is no silver bullet for this phase ordering problem.
Venkad000 commentedon Jun 26, 2026
I reproduced this on ARM64 (Apple Silicon) where loop cloning doesn't appear to interfere, and the pattern is visible directly:
vs. separate ++i;:
I did some digging and found out that Roslyn emits dup for inline (uint)++i, which the JIT importer (importer.cpp, CEE_DUP handler) materializes as a temp via lvaGrabTemp. This temp is again used in storing the value to i and in indexing the array. So the interval is kept alive past the STORE_LCL_VAR.
I would like to work on this with some guidance.