-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JIT: Loop hoisting re-ordering exceptions #6639
Comments
@JosephTremoulet: do you think this will make 1.2? |
Here it's probably worth pointing out that hoisting can be done correctly in the following case:
This is relatively easy to fix. When a non-hoistable node is encountered all previously encountered hoistable trees must be hoisted, not only its children. |
Contributes to issue #7147 - JIT: Loop hoisting re-ordering exceptions Added the Test case for Issue 26417
Contributes to issue #7147 - JIT: Loop hoisting re-ordering exceptions Added the Test case for Issue 26417 Updated comments
Contributes to issue #7147 - JIT: Loop hoisting re-ordering exceptions Added the Test case for Issue 26417 Updated comments Rebased
…e assigned a constant value. (#26952) * Fix issue #26417 = Incorrect caching of loop variable Contributes to issue #7147 - JIT: Loop hoisting re-ordering exceptions Added the Test case for Issue 26417
…e assigned a constant value. (dotnet#26952) * Fix issue #26417 = Incorrect caching of loop variable Contributes to issue #7147 - JIT: Loop hoisting re-ordering exceptions Added the Test case for Issue 26417
@BruceForstall still planning on fixing this in 6.0? |
Loop-hoisting optimization mentions in a comment that "We assume that expressions will be hoisted so that they are evaluated in the same order as they would have been in the loop," but that assumption doesn't hold with the current implementation. Consider the following code:
In the case of method
cross
, there's an invariant expression in the loop which may throw, but it is preceded by a variant expression which may throw a different kind of exception; the optimizer currently performs the hoist and changes the observable exception type.In the case of method
swap
, two invariant expressions are hoisted, but the order of their hoisted copies in the preheader is reversed from their order in the loop, which again is observable since the two invariant expressions can raise different types of exception.The sequence of events leading to the swapped order in
swap
is:x / y < i + c.f
is visited byoptHoistLoopExprsForTree
x / y
is recursively visited. It is marked as invariant and hoistable, but not hoisted yet because we're waiting to see if the whole parent expression is invariant and hoistable.i + c.f
is recursivley visitedi
is resursively visited, and found to be variantc.f
is recursively visited, and found to be invariant and hoistablei + c.f
is post-visited; it is not invariant or hoistable, but it has an invariant hoistable childc.f
, which is now hoistedx / y < i + c.f
is post-visited; it is not invariant or hoistable, but it has an invariant hoistable childx / y
, which is now hoistedThis same sequence of events swapping the hoisted expressions in
swap
was responsible for swapping a static field access and a static initializer call in dotnet/corefx#11524, due to which dotnet/coreclr#6889 was reverted in dotnet/coreclr#7118. It's possible this is the same issue prompting the workaround that disable hoisting of ClsVars.category:correctness
theme:loop-opt
skill-level:expert
cost:medium
The text was updated successfully, but these errors were encountered: