@@ -181,6 +181,9 @@ GenTree* Lowering::LowerNode(GenTree* node)
181181 case GT_JTRUE:
182182 return LowerJTrue (node->AsOp ());
183183
184+ case GT_JCC:
185+ return LowerJCC (node->AsCC ());
186+
184187 case GT_SELCC:
185188 return LowerSelCC (node->AsOpCC ());
186189
@@ -3358,8 +3361,8 @@ class IfConversion
33583361
33593362 GenTreeOpCC* TryIfConversion (GenTreeOp* relop, GenTree* jtrue)
33603363 {
3361- assert (relop->OperIsCompare ());
3362- assert (jtrue->OperIs (GT_JTRUE));
3364+ assert (relop->OperIsCompare () || (relop-> gtFlags & GTF_SET_FLAGS) );
3365+ assert (jtrue->OperIs (GT_JTRUE, GT_JCC ));
33633366
33643367 HammockKind kind = MakeHammock ();
33653368
@@ -3372,18 +3375,28 @@ class IfConversion
33723375 return nullptr ;
33733376 }
33743377
3375- GenCondition condition = GenCondition::FromRelop (relop);
3376- condition = GenCondition::Reverse (condition);
3378+ GenCondition condition;
3379+
3380+ if (relop->OperIsCompare ())
3381+ {
3382+ condition = GenCondition::FromRelop (relop);
3383+ relop->ChangeOper (GenCondition::LowerRelopOper (relop->OperGet ()));
3384+ relop->gtType = TYP_VOID;
3385+ relop->gtFlags |= GTF_SET_FLAGS;
3386+ }
3387+ else
3388+ {
3389+ condition = jtrue->AsCC ()->gtCondition ;
3390+ }
33773391
3378- relop->ChangeOper (GT_CMP);
3379- relop->gtType = TYP_VOID;
33803392 jtrue->ChangeOper (GT_SELCC);
3393+ jtrue->gtFlags |= GTF_USE_FLAGS;
33813394 GenTreeOpCC* selcc = jtrue->AsOpCC ();
33823395
33833396 GenTree* trueSrc = summary.CloneOpSrc (m_comp, selcc);
33843397 GenTree* falseSrc = summary.CloneOpAsLclVar (m_comp, selcc);
33853398
3386- selcc->gtCondition = condition;
3399+ selcc->gtCondition = GenCondition::Reverse ( condition) ;
33873400 selcc->gtConditionDef = relop;
33883401 selcc->gtType = falseSrc->TypeGet ();
33893402 selcc->gtOp1 = falseSrc;
@@ -3413,11 +3426,23 @@ class IfConversion
34133426 return nullptr ;
34143427 }
34153428
3416- GenCondition condition = GenCondition::FromRelop (relop);
3429+ GenCondition condition;
3430+
3431+ if (relop->OperIsCompare ())
3432+ {
3433+ condition = GenCondition::FromRelop (relop);
3434+
3435+ relop->ChangeOper (GenCondition::LowerRelopOper (relop->OperGet ()));
3436+ relop->gtType = TYP_VOID;
3437+ relop->gtFlags |= GTF_SET_FLAGS;
3438+ }
3439+ else
3440+ {
3441+ condition = jtrue->AsCC ()->gtCondition ;
3442+ }
34173443
3418- relop->ChangeOper (GT_CMP);
3419- relop->gtType = TYP_VOID;
34203444 jtrue->ChangeOper (GT_SELCC);
3445+ jtrue->gtFlags |= GTF_USE_FLAGS;
34213446 GenTreeOpCC* selcc = jtrue->AsOpCC ();
34223447
34233448 falseSummary.CloneCopies (m_comp, selcc);
@@ -3500,7 +3525,7 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue)
35003525
35013526#ifdef _TARGET_AMD64_
35023527 GenTreeOp* relop = jtrue->gtGetOp1 ()->AsOp ();
3503- if (!relop->OperIs (GT_TEST_EQ, GT_TEST_NE ))
3528+ // if (!relop->OperIs(GT_TEST_NE, GT_TEST_EQ ))
35043529 {
35053530 IfConversion ifConversion (comp, m_block);
35063531 GenTreeOpCC* selcc = ifConversion.TryIfConversion (relop, jtrue);
@@ -3513,14 +3538,14 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue)
35133538 {
35143539 // Prefer FGT and FGE to FLT and FLE, they generate a single CMOV.
35153540 std::swap (relop->gtOp1 , relop->gtOp2 );
3516- selcc->gtCondition . Swap ();
3541+ selcc->gtCondition = GenCondition:: Swap (selcc-> gtCondition );
35173542 }
35183543 else if (selcc->gtCondition .Is (GenCondition::FEQ))
35193544 {
35203545 // Prefer FNEU to FEQ, FEQ requires a branch for the unordered case
35213546 // but FNEU can be implemented with 2 CMOVs.
35223547 std::swap (selcc->gtOp1 , selcc->gtOp2 );
3523- selcc->gtCondition . Reverse ();
3548+ selcc->gtCondition = GenCondition:: Reverse (selcc-> gtCondition );
35243549 }
35253550
35263551 // Floating point CMP has different containment rules
@@ -3540,6 +3565,26 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue)
35403565 return nullptr ;
35413566}
35423567
3568+ GenTree* Lowering::LowerJCC (GenTreeCC* jcc)
3569+ {
3570+ #ifdef _TARGET_AMD64_
3571+ GenTree* relop = jcc->gtPrev ;
3572+ if ((relop->gtFlags & GTF_SET_FLAGS) != 0 )
3573+ {
3574+ IfConversion ifConversion (comp, m_block);
3575+ GenTreeOpCC* selcc = ifConversion.TryIfConversion (relop->AsOp (), jcc);
3576+
3577+ if (selcc != nullptr )
3578+ {
3579+ return selcc;
3580+ }
3581+ }
3582+ #endif
3583+
3584+ assert (jcc->gtNext == nullptr );
3585+ return nullptr ;
3586+ }
3587+
35433588// Lower "jmp <method>" tail call to insert PInvoke method epilog if required.
35443589void Lowering::LowerJmpMethod (GenTree* jmp)
35453590{
@@ -6153,6 +6198,7 @@ void Lowering::ContainCheckNode(GenTree* node)
61536198 case GT_TEST_EQ:
61546199 case GT_TEST_NE:
61556200 case GT_CMP:
6201+ case GT_TEST:
61566202 case GT_JCMP:
61576203 ContainCheckCompare (node->AsOp ());
61586204 break ;
0 commit comments