https://godbolt.org/z/x3e349nEW
uint ConstSubVar(uint x)
{
return 32 - x;
}
Program:ConstSubVar(uint):uint:this (FullOpts):
mov eax, esi
neg eax
add eax, 32
ret
Should be:
Program:ConstSubVar(uint):uint:this (FullOpts):
mov eax, 32
sub eax, esi
ret
We canonicalize into (cns1 + (-op2)) in morph:
|
/* Check for "cns1 - op2" , we change it to "(cns1 + (-op2))" */ |
|
|
|
noway_assert(op1); |
|
if (op1->IsCnsIntOrI()) |
|
{ |
|
noway_assert(varTypeIsIntegralOrI(tree)); |
|
|
|
// The type of the new GT_NEG node cannot just be op2->TypeGet(). |
|
// Otherwise we may sign-extend incorrectly in cases where the GT_NEG |
|
// node ends up feeding directly into a cast, for example in |
|
// GT_CAST<ubyte>(GT_SUB(0, s_1.ubyte)) |
|
|
|
if (op1->IsIntegralConst(0)) |
|
{ |
|
tree->ChangeOper(GT_NEG); |
|
tree->gtType = genActualType(op2->TypeGet()); |
|
|
|
tree->AsOp()->gtOp1 = op2; |
|
tree->AsOp()->gtOp2 = nullptr; |
|
|
|
DEBUG_DESTROY_NODE(op1); |
|
return tree; |
|
} |
|
|
|
tree->AsOp()->gtOp2 = op2 = gtNewOperNode(GT_NEG, genActualType(op2->TypeGet()), op2); |
|
fgMorphTreeDone(op2); |
|
|
|
oper = GT_ADD; |
|
tree->ChangeOper(oper); |
|
goto CM_ADD_OP; |
|
} |
https://godbolt.org/z/x3e349nEW
Should be:
We canonicalize into
(cns1 + (-op2))in morph:runtime/src/coreclr/jit/morph.cpp
Lines 7890 to 7920 in 209c66f