Skip to content

Commit 78f7ca0

Browse files
authored
[InstCombine] Use KnownBits predicate helpers (#115874)
Inside foldICmpUsingKnownBits(), instead of rolling our own logic based on min/max values, make use of ICmpInst::compare() working on KnownBits. This gives better results for the equality predicates. In practice, the improvement is only for pointers, because isKnownNonEqual() handles the non-pointer case. I've adjusted some tests to prevent the new fold from triggering, to retain their original intent of testing constant expressions.
1 parent cb64c3c commit 78f7ca0

File tree

5 files changed

+17
-69
lines changed

5 files changed

+17
-69
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6576,6 +6576,16 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
65766576
return &I;
65776577
}
65786578

6579+
if (!isa<Constant>(Op0) && Op0Known.isConstant())
6580+
return new ICmpInst(
6581+
Pred, ConstantExpr::getIntegerValue(Ty, Op0Known.getConstant()), Op1);
6582+
if (!isa<Constant>(Op1) && Op1Known.isConstant())
6583+
return new ICmpInst(
6584+
Pred, Op0, ConstantExpr::getIntegerValue(Ty, Op1Known.getConstant()));
6585+
6586+
if (std::optional<bool> Res = ICmpInst::compare(Op0Known, Op1Known, Pred))
6587+
return replaceInstUsesWith(I, ConstantInt::getBool(I.getType(), *Res));
6588+
65796589
// Given the known and unknown bits, compute a range that the LHS could be
65806590
// in. Compute the Min, Max and RHS values based on the known bits. For the
65816591
// EQ and NE we use unsigned values.
@@ -6593,14 +6603,6 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
65936603
Op1Max = Op1Known.getMaxValue();
65946604
}
65956605

6596-
// If Min and Max are known to be the same, then SimplifyDemandedBits figured
6597-
// out that the LHS or RHS is a constant. Constant fold this now, so that
6598-
// code below can assume that Min != Max.
6599-
if (!isa<Constant>(Op0) && Op0Min == Op0Max)
6600-
return new ICmpInst(Pred, ConstantExpr::getIntegerValue(Ty, Op0Min), Op1);
6601-
if (!isa<Constant>(Op1) && Op1Min == Op1Max)
6602-
return new ICmpInst(Pred, Op0, ConstantExpr::getIntegerValue(Ty, Op1Min));
6603-
66046606
// Don't break up a clamp pattern -- (min(max X, Y), Z) -- by replacing a
66056607
// min/max canonical compare with some other compare. That could lead to
66066608
// conflict with select canonicalization and infinite looping.
@@ -6682,13 +6684,9 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
66826684
// simplify this comparison. For example, (x&4) < 8 is always true.
66836685
switch (Pred) {
66846686
default:
6685-
llvm_unreachable("Unknown icmp opcode!");
6687+
break;
66866688
case ICmpInst::ICMP_EQ:
66876689
case ICmpInst::ICMP_NE: {
6688-
if (Op0Max.ult(Op1Min) || Op0Min.ugt(Op1Max))
6689-
return replaceInstUsesWith(
6690-
I, ConstantInt::getBool(I.getType(), Pred == CmpInst::ICMP_NE));
6691-
66926690
// If all bits are known zero except for one, then we know at most one bit
66936691
// is set. If the comparison is against zero, then this is a check to see if
66946692
// *that* bit is set.
@@ -6728,67 +6726,19 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
67286726
ConstantInt::getNullValue(Op1->getType()));
67296727
break;
67306728
}
6731-
case ICmpInst::ICMP_ULT: {
6732-
if (Op0Max.ult(Op1Min)) // A <u B -> true if max(A) < min(B)
6733-
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
6734-
if (Op0Min.uge(Op1Max)) // A <u B -> false if min(A) >= max(B)
6735-
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
6736-
break;
6737-
}
6738-
case ICmpInst::ICMP_UGT: {
6739-
if (Op0Min.ugt(Op1Max)) // A >u B -> true if min(A) > max(B)
6740-
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
6741-
if (Op0Max.ule(Op1Min)) // A >u B -> false if max(A) <= max(B)
6742-
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
6743-
break;
6744-
}
6745-
case ICmpInst::ICMP_SLT: {
6746-
if (Op0Max.slt(Op1Min)) // A <s B -> true if max(A) < min(C)
6747-
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
6748-
if (Op0Min.sge(Op1Max)) // A <s B -> false if min(A) >= max(C)
6749-
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
6750-
break;
6751-
}
6752-
case ICmpInst::ICMP_SGT: {
6753-
if (Op0Min.sgt(Op1Max)) // A >s B -> true if min(A) > max(B)
6754-
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
6755-
if (Op0Max.sle(Op1Min)) // A >s B -> false if max(A) <= min(B)
6756-
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
6757-
break;
6758-
}
67596729
case ICmpInst::ICMP_SGE:
6760-
assert(!isa<ConstantInt>(Op1) && "ICMP_SGE with ConstantInt not folded!");
6761-
if (Op0Min.sge(Op1Max)) // A >=s B -> true if min(A) >= max(B)
6762-
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
6763-
if (Op0Max.slt(Op1Min)) // A >=s B -> false if max(A) < min(B)
6764-
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
67656730
if (Op1Min == Op0Max) // A >=s B -> A == B if max(A) == min(B)
67666731
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
67676732
break;
67686733
case ICmpInst::ICMP_SLE:
6769-
assert(!isa<ConstantInt>(Op1) && "ICMP_SLE with ConstantInt not folded!");
6770-
if (Op0Max.sle(Op1Min)) // A <=s B -> true if max(A) <= min(B)
6771-
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
6772-
if (Op0Min.sgt(Op1Max)) // A <=s B -> false if min(A) > max(B)
6773-
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
67746734
if (Op1Max == Op0Min) // A <=s B -> A == B if min(A) == max(B)
67756735
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
67766736
break;
67776737
case ICmpInst::ICMP_UGE:
6778-
assert(!isa<ConstantInt>(Op1) && "ICMP_UGE with ConstantInt not folded!");
6779-
if (Op0Min.uge(Op1Max)) // A >=u B -> true if min(A) >= max(B)
6780-
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
6781-
if (Op0Max.ult(Op1Min)) // A >=u B -> false if max(A) < min(B)
6782-
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
67836738
if (Op1Min == Op0Max) // A >=u B -> A == B if max(A) == min(B)
67846739
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
67856740
break;
67866741
case ICmpInst::ICMP_ULE:
6787-
assert(!isa<ConstantInt>(Op1) && "ICMP_ULE with ConstantInt not folded!");
6788-
if (Op0Max.ule(Op1Min)) // A <=u B -> true if max(A) <= min(B)
6789-
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
6790-
if (Op0Min.ugt(Op1Max)) // A <=u B -> false if min(A) > max(B)
6791-
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
67926742
if (Op1Max == Op0Min) // A <=u B -> A == B if min(A) == max(B)
67936743
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
67946744
break;

