Skip to content

Commit 8f07629

Browse files
committed
Add recursive decomposition reasoning to isKnownNonEqual
The basic idea is that by looking through operand instructions which don't change the equality result that we can push the existing known bits comparison down past instructions which would obscure them. We have analogous handling in InstSimplify for most - though weirdly not all - of these cases starting from an icmp root. It's a bit unfortunate to duplicate logic, but since my actual goal is to extend BasicAA, the icmp logic doesn't help. (And just makes it hard to test here.) The BasicAA change will be posted separately for review. Differential Revision: https://reviews.llvm.org/D92698
1 parent 109e70d commit 8f07629

File tree

2 files changed

+42
-18
lines changed

2 files changed

+42
-18
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -350,13 +350,14 @@ bool llvm::isKnownNegative(const Value *V, const DataLayout &DL, unsigned Depth,
350350
return Known.isNegative();
351351
}
352352

353-
static bool isKnownNonEqual(const Value *V1, const Value *V2, const Query &Q);
353+
static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
354+
const Query &Q);
354355

355356
bool llvm::isKnownNonEqual(const Value *V1, const Value *V2,
356357
const DataLayout &DL, AssumptionCache *AC,
357358
const Instruction *CxtI, const DominatorTree *DT,
358359
bool UseInstrInfo) {
359-
return ::isKnownNonEqual(V1, V2,
360+
return ::isKnownNonEqual(V1, V2, 0,
360361
Query(DL, AC, safeCxtI(V1, safeCxtI(V2, CxtI)), DT,
361362
UseInstrInfo, /*ORE=*/nullptr));
362363
}
@@ -2486,7 +2487,8 @@ bool isKnownNonZero(const Value* V, unsigned Depth, const Query& Q) {
24862487
}
24872488

24882489
/// Return true if V2 == V1 + X, where X is known non-zero.
2489-
static bool isAddOfNonZero(const Value *V1, const Value *V2, const Query &Q) {
2490+
static bool isAddOfNonZero(const Value *V1, const Value *V2, unsigned Depth,
2491+
const Query &Q) {
24902492
const BinaryOperator *BO = dyn_cast<BinaryOperator>(V1);
24912493
if (!BO || BO->getOpcode() != Instruction::Add)
24922494
return false;
@@ -2497,24 +2499,54 @@ static bool isAddOfNonZero(const Value *V1, const Value *V2, const Query &Q) {
24972499
Op = BO->getOperand(0);
24982500
else
24992501
return false;
2500-
return isKnownNonZero(Op, 0, Q);
2502+
return isKnownNonZero(Op, Depth + 1, Q);
25012503
}
25022504

25032505
/// Return true if it is known that V1 != V2.
2504-
static bool isKnownNonEqual(const Value *V1, const Value *V2, const Query &Q) {
2506+
static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
2507+
const Query &Q) {
25052508
if (V1 == V2)
25062509
return false;
25072510
if (V1->getType() != V2->getType())
25082511
// We can't look through casts yet.
25092512
return false;
2510-
if (isAddOfNonZero(V1, V2, Q) || isAddOfNonZero(V2, V1, Q))
2513+
2514+
if (Depth >= MaxAnalysisRecursionDepth)
2515+
return false;
2516+
2517+
// See if we can recurse through (exactly one of) our operands.
2518+
auto *O1 = dyn_cast<Operator>(V1);
2519+
auto *O2 = dyn_cast<Operator>(V2);
2520+
if (O1 && O2 && O1->getOpcode() == O2->getOpcode()) {
2521+
switch (O1->getOpcode()) {
2522+
default: break;
2523+
case Instruction::Add:
2524+
case Instruction::Sub:
2525+
// Assume operand order has been canonicalized
2526+
if (O1->getOperand(0) == O2->getOperand(0))
2527+
return isKnownNonEqual(O1->getOperand(1), O2->getOperand(1),
2528+
Depth + 1, Q);
2529+
if (O1->getOperand(1) == O2->getOperand(1))
2530+
return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
2531+
Depth + 1, Q);
2532+
break;
2533+
case Instruction::SExt:
2534+
case Instruction::ZExt:
2535+
if (O1->getOperand(0)->getType() == O2->getOperand(0)->getType())
2536+
return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
2537+
Depth + 1, Q);
2538+
break;
2539+
};
2540+
}
2541+
2542+
if (isAddOfNonZero(V1, V2, Depth, Q) || isAddOfNonZero(V2, V1, Depth, Q))
25112543
return true;
25122544

25132545
if (V1->getType()->isIntOrIntVectorTy()) {
25142546
// Are any known bits in V1 contradictory to known bits in V2? If V1
25152547
// has a known zero where V2 has a known one, they must not be equal.
2516-
KnownBits Known1 = computeKnownBits(V1, 0, Q);
2517-
KnownBits Known2 = computeKnownBits(V2, 0, Q);
2548+
KnownBits Known1 = computeKnownBits(V1, Depth, Q);
2549+
KnownBits Known2 = computeKnownBits(V2, Depth, Q);
25182550

25192551
if (Known1.Zero.intersects(Known2.One) ||
25202552
Known2.Zero.intersects(Known1.One))

llvm/test/Analysis/ValueTracking/known-non-equal.ll

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,7 @@ define i1 @add2(i8 %B, i8 %C) {
108108

109109
define i1 @sub1(i8 %B, i8 %C) {
110110
; CHECK-LABEL: @sub1(
111-
; CHECK-NEXT: [[A:%.*]] = add i8 [[B:%.*]], 1
112-
; CHECK-NEXT: [[A_OP:%.*]] = sub i8 [[A]], [[C:%.*]]
113-
; CHECK-NEXT: [[B_OP:%.*]] = sub i8 [[B]], [[C]]
114-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A_OP]], [[B_OP]]
115-
; CHECK-NEXT: ret i1 [[CMP]]
111+
; CHECK-NEXT: ret i1 false
116112
;
117113
%A = add i8 %B, 1
118114
%A.op = sub i8 %A, %C
@@ -124,11 +120,7 @@ define i1 @sub1(i8 %B, i8 %C) {
124120

125121
define i1 @sub2(i8 %B, i8 %C) {
126122
; CHECK-LABEL: @sub2(
127-
; CHECK-NEXT: [[A:%.*]] = add i8 [[B:%.*]], 1
128-
; CHECK-NEXT: [[A_OP:%.*]] = sub i8 [[C:%.*]], [[A]]
129-
; CHECK-NEXT: [[B_OP:%.*]] = sub i8 [[C]], [[B]]
130-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A_OP]], [[B_OP]]
131-
; CHECK-NEXT: ret i1 [[CMP]]
123+
; CHECK-NEXT: ret i1 false
132124
;
133125
%A = add i8 %B, 1
134126
%A.op = sub i8 %C, %A

0 commit comments

Comments
 (0)