forked from OSchip/llvm-project
[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 https://github.com/llvm/llvm-project/issues/51867.
This commit is contained in:
parent
b7bf96a258
commit
3ec7f46e99
|
@ -1132,14 +1132,16 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
|
|||
}
|
||||
|
||||
// If (X urem Modulus) >= C, then X >= C.
|
||||
// If trunc X >= C, then X >= C.
|
||||
// TODO: An upper bound could be computed as well.
|
||||
if (match(LHS, m_URem(m_Specific(Val), m_Value())) &&
|
||||
if (match(LHS, m_CombineOr(m_URem(m_Specific(Val), m_Value()),
|
||||
m_Trunc(m_Specific(Val)))) &&
|
||||
match(RHS, m_APInt(C))) {
|
||||
// Use the icmp region so we don't have to deal with different predicates.
|
||||
ConstantRange CR = ConstantRange::makeExactICmpRegion(EdgePred, *C);
|
||||
if (!CR.isEmptySet())
|
||||
return ValueLatticeElement::getRange(ConstantRange::getNonEmpty(
|
||||
CR.getUnsignedMin(), APInt(BitWidth, 0)));
|
||||
CR.getUnsignedMin().zextOrSelf(BitWidth), APInt(BitWidth, 0)));
|
||||
}
|
||||
|
||||
return ValueLatticeElement::getOverdefined();
|
||||
|
|
|
@ -1131,14 +1131,12 @@ define void @trunc_icmp_ule(i32 %x, i1* %p) {
|
|||
; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[T]], 5
|
||||
; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: [[C1:%.*]] = icmp uge i32 [[X]], 5
|
||||
; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1
|
||||
; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 5
|
||||
; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1
|
||||
; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 5
|
||||
; CHECK-NEXT: store i1 [[C3]], i1* [[P]], align 1
|
||||
; CHECK-NEXT: [[C4:%.*]] = icmp ult i32 [[X]], 5
|
||||
; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1
|
||||
; CHECK-NEXT: store i1 false, i1* [[P]], align 1
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 5
|
||||
|
@ -1184,14 +1182,12 @@ define void @trunc_icmp_eq(i32 %x, i1* %p) {
|
|||
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[T]], 5
|
||||
; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||
; CHECK: true:
|
||||
; CHECK-NEXT: [[C1:%.*]] = icmp uge i32 [[X]], 5
|
||||
; CHECK-NEXT: store i1 [[C1]], i1* [[P:%.*]], align 1
|
||||
; CHECK-NEXT: store i1 true, i1* [[P:%.*]], align 1
|
||||
; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 5
|
||||
; CHECK-NEXT: store i1 [[C2]], i1* [[P]], align 1
|
||||
; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 5
|
||||
; CHECK-NEXT: store i1 [[C3]], i1* [[P]], align 1
|
||||
; CHECK-NEXT: [[C4:%.*]] = icmp ult i32 [[X]], 5
|
||||
; CHECK-NEXT: store i1 [[C4]], i1* [[P]], align 1
|
||||
; CHECK-NEXT: store i1 false, i1* [[P]], align 1
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: false:
|
||||
; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 5
|
||||
|
|
Loading…
Reference in New Issue