Skip to content

Commit a0397e7

Browse files
authored
[RISC-V] Reverse unordered FP comparisons in branches (#115943)
* Reverse unordered comparisons * Codegen haircut
1 parent cdb1b8f commit a0397e7

File tree

2 files changed

+37
-56
lines changed

2 files changed

+37
-56
lines changed

src/coreclr/jit/codegenriscv64.cpp

Lines changed: 25 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3129,65 +3129,38 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree)
31293129

31303130
if (varTypeIsFloating(op1Type))
31313131
{
3132-
bool isUnordered = (tree->gtFlags & GTF_RELOP_NAN_UN) != 0;
3133-
regNumber regOp1 = op1->GetRegNum();
3134-
regNumber regOp2 = op2->GetRegNum();
3132+
assert(!op2->isContainedIntOrIImmed());
3133+
assert(op1Type == op2Type);
3134+
genTreeOps oper = tree->OperGet();
31353135

3136+
bool isUnordered = (tree->gtFlags & GTF_RELOP_NAN_UN) != 0;
31363137
if (isUnordered)
31373138
{
3138-
if (tree->OperIs(GT_LT))
3139-
{
3140-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_fle_s : INS_fle_d, cmpSize, targetReg, regOp2, regOp1);
3141-
}
3142-
else if (tree->OperIs(GT_LE))
3143-
{
3144-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_flt_s : INS_flt_d, cmpSize, targetReg, regOp2, regOp1);
3145-
}
3146-
else if (tree->OperIs(GT_NE))
3147-
{
3148-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_feq_s : INS_feq_d, cmpSize, targetReg, regOp1, regOp2);
3149-
}
3150-
else if (tree->OperIs(GT_GT))
3151-
{
3152-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_fle_s : INS_fle_d, cmpSize, targetReg, regOp1, regOp2);
3153-
}
3154-
else if (tree->OperIs(GT_GE))
3155-
{
3156-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_flt_s : INS_flt_d, cmpSize, targetReg, regOp1, regOp2);
3157-
}
3158-
else
3159-
{
3160-
unreached();
3161-
}
3162-
emit->emitIns_R_R_I(INS_xori, EA_8BYTE, targetReg, targetReg, 1);
3139+
oper = GenTree::ReverseRelop(oper);
31633140
}
3164-
else
3141+
if (oper == GT_GT || oper == GT_GE)
31653142
{
3166-
if (tree->OperIs(GT_LT))
3167-
{
3168-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_flt_s : INS_flt_d, cmpSize, targetReg, regOp1, regOp2);
3169-
}
3170-
else if (tree->OperIs(GT_LE))
3171-
{
3172-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_fle_s : INS_fle_d, cmpSize, targetReg, regOp1, regOp2);
3173-
}
3174-
else if (tree->OperIs(GT_EQ))
3175-
{
3176-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_feq_s : INS_feq_d, cmpSize, targetReg, regOp1, regOp2);
3177-
}
3178-
else if (tree->OperIs(GT_GT))
3179-
{
3180-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_flt_s : INS_flt_d, cmpSize, targetReg, regOp2, regOp1);
3181-
}
3182-
else if (tree->OperIs(GT_GE))
3183-
{
3184-
emit->emitIns_R_R_R(cmpSize == EA_4BYTE ? INS_fle_s : INS_fle_d, cmpSize, targetReg, regOp2, regOp1);
3185-
}
3186-
else
3187-
{
3143+
oper = GenTree::SwapRelop(oper);
3144+
std::swap(op1, op2);
3145+
}
3146+
instruction instr = INS_none;
3147+
switch (oper)
3148+
{
3149+
case GT_LT:
3150+
instr = (cmpSize == EA_4BYTE) ? INS_flt_s : INS_flt_d;
3151+
break;
3152+
case GT_LE:
3153+
instr = (cmpSize == EA_4BYTE) ? INS_fle_s : INS_fle_d;
3154+
break;
3155+
case GT_EQ:
3156+
instr = (cmpSize == EA_4BYTE) ? INS_feq_s : INS_feq_d;
3157+
break;
3158+
default:
31883159
unreached();
3189-
}
31903160
}
3161+
emit->emitIns_R_R_R(instr, cmpSize, targetReg, op1->GetRegNum(), op2->GetRegNum());
3162+
if (isUnordered)
3163+
emit->emitIns_R_R_I(INS_xori, EA_8BYTE, targetReg, targetReg, 1);
31913164
}
31923165
else
31933166
{

src/coreclr/jit/lowerriscv64.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,10 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue)
138138
GenTree* cmpOp1;
139139
GenTree* cmpOp2;
140140

141+
assert(!op->OperIsCompare() || op->OperIsCmpCompare()); // We do not expect any other relops on RISCV64
142+
141143
if (op->OperIsCompare() && !varTypeIsFloating(op->gtGetOp1()))
142144
{
143-
// We do not expect any other relops on RISCV64
144-
assert(op->OperIs(GT_EQ, GT_NE, GT_LT, GT_LE, GT_GE, GT_GT));
145-
146145
cond = GenCondition::FromRelop(op);
147146

148147
cmpOp1 = op->gtGetOp1();
@@ -153,7 +152,16 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue)
153152
}
154153
else
155154
{
156-
cond = GenCondition(GenCondition::NE);
155+
GenCondition::Code code = GenCondition::NE;
156+
if (op->OperIsCompare() && varTypeIsFloating(op->gtGetOp1()) && (op->gtFlags & GTF_RELOP_NAN_UN) != 0)
157+
{
158+
// Unordered floating-point comparisons are achieved by neg'ing the ordered counterparts. Avoid that by
159+
// reversing both the FP comparison and the zero-comparison fused with the branch.
160+
op->ChangeOper(GenTree::ReverseRelop(op->OperGet()));
161+
op->gtFlags &= ~GTF_RELOP_NAN_UN;
162+
code = GenCondition::EQ;
163+
}
164+
cond = GenCondition(code);
157165

158166
cmpOp1 = op;
159167
cmpOp2 = comp->gtNewZeroConNode(cmpOp1->TypeGet());

0 commit comments

Comments
 (0)