Skip to content

Commit 5d2bee5

Browse files
committed
[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`.
1 parent 1677989 commit 5d2bee5

File tree

2 files changed

+40
-20
lines changed

2 files changed

+40
-20
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -698,13 +698,26 @@ static void computeKnownBitsFromCmp(const Value *V, CmpInst::Predicate Pred,
698698
break;
699699
}
700700
default:
701-
const APInt *Offset = nullptr;
702-
if (match(LHS, m_CombineOr(m_V, m_AddLike(m_V, m_APInt(Offset)))) &&
703-
match(RHS, m_APInt(C))) {
704-
ConstantRange LHSRange = ConstantRange::makeAllowedICmpRegion(Pred, *C);
705-
if (Offset)
706-
LHSRange = LHSRange.sub(*Offset);
707-
Known = Known.unionWith(LHSRange.toKnownBits());
701+
if (match(RHS, m_APInt(C))) {
702+
const APInt *Offset = nullptr;
703+
if (match(LHS, m_CombineOr(m_V, m_AddLike(m_V, m_APInt(Offset))))) {
704+
ConstantRange LHSRange = ConstantRange::makeAllowedICmpRegion(Pred, *C);
705+
if (Offset)
706+
LHSRange = LHSRange.sub(*Offset);
707+
Known = Known.unionWith(LHSRange.toKnownBits());
708+
}
709+
// X & Y u> C -> X u> C && Y u> C
710+
if ((Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_UGE) &&
711+
match(LHS, m_c_And(m_V, m_Value()))) {
712+
Known.One.setHighBits(
713+
(*C + (Pred == ICmpInst::ICMP_UGT)).countLeadingOnes());
714+
}
715+
// X | Y u< C -> X u< C && Y u< C
716+
if ((Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_ULE) &&
717+
match(LHS, m_c_Or(m_V, m_Value()))) {
718+
Known.Zero.setHighBits(
719+
(*C - (Pred == ICmpInst::ICMP_ULT)).countLeadingZeros());
720+
}
708721
}
709722
break;
710723
}
@@ -9283,11 +9296,22 @@ void llvm::findValuesAffectedByCondition(
92839296
AddAffected(X);
92849297
}
92859298
} else {
9286-
// Handle (A + C1) u< C2, which is the canonical form of
9287-
// A > C3 && A < C4.
9288-
if (match(A, m_AddLike(m_Value(X), m_ConstantInt())) &&
9289-
match(B, m_ConstantInt()))
9290-
AddAffected(X);
9299+
if (match(B, m_ConstantInt())) {
9300+
// Handle (A + C1) u< C2, which is the canonical form of
9301+
// A > C3 && A < C4.
9302+
if (match(A, m_AddLike(m_Value(X), m_ConstantInt())))
9303+
AddAffected(X);
9304+
9305+
Value *Y;
9306+
// X & Y u> C -> X >u C && Y >u C
9307+
// X | Y u< C -> X u< C && Y u< C
9308+
if (ICmpInst::isUnsigned(Pred) &&
9309+
(match(A, m_And(m_Value(X), m_Value(Y))) ||
9310+
match(A, m_Or(m_Value(X), m_Value(Y))))) {
9311+
AddAffected(X);
9312+
AddAffected(Y);
9313+
}
9314+
}
92919315

92929316
// Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
92939317
// by computeKnownFPClass().

llvm/test/Transforms/InstCombine/known-bits.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,7 @@ define i8 @test_icmp_or(i8 %n, i8 %n2, i8 %other) {
539539
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_OR]], 32
540540
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
541541
; CHECK: if.then:
542-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
543-
; CHECK-NEXT: ret i8 [[R]]
542+
; CHECK-NEXT: ret i8 0
544543
; CHECK: if.else:
545544
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
546545
;
@@ -566,8 +565,7 @@ define i8 @test_icmp_or2(i8 %n, i8 %n2, i8 %other) {
566565
; CHECK: if.then:
567566
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
568567
; CHECK: if.else:
569-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
570-
; CHECK-NEXT: ret i8 [[R]]
568+
; CHECK-NEXT: ret i8 0
571569
;
572570
entry:
573571
%n_or = or i8 %n, %n2
@@ -639,8 +637,7 @@ define i8 @test_icmp_and(i8 %n, i8 %n2, i8 %other) {
639637
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_AND]], -33
640638
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
641639
; CHECK: if.then:
642-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
643-
; CHECK-NEXT: ret i8 [[R]]
640+
; CHECK-NEXT: ret i8 32
644641
; CHECK: if.else:
645642
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
646643
;
@@ -666,8 +663,7 @@ define i8 @test_icmp_and2(i8 %n, i8 %n2, i8 %other) {
666663
; CHECK: if.then:
667664
; CHECK-NEXT: ret i8 [[OTHER:%.*]]
668665
; CHECK: if.else:
669-
; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
670-
; CHECK-NEXT: ret i8 [[R]]
666+
; CHECK-NEXT: ret i8 32
671667
;
672668
entry:
673669
%n_and = and i8 %n, %n2

0 commit comments

Comments
 (0)