From a05f6a70d0c94c03b945791d0ad54d06363b7746 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Tue, 17 Dec 2024 16:24:00 +0000 Subject: [PATCH] VT: teach isImpliedCondOperands about samesign isImpliedCondICmps() and its callers in ValueTracking can greatly benefit from being taught about samesign. As a first step, teach one caller, namely isImpliedCondOperands(). Very minimal changes are required for this, as CmpPredicate::getMatching() does most of the work. --- llvm/lib/Analysis/ValueTracking.cpp | 24 +++++++++---------- .../implied-condition-samesign.ll | 24 ++++--------------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 0eb43dd581acc..db244148a3b1e 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -9405,36 +9405,34 @@ static std::optional isImpliedCondCommonOperandWithCR( /// Return true if LHS implies RHS (expanded to its components as "R0 RPred R1") /// is true. Return false if LHS implies RHS is false. Otherwise, return /// std::nullopt if we can't infer anything. -static std::optional isImpliedCondICmps(const ICmpInst *LHS, - CmpInst::Predicate RPred, - const Value *R0, const Value *R1, - const DataLayout &DL, - bool LHSIsTrue) { +static std::optional +isImpliedCondICmps(const ICmpInst *LHS, CmpPredicate RPred, const Value *R0, + const Value *R1, const DataLayout &DL, bool LHSIsTrue) { Value *L0 = LHS->getOperand(0); Value *L1 = LHS->getOperand(1); // The rest of the logic assumes the LHS condition is true. If that's not the // case, invert the predicate to make it so. - CmpInst::Predicate LPred = - LHSIsTrue ? LHS->getPredicate() : LHS->getInversePredicate(); + CmpPredicate LPred = + LHSIsTrue ? LHS->getCmpPredicate() : LHS->getInverseCmpPredicate(); // We can have non-canonical operands, so try to normalize any common operand // to L0/R0. if (L0 == R1) { std::swap(R0, R1); - RPred = ICmpInst::getSwappedPredicate(RPred); + RPred = ICmpInst::getSwappedCmpPredicate(RPred); } if (R0 == L1) { std::swap(L0, L1); - LPred = ICmpInst::getSwappedPredicate(LPred); + LPred = ICmpInst::getSwappedCmpPredicate(LPred); } if (L1 == R1) { // If we have L0 == R0 and L1 == R1, then make L1/R1 the constants. if (L0 != R0 || match(L0, m_ImmConstant())) { std::swap(L0, L1); - LPred = ICmpInst::getSwappedPredicate(LPred); + LPred = ICmpInst::getSwappedCmpPredicate(LPred); std::swap(R0, R1); - RPred = ICmpInst::getSwappedPredicate(RPred); + RPred = ICmpInst::getSwappedCmpPredicate(RPred); } } @@ -9493,8 +9491,8 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, match(L0, m_c_Add(m_Specific(L1), m_Specific(R1)))) return CmpPredicate::getMatching(LPred, RPred).has_value(); - if (LPred == RPred) - return isImpliedCondOperands(LPred, L0, L1, R0, R1); + if (auto P = CmpPredicate::getMatching(LPred, RPred)) + return isImpliedCondOperands(*P, L0, L1, R0, R1); return std::nullopt; } diff --git a/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll b/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll index 0ea69c2cd4d47..3abe4c76aaab6 100644 --- a/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll +++ b/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll @@ -4,11 +4,7 @@ define i1 @incr_sle(i32 %i, i32 %len) { ; CHECK-LABEL: define i1 @incr_sle( ; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) { -; CHECK-NEXT: [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1 -; CHECK-NEXT: [[I_GT_LEN:%.*]] = icmp samesign ugt i32 [[I]], [[LEN]] -; CHECK-NEXT: [[I_INCR_SGT_LEN:%.*]] = icmp sgt i32 [[I_INCR]], [[LEN]] -; CHECK-NEXT: [[RES:%.*]] = icmp sle i1 [[I_INCR_SGT_LEN]], [[I_GT_LEN]] -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 true ; %i.incr = add nsw nuw i32 %i, 1 %i.gt.len = icmp samesign ugt i32 %i, %len @@ -36,11 +32,7 @@ define i1 @incr_sle_no_nsw_nuw(i32 %i, i32 %len) { define i1 @incr_sge(i32 %i, i32 %len) { ; CHECK-LABEL: define i1 @incr_sge( ; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) { -; CHECK-NEXT: [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1 -; CHECK-NEXT: [[I_LT_LEN:%.*]] = icmp samesign ult i32 [[I]], [[LEN]] -; CHECK-NEXT: [[I_INCR_SLT_LEN:%.*]] = icmp slt i32 [[I_INCR]], [[LEN]] -; CHECK-NEXT: [[RES:%.*]] = icmp sge i1 [[I_INCR_SLT_LEN]], [[I_LT_LEN]] -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 true ; %i.incr = add nsw nuw i32 %i, 1 %i.lt.len = icmp samesign ult i32 %i, %len @@ -68,11 +60,7 @@ define i1 @incr_sge_no_nsw_nuw(i32 %i, i32 %len) { define i1 @incr_ule(i32 %i, i32 %len) { ; CHECK-LABEL: define i1 @incr_ule( ; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) { -; CHECK-NEXT: [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1 -; CHECK-NEXT: [[I_GT_LEN:%.*]] = icmp samesign ugt i32 [[I]], [[LEN]] -; CHECK-NEXT: [[I_INCR_SGT_LEN:%.*]] = icmp sgt i32 [[I_INCR]], [[LEN]] -; CHECK-NEXT: [[RES:%.*]] = icmp ule i1 [[I_GT_LEN]], [[I_INCR_SGT_LEN]] -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 true ; %i.incr = add nsw nuw i32 %i, 1 %i.gt.len = icmp samesign ugt i32 %i, %len @@ -100,11 +88,7 @@ define i1 @incr_ule_no_nsw_nuw(i32 %i, i32 %len) { define i1 @incr_uge(i32 %i, i32 %len) { ; CHECK-LABEL: define i1 @incr_uge( ; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) { -; CHECK-NEXT: [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1 -; CHECK-NEXT: [[I_LT_LEN:%.*]] = icmp samesign ult i32 [[I]], [[LEN]] -; CHECK-NEXT: [[I_INCR_SLT_LEN:%.*]] = icmp slt i32 [[I_INCR]], [[LEN]] -; CHECK-NEXT: [[RES:%.*]] = icmp uge i1 [[I_LT_LEN]], [[I_INCR_SLT_LEN]] -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 true ; %i.incr = add nsw nuw i32 %i, 1 %i.lt.len = icmp samesign ult i32 %i, %len