Skip to content

Commit 3ec7f46

Browse files
committed
[LVI] Handle implication from icmp of trunc (PR51867)
Similar to the existing urem code, if we have (trunc X) >= C, then also X >= C. Proof: https://alive2.llvm.org/ce/z/RF4YR2 Fixes llvm/llvm-project#51867.
1 parent b7bf96a commit 3ec7f46

File tree

2 files changed

+8
-10
lines changed

2 files changed

+8
-10
lines changed

llvm/lib/Analysis/LazyValueInfo.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,14 +1132,16 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
11321132
}
11331133

11341134
// If (X urem Modulus) >= C, then X >= C.
1135+
// If trunc X >= C, then X >= C.
11351136
// TODO: An upper bound could be computed as well.
1136-
if (match(LHS, m_URem(m_Specific(Val), m_Value())) &&
1137+
if (match(LHS, m_CombineOr(m_URem(m_Specific(Val), m_Value()),
1138+
m_Trunc(m_Specific(Val)))) &&
11371139
match(RHS, m_APInt(C))) {
11381140
// Use the icmp region so we don't have to deal with different predicates.
11391141
ConstantRange CR = ConstantRange::makeExactICmpRegion(EdgePred, *C);
11401142
if (!CR.isEmptySet())
11411143
return ValueLatticeElement::getRange(ConstantRange::getNonEmpty(
1142-
CR.getUnsignedMin(), APInt(BitWidth, 0)));
1144+
CR.getUnsignedMin().zextOrSelf(BitWidth), APInt(BitWidth, 0)));
11431145
}
11441146

11451147
return ValueLatticeElement::getOverdefined();

llvm/test/Transforms/CorrelatedValuePropagation/basic.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,14 +1131,12 @@ define void @trunc_icmp_ule(i32 %x, i1* %p) {
11311131
; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[T]], 5
11321132
; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
11331133
; CHECK: true:
1134-
; CHECK-NEXT: [[C1:%.*]] = icmp uge i32 [[X]], 5
1135-
; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1
1134+
; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1
11361135
; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 5
11371136
; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1
11381137
; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 5
11391138
; CHECK-NEXT: store i1 [[C3]], i1* [[P]], align 1
1140-
; CHECK-NEXT: [[C4:%.*]] = icmp ult i32 [[X]], 5
1141-
; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1
1139+
; CHECK-NEXT: store i1 false, i1* [[P]], align 1
11421140
; CHECK-NEXT: ret void
11431141
; CHECK: false:
11441142
; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 5
@@ -1184,14 +1182,12 @@ define void @trunc_icmp_eq(i32 %x, i1* %p) {
11841182
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[T]], 5
11851183
; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
11861184
; CHECK: true:
1187-
; CHECK-NEXT: [[C1:%.*]] = icmp uge i32 [[X]], 5
1188-
; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1
1185+
; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1
11891186
; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 5
11901187
; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1
11911188
; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 5
11921189
; CHECK-NEXT: store i1 [[C3]], i1* [[P]], align 1
1193-
; CHECK-NEXT: [[C4:%.*]] = icmp ult i32 [[X]], 5
1194-
; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1
1190+
; CHECK-NEXT: store i1 false, i1* [[P]], align 1
11951191
; CHECK-NEXT: ret void
11961192
; CHECK: false:
11971193
; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 5

0 commit comments

Comments
 (0)