@@ -8393,8 +8393,7 @@ bool llvm::matchSimpleRecurrence(const BinaryOperator *I, PHINode *&P,
8393
8393
8394
8394
// / Return true if "icmp Pred LHS RHS" is always true.
8395
8395
static bool isTruePredicate (CmpInst::Predicate Pred, const Value *LHS,
8396
- const Value *RHS, const DataLayout &DL,
8397
- unsigned Depth) {
8396
+ const Value *RHS) {
8398
8397
if (ICmpInst::isTrueWhenEqual (Pred) && LHS == RHS)
8399
8398
return true ;
8400
8399
@@ -8406,8 +8405,26 @@ static bool isTruePredicate(CmpInst::Predicate Pred, const Value *LHS,
8406
8405
const APInt *C;
8407
8406
8408
8407
// LHS s<= LHS +_{nsw} C if C >= 0
8409
- if (match (RHS, m_NSWAdd (m_Specific (LHS), m_APInt (C))))
8408
+ // LHS s<= LHS | C if C >= 0
8409
+ if (match (RHS, m_NSWAdd (m_Specific (LHS), m_APInt (C))) ||
8410
+ match (RHS, m_Or (m_Specific (LHS), m_APInt (C))))
8410
8411
return !C->isNegative ();
8412
+
8413
+ // LHS s<= smax(LHS, V) for any V
8414
+ if (match (RHS, m_c_SMax (m_Specific (LHS), m_Value ())))
8415
+ return true ;
8416
+
8417
+ // smin(RHS, V) s<= RHS for any V
8418
+ if (match (LHS, m_c_SMin (m_Specific (RHS), m_Value ())))
8419
+ return true ;
8420
+
8421
+ // Match A to (X +_{nsw} CA) and B to (X +_{nsw} CB)
8422
+ const Value *X;
8423
+ const APInt *CLHS, *CRHS;
8424
+ if (match (LHS, m_NSWAddLike (m_Value (X), m_APInt (CLHS))) &&
8425
+ match (RHS, m_NSWAddLike (m_Specific (X), m_APInt (CRHS))))
8426
+ return CLHS->sle (*CRHS);
8427
+
8411
8428
return false ;
8412
8429
}
8413
8430
@@ -8417,34 +8434,36 @@ static bool isTruePredicate(CmpInst::Predicate Pred, const Value *LHS,
8417
8434
cast<OverflowingBinaryOperator>(RHS)->hasNoUnsignedWrap ())
8418
8435
return true ;
8419
8436
8437
+ // LHS u<= LHS | V for any V
8438
+ if (match (RHS, m_c_Or (m_Specific (LHS), m_Value ())))
8439
+ return true ;
8440
+
8441
+ // LHS u<= umax(LHS, V) for any V
8442
+ if (match (RHS, m_c_UMax (m_Specific (LHS), m_Value ())))
8443
+ return true ;
8444
+
8420
8445
// RHS >> V u<= RHS for any V
8421
8446
if (match (LHS, m_LShr (m_Specific (RHS), m_Value ())))
8422
8447
return true ;
8423
8448
8424
- // Match A to (X +_{nuw} CA) and B to (X +_{nuw} CB)
8425
- auto MatchNUWAddsToSameValue = [&](const Value *A, const Value *B,
8426
- const Value *&X,
8427
- const APInt *&CA, const APInt *&CB) {
8428
- if (match (A, m_NUWAdd (m_Value (X), m_APInt (CA))) &&
8429
- match (B, m_NUWAdd (m_Specific (X), m_APInt (CB))))
8430
- return true ;
8449
+ // RHS u/ C_ugt_1 u<= RHS
8450
+ const APInt *C;
8451
+ if (match (LHS, m_UDiv (m_Specific (RHS), m_APInt (C))) && C->ugt (1 ))
8452
+ return true ;
8431
8453
8432
- // If X & C == 0 then (X | C) == X +_{nuw} C
8433
- if (match (A, m_Or (m_Value (X), m_APInt (CA))) &&
8434
- match (B, m_Or (m_Specific (X), m_APInt (CB)))) {
8435
- KnownBits Known (CA->getBitWidth ());
8436
- computeKnownBits (X, Known, DL, Depth + 1 , /* AC*/ nullptr ,
8437
- /* CxtI*/ nullptr , /* DT*/ nullptr );
8438
- if (CA->isSubsetOf (Known.Zero ) && CB->isSubsetOf (Known.Zero ))
8439
- return true ;
8440
- }
8454
+ // RHS & V u<= RHS for any V
8455
+ if (match (LHS, m_c_And (m_Specific (RHS), m_Value ())))
8456
+ return true ;
8441
8457
8442
- return false ;
8443
- };
8458
+ // umin(RHS, V) u<= RHS for any V
8459
+ if (match (LHS, m_c_UMin (m_Specific (RHS), m_Value ())))
8460
+ return true ;
8444
8461
8462
+ // Match A to (X +_{nuw} CA) and B to (X +_{nuw} CB)
8445
8463
const Value *X;
8446
8464
const APInt *CLHS, *CRHS;
8447
- if (MatchNUWAddsToSameValue (LHS, RHS, X, CLHS, CRHS))
8465
+ if (match (LHS, m_NUWAddLike (m_Value (X), m_APInt (CLHS))) &&
8466
+ match (RHS, m_NUWAddLike (m_Specific (X), m_APInt (CRHS))))
8448
8467
return CLHS->ule (*CRHS);
8449
8468
8450
8469
return false ;
@@ -8456,37 +8475,36 @@ static bool isTruePredicate(CmpInst::Predicate Pred, const Value *LHS,
8456
8475
// / ALHS ARHS" is true. Otherwise, return std::nullopt.
8457
8476
static std::optional<bool >
8458
8477
isImpliedCondOperands (CmpInst::Predicate Pred, const Value *ALHS,
8459
- const Value *ARHS, const Value *BLHS, const Value *BRHS,
8460
- const DataLayout &DL, unsigned Depth) {
8478
+ const Value *ARHS, const Value *BLHS, const Value *BRHS) {
8461
8479
switch (Pred) {
8462
8480
default :
8463
8481
return std::nullopt;
8464
8482
8465
8483
case CmpInst::ICMP_SLT:
8466
8484
case CmpInst::ICMP_SLE:
8467
- if (isTruePredicate (CmpInst::ICMP_SLE, BLHS, ALHS, DL, Depth ) &&
8468
- isTruePredicate (CmpInst::ICMP_SLE, ARHS, BRHS, DL, Depth ))
8485
+ if (isTruePredicate (CmpInst::ICMP_SLE, BLHS, ALHS) &&
8486
+ isTruePredicate (CmpInst::ICMP_SLE, ARHS, BRHS))
8469
8487
return true ;
8470
8488
return std::nullopt;
8471
8489
8472
8490
case CmpInst::ICMP_SGT:
8473
8491
case CmpInst::ICMP_SGE:
8474
- if (isTruePredicate (CmpInst::ICMP_SLE, ALHS, BLHS, DL, Depth ) &&
8475
- isTruePredicate (CmpInst::ICMP_SLE, BRHS, ARHS, DL, Depth ))
8492
+ if (isTruePredicate (CmpInst::ICMP_SLE, ALHS, BLHS) &&
8493
+ isTruePredicate (CmpInst::ICMP_SLE, BRHS, ARHS))
8476
8494
return true ;
8477
8495
return std::nullopt;
8478
8496
8479
8497
case CmpInst::ICMP_ULT:
8480
8498
case CmpInst::ICMP_ULE:
8481
- if (isTruePredicate (CmpInst::ICMP_ULE, BLHS, ALHS, DL, Depth ) &&
8482
- isTruePredicate (CmpInst::ICMP_ULE, ARHS, BRHS, DL, Depth ))
8499
+ if (isTruePredicate (CmpInst::ICMP_ULE, BLHS, ALHS) &&
8500
+ isTruePredicate (CmpInst::ICMP_ULE, ARHS, BRHS))
8483
8501
return true ;
8484
8502
return std::nullopt;
8485
8503
8486
8504
case CmpInst::ICMP_UGT:
8487
8505
case CmpInst::ICMP_UGE:
8488
- if (isTruePredicate (CmpInst::ICMP_ULE, ALHS, BLHS, DL, Depth ) &&
8489
- isTruePredicate (CmpInst::ICMP_ULE, BRHS, ARHS, DL, Depth ))
8506
+ if (isTruePredicate (CmpInst::ICMP_ULE, ALHS, BLHS) &&
8507
+ isTruePredicate (CmpInst::ICMP_ULE, BRHS, ARHS))
8490
8508
return true ;
8491
8509
return std::nullopt;
8492
8510
}
@@ -8530,7 +8548,7 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
8530
8548
CmpInst::Predicate RPred,
8531
8549
const Value *R0, const Value *R1,
8532
8550
const DataLayout &DL,
8533
- bool LHSIsTrue, unsigned Depth ) {
8551
+ bool LHSIsTrue) {
8534
8552
Value *L0 = LHS->getOperand (0 );
8535
8553
Value *L1 = LHS->getOperand (1 );
8536
8554
@@ -8577,7 +8595,7 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
8577
8595
return LPred == RPred;
8578
8596
8579
8597
if (LPred == RPred)
8580
- return isImpliedCondOperands (LPred, L0, L1, R0, R1, DL, Depth );
8598
+ return isImpliedCondOperands (LPred, L0, L1, R0, R1);
8581
8599
8582
8600
return std::nullopt;
8583
8601
}
@@ -8639,8 +8657,7 @@ llvm::isImpliedCondition(const Value *LHS, CmpInst::Predicate RHSPred,
8639
8657
// Both LHS and RHS are icmps.
8640
8658
const ICmpInst *LHSCmp = dyn_cast<ICmpInst>(LHS);
8641
8659
if (LHSCmp)
8642
- return isImpliedCondICmps (LHSCmp, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue,
8643
- Depth);
8660
+ return isImpliedCondICmps (LHSCmp, RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue);
8644
8661
8645
8662
// / The LHS should be an 'or', 'and', or a 'select' instruction. We expect
8646
8663
// / the RHS to be an icmp.
0 commit comments