[llvm] a917fb8 - [LVI] Simplify and generalize handling of clamp patterns
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 6 01:42:51 PST 2021
Author: Nikita Popov
Date: 2021-03-06T10:42:41+01:00
New Revision: a917fb89dc2818dc329f099e6912e28967961cc9
URL: https://github.com/llvm/llvm-project/commit/a917fb89dc2818dc329f099e6912e28967961cc9
DIFF: https://github.com/llvm/llvm-project/commit/a917fb89dc2818dc329f099e6912e28967961cc9.diff
LOG: [LVI] Simplify and generalize handling of clamp patterns
Instead of handling a number of special cases for selects, handle
this generally when inferring ranges from conditions. We already
infer ranges from `x + C pred C2` to `x`, so doing the same for
`x pred C2` to `x + C` is straightforward.
Added:
Modified:
llvm/lib/Analysis/LazyValueInfo.cpp
llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
Removed:
################################################################################
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<ValueLatticeElement> 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<ICmpInst>(Cond)) {
- ICmpInst::Predicate Pred = ICI->getPredicate();
- Value *A = ICI->getOperand(0);
- if (ConstantInt *CIBase = dyn_cast<ConstantInt>(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
;
More information about the llvm-commits
mailing list