@@ -1439,8 +1439,12 @@ bool IndVarSimplify::canonicalizeExitCondition(Loop *L) {
1439
1439
// For the range reasoning, avoid computing SCEVs in the loop to avoid
1440
1440
// poisoning cache with sub-optimal results. For the must-execute case,
1441
1441
// this is a neccessary precondition for correctness.
1442
- if (!L->isLoopInvariant (RHS))
1443
- continue ;
1442
+ if (!L->isLoopInvariant (RHS)) {
1443
+ if (!L->isLoopInvariant (LHS))
1444
+ continue ;
1445
+ // Same logic applies for the inverse case
1446
+ std::swap (LHS, RHS);
1447
+ }
1444
1448
1445
1449
// Match (icmp signed-cond zext, RHS)
1446
1450
Value *LHSOp = nullptr ;
@@ -1475,11 +1479,19 @@ bool IndVarSimplify::canonicalizeExitCondition(Loop *L) {
1475
1479
if (!ICmp || !ICmp->hasOneUse () || !ICmp->isUnsigned ())
1476
1480
continue ;
1477
1481
1482
+ bool Swapped = false ;
1478
1483
auto *LHS = ICmp->getOperand (0 );
1479
1484
auto *RHS = ICmp->getOperand (1 );
1480
- if (L->isLoopInvariant (LHS) || ! L->isLoopInvariant (RHS))
1485
+ if (L->isLoopInvariant (LHS) == L->isLoopInvariant (RHS))
1481
1486
// Nothing to rotate
1482
1487
continue ;
1488
+ if (L->isLoopInvariant (LHS)) {
1489
+ // Same logic applies for the inverse case until we actually pick
1490
+ // which operand of the compare to update.
1491
+ Swapped = true ;
1492
+ std::swap (LHS, RHS);
1493
+ }
1494
+ assert (!L->isLoopInvariant (LHS) && L->isLoopInvariant (RHS));
1483
1495
1484
1496
if (!LHS->hasOneUse ())
1485
1497
// Can't rotate without increasing instruction count
@@ -1501,8 +1513,8 @@ bool IndVarSimplify::canonicalizeExitCondition(Loop *L) {
1501
1513
auto *NewRHS =
1502
1514
CastInst::Create (Instruction::Trunc, RHS, LHSOp->getType (), " " ,
1503
1515
L->getLoopPreheader ()->getTerminator ());
1504
- ICmp->setOperand (0 , LHSOp);
1505
- ICmp->setOperand (1 , NewRHS);
1516
+ ICmp->setOperand (Swapped ? 1 : 0 , LHSOp);
1517
+ ICmp->setOperand (Swapped ? 0 : 1 , NewRHS);
1506
1518
if (LHS->use_empty ())
1507
1519
DeadInsts.push_back (LHS);
1508
1520
};
0 commit comments