Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@ class CodeGen final : public CodeGenInterface
#endif
void genCodeForTreeNode(GenTree* treeNode);
void genCodeForBinary(GenTreeOp* treeNode);
bool genIsSameLocalVar(GenTree* tree1, GenTree* tree2);

#if defined(TARGET_X86)
void genCodeForLongUMod(GenTreeOp* node);
Expand Down
42 changes: 22 additions & 20 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1143,28 +1143,11 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
// In order for this operation to be correct
// we need that op is a commutative operation so
// we can convert it into reg1 = reg1 op reg2 and emit
// the same code as above
// the same code as above. Or we need both operands to
// be the same local.
else if (op2reg == targetReg)
{

#ifdef DEBUG
unsigned lclNum1 = (unsigned)-1;
unsigned lclNum2 = (unsigned)-2;

GenTree* op1Skip = op1->gtSkipReloadOrCopy();
GenTree* op2Skip = op2->gtSkipReloadOrCopy();

if (op1Skip->OperIsLocalRead())
{
lclNum1 = op1Skip->AsLclVarCommon()->GetLclNum();
}
if (op2Skip->OperIsLocalRead())
{
lclNum2 = op2Skip->AsLclVarCommon()->GetLclNum();
}

assert(GenTree::OperIsCommutative(oper) || (lclNum1 == lclNum2));
#endif
assert(GenTree::OperIsCommutative(oper) || genIsSameLocalVar(op1, op2));

dst = op2;
src = op1;
Expand Down Expand Up @@ -1232,6 +1215,25 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
genProduceReg(treeNode);
}

//------------------------------------------------------------------------
// genIsSameLocalVar:
// Check if two trees represent the same scalar local value.
//
// Arguments:
// op1 - first tree
// op2 - second tree
//
// Returns:
// True if so.
//
bool CodeGen::genIsSameLocalVar(GenTree* op1, GenTree* op2)
{
GenTree* op1Skip = op1->gtSkipReloadOrCopy();
GenTree* op2Skip = op1->gtSkipReloadOrCopy();
return op1Skip->OperIs(GT_LCL_VAR) && op2Skip->OperIs(GT_LCL_VAR) &&
(op1Skip->AsLclVar()->GetLclNum() == op2Skip->AsLclVar()->GetLclNum());
}

//------------------------------------------------------------------------
// genCodeForMul: Generate code for a MUL operation.
//
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/hwintrinsiccodegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2240,7 +2240,8 @@ void CodeGen::genSSE42Intrinsic(GenTreeHWIntrinsic* node, insOpts instOptions)
{
assert(instOptions == INS_OPTS_NONE);

assert(!op2->isUsedFromReg() || (op2->GetRegNum() != targetReg) || (op1Reg == targetReg));
assert(!op2->isUsedFromReg() || (op2->GetRegNum() != targetReg) || (op1Reg == targetReg) ||
genIsSameLocalVar(op1, op2));
emit->emitIns_Mov(INS_mov, emitTypeSize(targetType), targetReg, op1Reg, /* canSkip */ true);

if ((baseType == TYP_UBYTE) || (baseType == TYP_USHORT)) // baseType is the type of the second argument
Expand Down
Loading