Skip to content

Commit 7e79492

Browse files
committed
[ValueTracking] Infer NonEqual from dominating conditions/assumptions
1 parent f8202e1 commit 7e79492

File tree

2 files changed

+50
-17
lines changed

2 files changed

+50
-17
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,6 +3748,50 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2,
37483748
match(V2, m_PtrToIntSameSize(Q.DL, m_Value(B))))
37493749
return isKnownNonEqual(A, B, DemandedElts, Depth + 1, Q);
37503750

3751+
if (!Q.CxtI)
3752+
return false;
3753+
3754+
// Try to infer NonEqual based on information from dominating conditions.
3755+
if (Q.DC && Q.DT) {
3756+
for (BranchInst *BI : Q.DC->conditionsFor(V1)) {
3757+
Value *Cond = BI->getCondition();
3758+
BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
3759+
if (isImpliedCondition(Cond, ICmpInst::ICMP_NE, V1, V2, Q.DL,
3760+
/*LHSIsTrue=*/true, Depth)
3761+
.value_or(false) &&
3762+
Q.DT->dominates(Edge0, Q.CxtI->getParent()))
3763+
return true;
3764+
3765+
BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
3766+
if (isImpliedCondition(Cond, ICmpInst::ICMP_NE, V1, V2, Q.DL,
3767+
/*LHSIsTrue=*/false, Depth)
3768+
.value_or(false) &&
3769+
Q.DT->dominates(Edge1, Q.CxtI->getParent()))
3770+
return true;
3771+
}
3772+
}
3773+
3774+
if (!Q.AC)
3775+
return false;
3776+
3777+
// Try to infer NonEqual based on information from assumptions.
3778+
for (auto &AssumeVH : Q.AC->assumptionsFor(V1)) {
3779+
if (!AssumeVH)
3780+
continue;
3781+
CallInst *I = cast<CallInst>(AssumeVH);
3782+
3783+
assert(I->getFunction() == Q.CxtI->getFunction() &&
3784+
"Got assumption for the wrong function!");
3785+
assert(I->getIntrinsicID() == Intrinsic::assume &&
3786+
"must be an assume intrinsic");
3787+
3788+
if (isImpliedCondition(I->getArgOperand(0), ICmpInst::ICMP_NE, V1, V2, Q.DL,
3789+
/*LHSIsTrue=*/true, Depth)
3790+
.value_or(false) &&
3791+
isValidAssumeForContext(I, Q.CxtI, Q.DT))
3792+
return true;
3793+
}
3794+
37513795
return false;
37523796
}
37533797

@@ -10037,10 +10081,10 @@ void llvm::findValuesAffectedByCondition(
1003710081
Worklist.push_back(B);
1003810082
}
1003910083
} else if (match(V, m_ICmp(Pred, m_Value(A), m_Value(B)))) {
10040-
AddCmpOperands(A, B);
10041-
1004210084
bool HasRHSC = match(B, m_ConstantInt());
1004310085
if (ICmpInst::isEquality(Pred)) {
10086+
AddAffected(A);
10087+
AddAffected(B);
1004410088
if (HasRHSC) {
1004510089
Value *Y;
1004610090
// (X & C) or (X | C) or (X ^ C).
@@ -10055,6 +10099,7 @@ void llvm::findValuesAffectedByCondition(
1005510099
}
1005610100
}
1005710101
} else {
10102+
AddCmpOperands(A, B);
1005810103
if (HasRHSC) {
1005910104
// Handle (A + C1) u< C2, which is the canonical form of
1006010105
// A > C3 && A < C4.

llvm/test/Transforms/InstCombine/icmp-dom.ll

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -569,11 +569,7 @@ define i1 @test_nonequal_domcond1(i64 %x, i64 %y, i64 %z, i64 %w) {
569569
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 true, i1 [[COND2]]
570570
; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
571571
; CHECK: if.then:
572-
; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
573-
; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
574-
; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
575-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
576-
; CHECK-NEXT: ret i1 [[CMP]]
572+
; CHECK-NEXT: ret i1 false
577573
; CHECK: if.end:
578574
; CHECK-NEXT: ret i1 false
579575
;
@@ -602,11 +598,7 @@ define i1 @test_nonequal_domcond2(i64 %x, i64 %y, i64 %z, i64 %w) {
602598
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[COND1]], i1 [[COND2]], i1 false
603599
; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
604600
; CHECK: if.then:
605-
; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
606-
; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
607-
; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
608-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
609-
; CHECK-NEXT: ret i1 [[CMP]]
601+
; CHECK-NEXT: ret i1 false
610602
; CHECK: if.end:
611603
; CHECK-NEXT: ret i1 false
612604
;
@@ -634,11 +626,7 @@ define i1 @test_nonequal_assume(i64 %x, i64 %y, i64 %z, i64 %w) {
634626
; CHECK-NEXT: call void @llvm.assume(i1 [[COND1]])
635627
; CHECK-NEXT: [[COND2:%.*]] = icmp ne i64 [[W:%.*]], [[Z:%.*]]
636628
; CHECK-NEXT: call void @llvm.assume(i1 [[COND2]])
637-
; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[W]], [[Z]]
638-
; CHECK-NEXT: [[SUB2:%.*]] = sub i64 [[Y]], [[X]]
639-
; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SUB1]], i64 [[SUB2]])
640-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[UMIN]], 0
641-
; CHECK-NEXT: ret i1 [[CMP]]
629+
; CHECK-NEXT: ret i1 false
642630
;
643631
entry:
644632
%cond1 = icmp ne i64 %y, %x

0 commit comments

Comments
 (0)