[llvm] b865960 - [ValueTracking] compute knownbits from `(icmp upred X (and/or X, Y))`; NFC
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 11 10:27:38 PDT 2024
Author: Noah Goldstein
Date: 2024-04-11T12:27:10-05:00
New Revision: b8659600c3af6e5f1a5dd51ac59d6ab2554603d8
URL: https://github.com/llvm/llvm-project/commit/b8659600c3af6e5f1a5dd51ac59d6ab2554603d8
DIFF: https://github.com/llvm/llvm-project/commit/b8659600c3af6e5f1a5dd51ac59d6ab2554603d8.diff
LOG: [ValueTracking] compute knownbits from `(icmp upred X (and/or X, Y))`; NFC
`(icmp uge/ugt (and X, Y), C)` implies both `(icmp uge/ugt X, C)` and
`(icmp uge/ugt Y, C)`. We can use this to deduce leading ones in `X`.
`(icmp ule/ult (or X, Y), C)` implies both `(icmp ule/ult X, C)` and
`(icmp ule/ult Y, C)`. We can use this to deduce leading zeros in `X`.
Closes #86059
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstCombine/known-bits.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3a10de72a27562..eb8925c5347537 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -701,13 +701,26 @@ static void computeKnownBitsFromCmp(const Value *V, CmpInst::Predicate Pred,
break;
}
default:
- const APInt *Offset = nullptr;
- if (match(LHS, m_CombineOr(m_V, m_AddLike(m_V, m_APInt(Offset)))) &&
- match(RHS, m_APInt(C))) {
- ConstantRange LHSRange = ConstantRange::makeAllowedICmpRegion(Pred, *C);
- if (Offset)
- LHSRange = LHSRange.sub(*Offset);
- Known = Known.unionWith(LHSRange.toKnownBits());
+ if (match(RHS, m_APInt(C))) {
+ const APInt *Offset = nullptr;
+ if (match(LHS, m_CombineOr(m_V, m_AddLike(m_V, m_APInt(Offset))))) {
+ ConstantRange LHSRange = ConstantRange::makeAllowedICmpRegion(Pred, *C);
+ if (Offset)
+ LHSRange = LHSRange.sub(*Offset);
+ Known = Known.unionWith(LHSRange.toKnownBits());
+ }
+ // X & Y u> C -> X u> C && Y u> C
+ if ((Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_UGE) &&
+ match(LHS, m_c_And(m_V, m_Value()))) {
+ Known.One.setHighBits(
+ (*C + (Pred == ICmpInst::ICMP_UGT)).countLeadingOnes());
+ }
+ // X | Y u< C -> X u< C && Y u< C
+ if ((Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE) &&
+ match(LHS, m_c_Or(m_V, m_Value()))) {
+ Known.Zero.setHighBits(
+ (*C - (Pred == ICmpInst::ICMP_ULT)).countLeadingZeros());
+ }
}
break;
}
@@ -9448,11 +9461,22 @@ void llvm::findValuesAffectedByCondition(
}
}
} else {
- // Handle (A + C1) u< C2, which is the canonical form of
- // A > C3 && A < C4.
- if (match(A, m_AddLike(m_Value(X), m_ConstantInt())) &&
- match(B, m_ConstantInt()))
- AddAffected(X);
+ if (match(B, m_ConstantInt())) {
+ // Handle (A + C1) u< C2, which is the canonical form of
+ // A > C3 && A < C4.
+ if (match(A, m_AddLike(m_Value(X), m_ConstantInt())))
+ AddAffected(X);
+
+ Value *Y;
+ // X & Y u> C -> X >u C && Y >u C
+ // X | Y u< C -> X u< C && Y u< C
+ if (ICmpInst::isUnsigned(Pred) &&
+ (match(A, m_And(m_Value(X), m_Value(Y))) ||
+ match(A, m_Or(m_Value(X), m_Value(Y))))) {
+ AddAffected(X);
+ AddAffected(Y);
+ }
+ }
// Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
// by computeKnownFPClass().
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index 30c18cebb2a3ba..fea2f647ee2a81 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -550,8 +550,7 @@ define i8 @test_icmp_or(i8 %n, i8 %n2, i8 %other) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_OR]], 32
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
; CHECK: if.else:
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
;
@@ -577,8 +576,7 @@ define i8 @test_icmp_or2(i8 %n, i8 %n2, i8 %other) {
; CHECK: if.then:
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
; CHECK: if.else:
-; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
entry:
%n_or = or i8 %n, %n2
@@ -650,8 +648,7 @@ define i8 @test_icmp_and(i8 %n, i8 %n2, i8 %other) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_AND]], -33
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 32
; CHECK: if.else:
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
;
@@ -677,8 +674,7 @@ define i8 @test_icmp_and2(i8 %n, i8 %n2, i8 %other) {
; CHECK: if.then:
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
; CHECK: if.else:
-; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 32
;
entry:
%n_and = and i8 %n, %n2
More information about the llvm-commits
mailing list