diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index b74ed047cc9a..8d807c3331ea 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -875,48 +875,6 @@ Optional LazyValueInfoImpl::solveBlockValueSelect( FalseVal = intersect(FalseVal, getValueFromCondition(SI->getFalseValue(), Cond, false)); - // Handle clamp idioms such as: - // %24 = constantrange<0, 17> - // %39 = icmp eq i32 %24, 0 - // %40 = add i32 %24, -1 - // %siv.next = select i1 %39, i32 16, i32 %40 - // %siv.next = constantrange<0, 17> not <-1, 17> - // In general, this can handle any clamp idiom which tests the edge - // condition via an equality or inequality. - if (auto *ICI = dyn_cast(Cond)) { - ICmpInst::Predicate Pred = ICI->getPredicate(); - Value *A = ICI->getOperand(0); - if (ConstantInt *CIBase = dyn_cast(ICI->getOperand(1))) { - auto addConstants = [](ConstantInt *A, ConstantInt *B) { - assert(A->getType() == B->getType()); - return ConstantInt::get(A->getType(), A->getValue() + B->getValue()); - }; - // See if either input is A + C2, subject to the constraint from the - // condition that A != C when that input is used. We can assume that - // that input doesn't include C + C2. - ConstantInt *CIAdded; - switch (Pred) { - default: break; - case ICmpInst::ICMP_EQ: - if (match(SI->getFalseValue(), m_Add(m_Specific(A), - m_ConstantInt(CIAdded)))) { - auto ResNot = addConstants(CIBase, CIAdded); - FalseVal = intersect(FalseVal, - ValueLatticeElement::getNot(ResNot)); - } - break; - case ICmpInst::ICMP_NE: - if (match(SI->getTrueValue(), m_Add(m_Specific(A), - m_ConstantInt(CIAdded)))) { - auto ResNot = addConstants(CIBase, CIAdded); - TrueVal = intersect(TrueVal, - ValueLatticeElement::getNot(ResNot)); - } - break; - }; - } - } - ValueLatticeElement Result = TrueVal; Result.mergeIn(FalseVal); return Result; @@ -1089,6 +1047,13 @@ static bool matchICmpOperand(APInt &Offset, Value *LHS, Value *Val, return true; } + // Handle the symmetric case. This appears in saturation patterns like + // (x == 16) ? 16 : (x + 1). + if (match(Val, m_Add(m_Specific(LHS), m_APInt(C)))) { + Offset = -*C; + return true; + } + // If (x | y) < C, then (x < C) && (y < C). if (match(LHS, m_c_Or(m_Specific(Val), m_Value())) && (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE)) diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll index 4713752f6979..9748037e8af7 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll @@ -587,8 +587,7 @@ define i1 @clamp_low3(i32 %a) { ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sgt i32 [[A]], 5 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 4 -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 false ; CHECK: out: ; CHECK-NEXT: ret i1 false ; @@ -615,8 +614,7 @@ define i1 @clamp_low4(i32 %a) { ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sle i32 [[A]], 5 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 4 -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 false ; CHECK: out: ; CHECK-NEXT: ret i1 false ; @@ -697,8 +695,7 @@ define i1 @clamp_high3(i32 %a) { ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5 -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 6 -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 false ; CHECK: out: ; CHECK-NEXT: ret i1 false ; @@ -725,8 +722,7 @@ define i1 @clamp_high4(i32 %a) { ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 5 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 6 -; CHECK-NEXT: ret i1 [[RES]] +; CHECK-NEXT: ret i1 false ; CHECK: out: ; CHECK-NEXT: ret i1 false ;