Skip to content

Commit 1d88d6f

Browse files
author
James Molloy
committed
[ValueTracking] Add a new predicate: isKnownNonEqual()
isKnownNonEqual(A, B) returns true if it can be determined that A != B. At the moment it only knows two facts, that a non-wrapping add of nonzero to a value cannot be that value: A + B != A [where B != 0, addition is nsw or nuw] and that contradictory known bits imply two values are not equal. This patch also hooks this up to InstSimplify; InstSimplify had a peephole for the first fact but not the second so this teaches InstSimplify a new trick too (alas no measured performance impact!) llvm-svn: 251012
1 parent efec163 commit 1d88d6f

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ namespace llvm {
9090
const Instruction *CxtI = nullptr,
9191
const DominatorTree *DT = nullptr);
9292

93+
/// isKnownNonEqual - Return true if the given values are known to be
94+
/// non-equal when defined. Supports scalar integer types only.
95+
bool isKnownNonEqual(Value *V1, Value *V2, const DataLayout &DL,
96+
AssumptionCache *AC = nullptr,
97+
const Instruction *CxtI = nullptr,
98+
const DominatorTree *DT = nullptr);
99+
93100
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
94101
/// this predicate to simplify operations downstream. Mask is known to be
95102
/// zero for bits that V cannot have.

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,6 +2642,14 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
26422642
}
26432643
}
26442644

2645+
// icmp eq|ne X, Y -> false|true if X != Y
2646+
if ((Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) &&
2647+
isKnownNonEqual(LHS, RHS, Q.DL, Q.AC, Q.CxtI, Q.DT)) {
2648+
LLVMContext &Ctx = LHS->getType()->getContext();
2649+
return Pred == ICmpInst::ICMP_NE ?
2650+
ConstantInt::getTrue(Ctx) : ConstantInt::getFalse(Ctx);
2651+
}
2652+
26452653
// Special logic for binary operators.
26462654
BinaryOperator *LBO = dyn_cast<BinaryOperator>(LHS);
26472655
BinaryOperator *RBO = dyn_cast<BinaryOperator>(RHS);

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,17 @@ bool llvm::isKnownNonNegative(Value *V, const DataLayout &DL, unsigned Depth,
193193
return NonNegative;
194194
}
195195

196+
static bool isKnownNonEqual(Value *V1, Value *V2, const DataLayout &DL,
197+
const Query &Q);
198+
199+
bool llvm::isKnownNonEqual(Value *V1, Value *V2, const DataLayout &DL,
200+
AssumptionCache *AC, const Instruction *CxtI,
201+
const DominatorTree *DT) {
202+
return ::isKnownNonEqual(V1, V2, DL, Query(AC,
203+
safeCxtI(V1, safeCxtI(V2, CxtI)),
204+
DT));
205+
}
206+
196207
static bool MaskedValueIsZero(Value *V, const APInt &Mask, const DataLayout &DL,
197208
unsigned Depth, const Query &Q);
198209

@@ -1950,6 +1961,51 @@ bool isKnownNonZero(Value *V, const DataLayout &DL, unsigned Depth,
19501961
return KnownOne != 0;
19511962
}
19521963

1964+
/// Return true if V2 == V1 + X, where X is known non-zero.
1965+
static bool isAddOfNonZero(Value *V1, Value *V2, const DataLayout &DL,
1966+
const Query &Q) {
1967+
BinaryOperator *BO = dyn_cast<BinaryOperator>(V1);
1968+
if (!BO || BO->getOpcode() != Instruction::Add)
1969+
return false;
1970+
Value *Op = nullptr;
1971+
if (V2 == BO->getOperand(0))
1972+
Op = BO->getOperand(1);
1973+
else if (V2 == BO->getOperand(1))
1974+
Op = BO->getOperand(0);
1975+
else
1976+
return false;
1977+
return isKnownNonZero(Op, DL, 0, Q);
1978+
}
1979+
1980+
/// Return true if it is known that V1 != V2.
1981+
static bool isKnownNonEqual(Value *V1, Value *V2, const DataLayout &DL,
1982+
const Query &Q) {
1983+
if (V1->getType()->isVectorTy() || V1 == V2)
1984+
return false;
1985+
if (V1->getType() != V2->getType())
1986+
// We can't look through casts yet.
1987+
return false;
1988+
if (isAddOfNonZero(V1, V2, DL, Q) || isAddOfNonZero(V2, V1, DL, Q))
1989+
return true;
1990+
1991+
if (IntegerType *Ty = dyn_cast<IntegerType>(V1->getType())) {
1992+
// Are any known bits in V1 contradictory to known bits in V2? If V1
1993+
// has a known zero where V2 has a known one, they must not be equal.
1994+
auto BitWidth = Ty->getBitWidth();
1995+
APInt KnownZero1(BitWidth, 0);
1996+
APInt KnownOne1(BitWidth, 0);
1997+
computeKnownBits(V1, KnownZero1, KnownOne1, DL, 0, Q);
1998+
APInt KnownZero2(BitWidth, 0);
1999+
APInt KnownOne2(BitWidth, 0);
2000+
computeKnownBits(V2, KnownZero2, KnownOne2, DL, 0, Q);
2001+
2002+
auto OppositeBits = (KnownZero1 & KnownOne2) | (KnownZero2 & KnownOne1);
2003+
if (OppositeBits.getBoolValue())
2004+
return true;
2005+
}
2006+
return false;
2007+
}
2008+
19532009
/// Return true if 'V & Mask' is known to be zero. We use this predicate to
19542010
/// simplify operations downstream. Mask is known to be zero for bits that V
19552011
/// cannot have.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; RUN: opt -instsimplify < %s -S | FileCheck %s
2+
3+
; CHECK: define i1 @test
4+
define i1 @test(i8* %pq, i8 %B) {
5+
%q = load i8, i8* %pq, !range !0 ; %q is known nonzero; no known bits
6+
%A = add nsw i8 %B, %q
7+
%cmp = icmp eq i8 %A, %B
8+
; CHECK: ret i1 false
9+
ret i1 %cmp
10+
}
11+
12+
; CHECK: define i1 @test2
13+
define i1 @test2(i8 %a, i8 %b) {
14+
%A = or i8 %a, 2 ; %A[1] = 1
15+
%B = and i8 %b, -3 ; %B[1] = 0
16+
%cmp = icmp eq i8 %A, %B ; %A[1] and %B[1] are contradictory.
17+
; CHECK: ret i1 false
18+
ret i1 %cmp
19+
}
20+
21+
!0 = !{ i8 1, i8 5 }

0 commit comments

Comments
 (0)