diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index db244148a3b1e..9a61b36efa51d 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -9388,17 +9388,32 @@ isImpliedCondMatchingOperands(CmpInst::Predicate LPred, /// Return true if "icmp LPred X, LCR" implies "icmp RPred X, RCR" is true. /// Return false if "icmp LPred X, LCR" implies "icmp RPred X, RCR" is false. /// Otherwise, return std::nullopt if we can't infer anything. -static std::optional isImpliedCondCommonOperandWithCR( - CmpInst::Predicate LPred, const ConstantRange &LCR, - CmpInst::Predicate RPred, const ConstantRange &RCR) { - ConstantRange DomCR = ConstantRange::makeAllowedICmpRegion(LPred, LCR); - // If all true values for lhs and true for rhs, lhs implies rhs - if (DomCR.icmp(RPred, RCR)) - return true; +static std::optional +isImpliedCondCommonOperandWithCR(CmpPredicate LPred, const ConstantRange &LCR, + CmpPredicate RPred, const ConstantRange &RCR) { + auto CRImpliesPred = [&](ConstantRange CR, + CmpInst::Predicate Pred) -> std::optional { + // If all true values for lhs and true for rhs, lhs implies rhs + if (CR.icmp(Pred, RCR)) + return true; - // If there is no overlap, lhs implies not rhs - if (DomCR.icmp(CmpInst::getInversePredicate(RPred), RCR)) - return false; + // If there is no overlap, lhs implies not rhs + if (CR.icmp(CmpInst::getInversePredicate(Pred), RCR)) + return false; + + return std::nullopt; + }; + if (auto Res = CRImpliesPred(ConstantRange::makeAllowedICmpRegion(LPred, LCR), + RPred)) + return Res; + if (LPred.hasSameSign() ^ RPred.hasSameSign()) { + LPred = LPred.hasSameSign() ? ICmpInst::getFlippedSignednessPredicate(LPred) + : static_cast(LPred); + RPred = RPred.hasSameSign() ? ICmpInst::getFlippedSignednessPredicate(RPred) + : static_cast(RPred); + return CRImpliesPred(ConstantRange::makeAllowedICmpRegion(LPred, LCR), + RPred); + } return std::nullopt; } diff --git a/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll b/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll index 3abe4c76aaab6..042155ae2bb79 100644 --- a/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll +++ b/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll @@ -160,9 +160,7 @@ define i32 @gt_implies_sge_dominating_cr(i32 %a, i32 %len) { ; CHECK-NEXT: [[A_GT_20:%.*]] = icmp samesign ugt i32 [[A]], 20 ; CHECK-NEXT: br i1 [[A_GT_20]], label %[[TAKEN:.*]], label %[[END:.*]] ; CHECK: [[TAKEN]]: -; CHECK-NEXT: [[A_SGE_10:%.*]] = icmp sge i32 [[A]], 10 -; CHECK-NEXT: [[RES:%.*]] = select i1 [[A_SGE_10]], i32 30, i32 0 -; CHECK-NEXT: ret i32 [[RES]] +; CHECK-NEXT: ret i32 30 ; CHECK: [[END]]: ; CHECK-NEXT: ret i32 -1 ; @@ -186,9 +184,7 @@ define i32 @sgt_implies_ge_dominating_cr(i32 %a, i32 %len) { ; CHECK-NEXT: [[A_SGT_MINUS_10:%.*]] = icmp sgt i32 [[A]], -10 ; CHECK-NEXT: br i1 [[A_SGT_MINUS_10]], label %[[TAKEN:.*]], label %[[END:.*]] ; CHECK: [[TAKEN]]: -; CHECK-NEXT: [[A_GE_MINUS_20:%.*]] = icmp samesign uge i32 [[A]], -20 -; CHECK-NEXT: [[RES:%.*]] = select i1 [[A_GE_MINUS_20]], i32 30, i32 0 -; CHECK-NEXT: ret i32 [[RES]] +; CHECK-NEXT: ret i32 30 ; CHECK: [[END]]: ; CHECK-NEXT: ret i32 -1 ;