Skip to content

Commit a917fb8

Browse files
committed
[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.
1 parent 906deaa commit a917fb8

File tree

2 files changed

+11
-50
lines changed

2 files changed

+11
-50
lines changed

llvm/lib/Analysis/LazyValueInfo.cpp

Lines changed: 7 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -875,48 +875,6 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueSelect(
875875
FalseVal = intersect(FalseVal,
876876
getValueFromCondition(SI->getFalseValue(), Cond, false));
877877

878-
// Handle clamp idioms such as:
879-
// %24 = constantrange<0, 17>
880-
// %39 = icmp eq i32 %24, 0
881-
// %40 = add i32 %24, -1
882-
// %siv.next = select i1 %39, i32 16, i32 %40
883-
// %siv.next = constantrange<0, 17> not <-1, 17>
884-
// In general, this can handle any clamp idiom which tests the edge
885-
// condition via an equality or inequality.
886-
if (auto *ICI = dyn_cast<ICmpInst>(Cond)) {
887-
ICmpInst::Predicate Pred = ICI->getPredicate();
888-
Value *A = ICI->getOperand(0);
889-
if (ConstantInt *CIBase = dyn_cast<ConstantInt>(ICI->getOperand(1))) {
890-
auto addConstants = [](ConstantInt *A, ConstantInt *B) {
891-
assert(A->getType() == B->getType());
892-
return ConstantInt::get(A->getType(), A->getValue() + B->getValue());
893-
};
894-
// See if either input is A + C2, subject to the constraint from the
895-
// condition that A != C when that input is used. We can assume that
896-
// that input doesn't include C + C2.
897-
ConstantInt *CIAdded;
898-
switch (Pred) {
899-
default: break;
900-
case ICmpInst::ICMP_EQ:
901-
if (match(SI->getFalseValue(), m_Add(m_Specific(A),
902-
m_ConstantInt(CIAdded)))) {
903-
auto ResNot = addConstants(CIBase, CIAdded);
904-
FalseVal = intersect(FalseVal,
905-
ValueLatticeElement::getNot(ResNot));
906-
}
907-
break;
908-
case ICmpInst::ICMP_NE:
909-
if (match(SI->getTrueValue(), m_Add(m_Specific(A),
910-
m_ConstantInt(CIAdded)))) {
911-
auto ResNot = addConstants(CIBase, CIAdded);
912-
TrueVal = intersect(TrueVal,
913-
ValueLatticeElement::getNot(ResNot));
914-
}
915-
break;
916-
};
917-
}
918-
}
919-
920878
ValueLatticeElement Result = TrueVal;
921879
Result.mergeIn(FalseVal);
922880
return Result;
@@ -1089,6 +1047,13 @@ static bool matchICmpOperand(APInt &Offset, Value *LHS, Value *Val,
10891047
return true;
10901048
}
10911049

1050+
// Handle the symmetric case. This appears in saturation patterns like
1051+
// (x == 16) ? 16 : (x + 1).
1052+
if (match(Val, m_Add(m_Specific(LHS), m_APInt(C)))) {
1053+
Offset = -*C;
1054+
return true;
1055+
}
1056+
10921057
// If (x | y) < C, then (x < C) && (y < C).
10931058
if (match(LHS, m_c_Or(m_Specific(Val), m_Value())) &&
10941059
(Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE))

llvm/test/Transforms/CorrelatedValuePropagation/basic.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -587,8 +587,7 @@ define i1 @clamp_low3(i32 %a) {
587587
; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sgt i32 [[A]], 5
588588
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
589589
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
590-
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 4
591-
; CHECK-NEXT: ret i1 [[RES]]
590+
; CHECK-NEXT: ret i1 false
592591
; CHECK: out:
593592
; CHECK-NEXT: ret i1 false
594593
;
@@ -615,8 +614,7 @@ define i1 @clamp_low4(i32 %a) {
615614
; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sle i32 [[A]], 5
616615
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
617616
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
618-
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 4
619-
; CHECK-NEXT: ret i1 [[RES]]
617+
; CHECK-NEXT: ret i1 false
620618
; CHECK: out:
621619
; CHECK-NEXT: ret i1 false
622620
;
@@ -697,8 +695,7 @@ define i1 @clamp_high3(i32 %a) {
697695
; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5
698696
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
699697
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
700-
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 6
701-
; CHECK-NEXT: ret i1 [[RES]]
698+
; CHECK-NEXT: ret i1 false
702699
; CHECK: out:
703700
; CHECK-NEXT: ret i1 false
704701
;
@@ -725,8 +722,7 @@ define i1 @clamp_high4(i32 %a) {
725722
; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 5
726723
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
727724
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
728-
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 6
729-
; CHECK-NEXT: ret i1 [[RES]]
725+
; CHECK-NEXT: ret i1 false
730726
; CHECK: out:
731727
; CHECK-NEXT: ret i1 false
732728
;

0 commit comments

Comments
 (0)