diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp index 761b57f47d5d..8d0912a017b5 100644 --- a/src/jit/lower.cpp +++ b/src/jit/lower.cpp @@ -2606,33 +2606,47 @@ GenTree* Lowering::LowerCompare(GenTree* cmp) { GenTree* op1 = cmp->gtGetOp1(); GenTree* op2 = cmp->gtGetOp2(); - LIR::Use cmpUse; - if (op1->OperIs(GT_AND, GT_OR, GT_XOR, GT_ADD, GT_SUB, GT_NEG) && op2->IsIntegralConst(0) && - (op1->gtNext == op2) && (op2->gtNext == cmp) && BlockRange().TryGetUse(cmp, &cmpUse)) + if (op2->IsIntegralConst(0) && op1->OperIs(GT_AND, GT_OR, GT_XOR, GT_ADD, GT_SUB, GT_NEG) && + (op1->gtNext == op2) && (op2->gtNext == cmp)) { - genTreeOps condition = cmp->OperGet(); - GenTree* next = cmp->gtNext; - GenTreeCC* cc; + op1->gtFlags |= GTF_SET_FLAGS; + op1->SetUnusedValue(); - if (cmpUse.User()->OperIs(GT_JTRUE)) + BlockRange().Remove(op2); + + GenTree* next = cmp->gtNext; + GenTree* cc; + genTreeOps ccOp; + LIR::Use cmpUse; + + // Fast check for the common case - relop used by a JTRUE that immediately follows it. + if ((next != nullptr) && next->OperIs(GT_JTRUE) && (next->gtGetOp1() == cmp)) { - cmpUse.User()->ChangeOper(GT_JCC); - cc = cmpUse.User()->AsCC(); + cc = next; + ccOp = GT_JCC; + next = nullptr; BlockRange().Remove(cmp); } - else + else if (BlockRange().TryGetUse(cmp, &cmpUse) && cmpUse.User()->OperIs(GT_JTRUE)) { - cmp->ChangeOper(GT_SETCC); - cc = cmp->AsCC(); + cc = cmpUse.User(); + ccOp = GT_JCC; + next = nullptr; + BlockRange().Remove(cmp); + } + else // The relop is not used by a JTRUE or it is not used at all. + { + // Transform the relop node it into a SETCC. If it's not used we could remove + // it completely but that means doing more work to handle a rare case. + cc = cmp; + ccOp = GT_SETCC; } - cc->gtCondition = condition; - cc->gtFlags |= GTF_USE_FLAGS; - op1->gtFlags |= GTF_SET_FLAGS; - op1->SetUnusedValue(); - - BlockRange().Remove(op2); + genTreeOps condition = cmp->OperGet(); + cc->ChangeOper(ccOp); + cc->AsCC()->gtCondition = condition; + cc->gtFlags |= GTF_USE_FLAGS | (cmp->gtFlags & GTF_UNSIGNED); return next; }