Skip to content

Commit de719bd

Browse files
committed
[InstCombine] Fold minmax intrinsic using KnownBits information
1 parent bd763f6 commit de719bd

File tree

4 files changed

+30
-18
lines changed

4 files changed

+30
-18
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,11 @@ ConstantRange computeConstantRange(const Value *V, bool ForSigned,
863863
const DominatorTree *DT = nullptr,
864864
unsigned Depth = 0);
865865

866+
/// Combine constant ranges from computeConstantRange() and computeKnownBits().
867+
ConstantRange
868+
computeConstantRangeIncludingKnownBits(const WithCache<const Value *> &V,
869+
bool ForSigned, const SimplifyQuery &SQ);
870+
866871
/// Return true if this function can prove that the instruction I will
867872
/// always transfer execution to one of its successors (including the next
868873
/// instruction that follows within a basic block). E.g. this is not

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6289,10 +6289,10 @@ static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
62896289
}
62906290

62916291
/// Combine constant ranges from computeConstantRange() and computeKnownBits().
6292-
static ConstantRange
6293-
computeConstantRangeIncludingKnownBits(const WithCache<const Value *> &V,
6294-
bool ForSigned,
6295-
const SimplifyQuery &SQ) {
6292+
ConstantRange
6293+
llvm::computeConstantRangeIncludingKnownBits(const WithCache<const Value *> &V,
6294+
bool ForSigned,
6295+
const SimplifyQuery &SQ) {
62966296
ConstantRange CR1 =
62976297
ConstantRange::fromKnownBits(V.getKnownBits(SQ), ForSigned);
62986298
ConstantRange CR2 = computeConstantRange(V, ForSigned, SQ.IIQ.UseInstrInfo);

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,23 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
17961796
if (Instruction *NewMinMax = factorizeMinMaxTree(II))
17971797
return NewMinMax;
17981798

1799+
// Try to fold minmax with constant RHS based on range information
1800+
const APInt *RHSC;
1801+
if (match(I1, m_APIntAllowUndef(RHSC))) {
1802+
ICmpInst::Predicate Pred =
1803+
ICmpInst::getNonStrictPredicate(MinMaxIntrinsic::getPredicate(IID));
1804+
bool IsSigned = MinMaxIntrinsic::isSigned(IID);
1805+
ConstantRange LHS_CR = computeConstantRangeIncludingKnownBits(
1806+
I0, IsSigned, SQ.getWithInstruction(II));
1807+
if (!LHS_CR.isFullSet()) {
1808+
if (LHS_CR.icmp(Pred, *RHSC))
1809+
return replaceInstUsesWith(*II, I0);
1810+
if (LHS_CR.icmp(ICmpInst::getSwappedPredicate(Pred), *RHSC))
1811+
return replaceInstUsesWith(*II,
1812+
ConstantInt::get(II->getType(), *RHSC));
1813+
}
1814+
}
1815+
17991816
break;
18001817
}
18011818
case Intrinsic::bitreverse: {

llvm/test/Transforms/InstCombine/minmax-intrinsics.ll

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,8 +2496,7 @@ define i8 @fold_umax_with_knownbits_info(i8 %a, i8 %b) {
24962496
; CHECK-NEXT: [[A1:%.*]] = or i8 [[A:%.*]], 1
24972497
; CHECK-NEXT: [[A2:%.*]] = shl i8 [[B:%.*]], 1
24982498
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[A1]], [[A2]]
2499-
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.umax.i8(i8 [[SUB]], i8 1)
2500-
; CHECK-NEXT: ret i8 [[VAL]]
2499+
; CHECK-NEXT: ret i8 [[SUB]]
25012500
;
25022501
entry:
25032502
%a1 = or i8 %a, 1
@@ -2513,8 +2512,7 @@ define <3 x i8> @fold_umax_with_knownbits_info_undef_in_splat(<3 x i8> %a, <3 x
25132512
; CHECK-NEXT: [[A1:%.*]] = or <3 x i8> [[A:%.*]], <i8 1, i8 1, i8 1>
25142513
; CHECK-NEXT: [[A2:%.*]] = shl <3 x i8> [[B:%.*]], <i8 1, i8 1, i8 1>
25152514
; CHECK-NEXT: [[SUB:%.*]] = sub <3 x i8> [[A1]], [[A2]]
2516-
; CHECK-NEXT: [[VAL:%.*]] = call <3 x i8> @llvm.umax.v3i8(<3 x i8> [[SUB]], <3 x i8> <i8 1, i8 undef, i8 1>)
2517-
; CHECK-NEXT: ret <3 x i8> [[VAL]]
2515+
; CHECK-NEXT: ret <3 x i8> [[SUB]]
25182516
;
25192517
entry:
25202518
%a1 = or <3 x i8> %a, <i8 1, i8 1, i8 1>
@@ -2527,11 +2525,7 @@ entry:
25272525
define i8 @fold_umin_with_knownbits_info(i8 %a, i8 %b) {
25282526
; CHECK-LABEL: @fold_umin_with_knownbits_info(
25292527
; CHECK-NEXT: entry:
2530-
; CHECK-NEXT: [[A1:%.*]] = or i8 [[A:%.*]], 3
2531-
; CHECK-NEXT: [[A2:%.*]] = shl i8 [[B:%.*]], 2
2532-
; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[A1]], [[A2]]
2533-
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.umin.i8(i8 [[SUB]], i8 3)
2534-
; CHECK-NEXT: ret i8 [[VAL]]
2528+
; CHECK-NEXT: ret i8 3
25352529
;
25362530
entry:
25372531
%a1 = or i8 %a, 3
@@ -2544,11 +2538,7 @@ entry:
25442538
define <3 x i8> @fold_umin_with_knownbits_info_undef_in_splat(<3 x i8> %a, <3 x i8> %b) {
25452539
; CHECK-LABEL: @fold_umin_with_knownbits_info_undef_in_splat(
25462540
; CHECK-NEXT: entry:
2547-
; CHECK-NEXT: [[A1:%.*]] = or <3 x i8> [[A:%.*]], <i8 3, i8 3, i8 3>
2548-
; CHECK-NEXT: [[A2:%.*]] = shl <3 x i8> [[B:%.*]], <i8 2, i8 2, i8 2>
2549-
; CHECK-NEXT: [[SUB:%.*]] = sub <3 x i8> [[A1]], [[A2]]
2550-
; CHECK-NEXT: [[VAL:%.*]] = call <3 x i8> @llvm.umin.v3i8(<3 x i8> [[SUB]], <3 x i8> <i8 3, i8 undef, i8 3>)
2551-
; CHECK-NEXT: ret <3 x i8> [[VAL]]
2541+
; CHECK-NEXT: ret <3 x i8> <i8 3, i8 3, i8 3>
25522542
;
25532543
entry:
25542544
%a1 = or <3 x i8> %a, <i8 3, i8 3, i8 3>

0 commit comments

Comments
 (0)