llvm/test/Transforms/InstCombine/icmp-gep.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,7 @@ define i1 @gep_nusw(ptr %p, i64 %a, i64 %b, i64 %c, i64 %d) {
583583

584584
define i1 @pointer_icmp_aligned_with_offset(ptr align 8 %a, ptr align 8 %a2) {
585585
; CHECK-LABEL: @pointer_icmp_aligned_with_offset(
586-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 4
587-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP]], [[A2:%.*]]
588-
; CHECK-NEXT: ret i1 [[CMP]]
586+
; CHECK-NEXT: ret i1 false
589587
;
590588
%gep = getelementptr i8, ptr %a, i64 4
591589
%cmp = icmp eq ptr %gep, %a2

llvm/test/Transforms/InstCombine/mul-inseltpoison.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,12 +570,12 @@ define i64 @test30(i32 %A, i32 %B) {
570570
@PR22087 = external global i32
571571
define i32 @test31(i32 %V) {
572572
; CHECK-LABEL: @test31(
573-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr inttoptr (i64 1 to ptr), @PR22087
573+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr inttoptr (i64 4 to ptr), @PR22087
574574
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i32
575575
; CHECK-NEXT: [[MUL1:%.*]] = shl i32 [[V:%.*]], [[EXT]]
576576
; CHECK-NEXT: ret i32 [[MUL1]]
577577
;
578-
%cmp = icmp ne ptr inttoptr (i64 1 to ptr), @PR22087
578+
%cmp = icmp ne ptr inttoptr (i64 4 to ptr), @PR22087
579579
%ext = zext i1 %cmp to i32
580580
%shl = shl i32 1, %ext
581581
%mul = mul i32 %V, %shl

llvm/test/Transforms/InstCombine/mul.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,12 +1153,12 @@ define i64 @test30(i32 %A, i32 %B) {
11531153
@PR22087 = external global i32
11541154
define i32 @test31(i32 %V) {
11551155
; CHECK-LABEL: @test31(
1156-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr inttoptr (i64 1 to ptr), @PR22087
1156+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr inttoptr (i64 4 to ptr), @PR22087
11571157
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i32
11581158
; CHECK-NEXT: [[MUL1:%.*]] = shl i32 [[V:%.*]], [[EXT]]
11591159
; CHECK-NEXT: ret i32 [[MUL1]]
11601160
;
1161-
%cmp = icmp ne ptr inttoptr (i64 1 to ptr), @PR22087
1161+
%cmp = icmp ne ptr inttoptr (i64 4 to ptr), @PR22087
11621162
%ext = zext i1 %cmp to i32
11631163
%shl = shl i32 1, %ext
11641164
%mul = mul i32 %V, %shl

llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ define <2 x i1> @n38_overshift(<2 x i32> %x, <2 x i32> %y) {
669669
}
670670

671671
; As usual, don't crash given constantexpr's :/
672-
@f.a = internal global i16 0
672+
@f.a = internal global i16 0, align 1
673673
define i1 @constantexpr() {
674674
; CHECK-LABEL: @constantexpr(
675675
; CHECK-NEXT: entry:

0 commit comments

Comments
 (0)