Uh oh!
There was an error while loading. Please reload this page.
JIT: Improve constant folding for commutative operators - #656
Conversation
sandreenko
left a comment
There was a problem hiding this comment.
The idea looks good, I have a few questions about the pre-existing logic here, that could lead to new errors if you apply it more broadly.
Why did you decide to delete the tests?
Uh oh!
There was an error while loading. Please reload this page.
| { | ||
| // Don't create a byref pointer that may point outside of the ref object. | ||
| // If a GC happens, the byref won't get updated. This can happen if one | ||
| // of the int components is negative. It also requires the address generation |
There was a problem hiding this comment.
// It also requires the address generation be in a fully-interruptible code region.
That comment looks incorrect, at least I do not see where we check that a fully-interruptible code region condition.
It is also not clear for me in which case that optimization for varTypeIsGC is incorrect, could somebody explain that to me please?
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
@sandreenko thanks for feedback, will try to address it soon, sorry for the delay. |
EgorBo
commented
Jan 12, 2020
@sandreenko could you please re-review? thanks |
sandreenko
left a comment
There was a problem hiding this comment.
Thanks for the update, @EgorBo.
The checks for each case are not obvious, could you please explain them to me?
| // If a GC happens, the byref won't get updated. This can happen if one | ||
| // of the int components is negative. It also requires the address generation | ||
| // be in a fully-interruptible code region. | ||
| if (!varTypeIsGC(op1->AsOp()->gtGetOp1()->TypeGet()) && !varTypeIsGC(op2->AsOp()->gtGetOp1()->TypeGet())) |
There was a problem hiding this comment.
here you check varTypeIsGC(x), varTypeIsGC(y), gtIsActiveCSE_Candidate(op2).
There was a problem hiding this comment.
Added also gtIsActiveCSE_Candidate(op1) here
| if (op2->IsCnsIntOrI() && varTypeIsIntegralOrI(tree->TypeGet())) | ||
| { | ||
| // Fold "((x <op> icon1) <op> icon2) to (x <op> (icon1 <op> icon2))" | ||
| if (op1->OperIs(oper) && !gtIsActiveCSE_Candidate(op1) && op1->AsOp()->gtGetOp2()->IsCnsIntOrI() && |
There was a problem hiding this comment.
here you check varTypeIsGC(icon1)? why does it need that check? Why don't you need to check x here as you do in the previous case?
You check gtIsActiveCSE_Candidate(op1), in the previous case you were checking gtIsActiveCSE_Candidate(op2), what is the difference?
There was a problem hiding this comment.
removed varTypeIsGC(icon1) and added gtIsActiveCSE_Candidate(op1) to the first expression
| const ssize_t icon1 = cns1->IconValue(); | ||
| const ssize_t icon2 = cns2->IconValue(); | ||
| if (oper == GT_ADD) |
There was a problem hiding this comment.
that code duplication doesn't look cool, but a function with 6 arguments GenTreeIntConCommon* fgGetCommutativeResult(oper, icon1, icon2, tree, op1, optional op2) also doesn't. I am not sure here.
There was a problem hiding this comment.
Neither am I, tried to simplify it a bit. Let me know if I should extract it to a separate method.
sandreenko
commented
Jan 16, 2020
Please take a look at the new test failures after the last change that I have not seen before, like x86 windows: |
stephentoub
commented
Feb 17, 2020
@EgorBo, still working on this? Thanks. |
stephentoub
commented
Mar 13, 2020
@EgorBo, seems like you're not working on this anymore. Shall we close it? |
EgorBo
commented
Mar 16, 2020
Sorry, will re-open it later with proper fixes 🙁 |
Moved from dotnet/coreclr: dotnet/coreclr#27325
This PR re-uses existing
GT_ADDconstant folding logic for other commutative operators, e.g.:Diff for the snippet above: https://www.diffchecker.com/1Us280l1
Jit-utills Diff: https://gist.github.com/EgorBo/1238cbde8226194c554b4de83a900609
cc @dotnet/jit-contrib