[llvm] c6a4fc8 - [ValueTracking] Determine assume KnownBits using ConstantRange
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 5 05:00:12 PDT 2023
Author: Nikita Popov
Date: 2023-07-05T14:00:03+02:00
New Revision: c6a4fc8ddfaf68d932b69b80a1efd0742fa8211a
URL: https://github.com/llvm/llvm-project/commit/c6a4fc8ddfaf68d932b69b80a1efd0742fa8211a
DIFF: https://github.com/llvm/llvm-project/commit/c6a4fc8ddfaf68d932b69b80a1efd0742fa8211a.diff
LOG: [ValueTracking] Determine assume KnownBits using ConstantRange
For non-equality icmps, we don't do any KnownBits-specific
reasoning, and just use the known bits as a constraint on the range.
We can generalize this for all predicates by round-tripping through
ConstantRange and using makeAllowedICmpRegion().
The minor improvement in zext-or-icmp is because we assume that
a value is ult [0,1], which means it must be zero.
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstCombine/zext-or-icmp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5499fe23219c2f..b98615da444189 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -644,8 +644,6 @@ static void computeKnownBitsFromCmp(const Value *V, const ICmpInst *Cmp,
CmpInst::Predicate Pred;
uint64_t C;
switch (Cmp->getPredicate()) {
- default:
- break;
case ICmpInst::ICMP_EQ:
// assume(v = a)
if (match(Cmp, m_c_ICmp(Pred, m_V, m_Value(A)))) {
@@ -759,87 +757,24 @@ static void computeKnownBitsFromCmp(const Value *V, const ICmpInst *Cmp,
Known.One |= RHSKnown.Zero << C;
}
break;
- case ICmpInst::ICMP_SGE:
- // assume(v >=_s c) where c is non-negative
- if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A)))) {
- KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC);
-
- if (RHSKnown.isNonNegative()) {
- // We know that the sign bit is zero.
- Known.makeNonNegative();
- }
- }
- break;
- case ICmpInst::ICMP_SGT:
- // assume(v >_s c) where c is at least -1.
- if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A)))) {
- KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC);
-
- if (RHSKnown.isAllOnes() || RHSKnown.isNonNegative()) {
- // We know that the sign bit is zero.
- Known.makeNonNegative();
- }
- }
- break;
- case ICmpInst::ICMP_SLE:
- // assume(v <=_s c) where c is negative
- if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A)))) {
- KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC);
-
- if (RHSKnown.isNegative()) {
- // We know that the sign bit is one.
- Known.makeNegative();
- }
- }
- break;
- case ICmpInst::ICMP_SLT:
- // assume(v <_s c) where c is non-positive
- if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A)))) {
- KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC);
-
- if (RHSKnown.isZero() || RHSKnown.isNegative()) {
- // We know that the sign bit is one.
- Known.makeNegative();
- }
- }
- break;
- case ICmpInst::ICMP_ULE:
- // assume(v <=_u c)
- if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A)))) {
- KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC);
-
- // Whatever high bits in c are zero are known to be zero.
- Known.Zero.setHighBits(RHSKnown.countMinLeadingZeros());
- }
- break;
- case ICmpInst::ICMP_ULT:
- // assume(v <_u c)
- if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A)))) {
- KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC);
-
- // If the RHS is known zero, then this assumption must be wrong (nothing
- // is unsigned less than zero). Signal a conflict and get out of here.
- if (RHSKnown.isZero()) {
- Known.Zero.setAllBits();
- Known.One.setAllBits();
- break;
- }
-
- // Whatever high bits in c are zero are known to be zero (if c is a power
- // of 2, then one more).
- if (isKnownToBeAPowerOfTwo(A, false, Depth + 1, QueryNoAC))
- Known.Zero.setHighBits(RHSKnown.countMinLeadingZeros() + 1);
- else
- Known.Zero.setHighBits(RHSKnown.countMinLeadingZeros());
- }
- break;
case ICmpInst::ICMP_NE: {
// assume (v & b != 0) where b is a power of 2
const APInt *BPow2;
if (match(Cmp, m_ICmp(Pred, m_c_And(m_V, m_Power2(BPow2)), m_Zero()))) {
Known.One |= *BPow2;
}
- } break;
+ break;
+ }
+ default:
+ if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A)))) {
+ KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC);
+ ConstantRange RHSRange =
+ ConstantRange::fromKnownBits(RHSKnown, Cmp->isSigned());
+ ConstantRange LHSRange =
+ ConstantRange::makeAllowedICmpRegion(Pred, RHSRange);
+ Known = Known.unionWith(LHSRange.toKnownBits());
+ }
+ break;
}
}
diff --git a/llvm/test/Transforms/InstCombine/zext-or-icmp.ll b/llvm/test/Transforms/InstCombine/zext-or-icmp.ll
index 23bfccfc06a9e0..74d0f2f21aec8e 100644
--- a/llvm/test/Transforms/InstCombine/zext-or-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/zext-or-icmp.ll
@@ -243,7 +243,7 @@ define i1 @PR51762(ptr %i, i32 %t0, i16 %t1, ptr %p, ptr %d, ptr %f, i32 %p2, i1
; CHECK-NEXT: store i32 [[ADD]], ptr [[F]], align 4
; CHECK-NEXT: [[REM18:%.*]] = srem i32 [[LOR_EXT]], [[ADD]]
; CHECK-NEXT: [[CONV19:%.*]] = zext i32 [[REM18]] to i64
-; CHECK-NEXT: store i32 [[SROA38]], ptr [[D]], align 8
+; CHECK-NEXT: store i32 0, ptr [[D]], align 8
; CHECK-NEXT: [[R:%.*]] = icmp ult i64 [[INSERT_INSERT41]], [[CONV19]]
; CHECK-NEXT: call void @llvm.assume(i1 [[R]])
; CHECK-NEXT: ret i1 [[R]]
More information about the llvm-commits
mailing list