ins = (op1Type == TYP_FLOAT) ? INS_ucomiss : INS_ucomisd;
cmpAttr = emitTypeSize(op1Type);
+ var_types targetType = treeNode->TypeGet();
+
+ // Clear target reg in advance via "xor reg,reg" to avoid movzx after SETCC
+ if ((targetReg != REG_NA) && (op1->GetRegNum() != targetReg) && (op2->GetRegNum() != targetReg) &&
+ !varTypeIsByte(targetType))
+ {
+ regMaskTP targetRegMask = genRegMask(targetReg);
+ if (((op1->gtGetContainedRegMask() | op2->gtGetContainedRegMask()) & targetRegMask) == 0)
+ {
+ instGen_Set_Reg_To_Zero(emitTypeSize(TYP_I_IMPL), targetReg);
+ targetType = TYP_BOOL; // just a tip for inst_SETCC that movzx is not needed
+ }
+ }
GetEmitter()->emitInsBinary(ins, cmpAttr, op1, op2);
// Are we evaluating this into a register?
condition = GenCondition(GenCondition::P);
}
- inst_SETCC(condition, treeNode->TypeGet(), targetReg);
+ inst_SETCC(condition, targetType, targetReg);
genProduceReg(tree);
}
}
// Sign jump optimization should only be set the following check
assert((tree->gtFlags & GTF_RELOP_SJUMP_OPT) == 0);
+ var_types targetType = tree->TypeGet();
+
if (canReuseFlags && emit->AreFlagsSetToZeroCmp(op1->GetRegNum(), emitTypeSize(type), tree->OperGet()))
{
JITDUMP("Not emitting compare due to flags being already set\n");
}
else
{
+ // Clear target reg in advance via "xor reg,reg" to avoid movzx after SETCC
+ if ((targetReg != REG_NA) && (op1->GetRegNum() != targetReg) && (op2->GetRegNum() != targetReg) &&
+ !varTypeIsByte(targetType))
+ {
+ regMaskTP targetRegMask = genRegMask(targetReg);
+ if (((op1->gtGetContainedRegMask() | op2->gtGetContainedRegMask()) & targetRegMask) == 0)
+ {
+ instGen_Set_Reg_To_Zero(emitTypeSize(TYP_I_IMPL), targetReg);
+ targetType = TYP_BOOL; // just a tip for inst_SETCC that movzx is not needed
+ }
+ }
emit->emitInsBinary(ins, emitTypeSize(type), op1, op2);
}
// Are we evaluating this into a register?
if (targetReg != REG_NA)
{
- inst_SETCC(GenCondition::FromIntegralRelop(tree), tree->TypeGet(), targetReg);
+ inst_SETCC(GenCondition::FromIntegralRelop(tree), targetType, targetReg);
genProduceReg(tree);
}
}
}
//---------------------------------------------------------------
+// gtGetContainedRegMask: Get the reg mask of the node including
+// contained nodes (recursive).
+//
+// Arguments:
+// None
+//
+// Return Value:
+// Reg Mask of GenTree node.
+//
+regMaskTP GenTree::gtGetContainedRegMask()
+{
+ if (!isContained())
+ {
+ return gtGetRegMask();
+ }
+
+ regMaskTP mask = 0;
+ for (GenTree* operand : Operands())
+ {
+ mask |= operand->gtGetContainedRegMask();
+ }
+ return mask;
+}
+
+//---------------------------------------------------------------
// gtGetRegMask: Get the reg mask of the node.
//
// Arguments: