From b4f227a2a58661618237bc78de4b4c7deb3b48c5 Mon Sep 17 00:00:00 2001 From: David Green Date: Thu, 11 Oct 2018 11:28:27 +0000 Subject: [PATCH] [InstCombine] Demand bits of UMin This is the umin alternative to the umax code from rL344237. We use DeMorgans law on the umax case to bring us to the same thing on umin, but using countLeadingOnes, not countLeadingZeros. Differential Revision: https://reviews.llvm.org/D53036 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344239 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 10 ++++++++++ test/Transforms/InstCombine/minmax-demandbits.ll | 12 +++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 18a2b2fdbfe..45cacc73d63 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -325,6 +325,16 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, unsigned CTZ = DemandedMask.countTrailingZeros(); if (match(RHS, m_APInt(C)) && CTZ >= C->getActiveBits()) return LHS; + } else if (SPF == SPF_UMIN) { + // UMin(A, C) == A if ... + // The lowest non-zero bit of DemandMask is higher than the highest + // non-one bit of C. + // This comes from using DeMorgans on the above umax example. + const APInt *C; + unsigned CTZ = DemandedMask.countTrailingZeros(); + if (match(RHS, m_APInt(C)) && + CTZ >= C->getBitWidth() - C->countLeadingOnes()) + return LHS; } // If this is a select as part of any other min/max pattern, don't simplify diff --git a/test/Transforms/InstCombine/minmax-demandbits.ll b/test/Transforms/InstCombine/minmax-demandbits.ll index f838560f965..29a569663d2 100644 --- a/test/Transforms/InstCombine/minmax-demandbits.ll +++ b/test/Transforms/InstCombine/minmax-demandbits.ll @@ -190,9 +190,7 @@ define i32 @or_umin(i32 %A) { define i8 @or_min_31_30(i8 %A) { ; CHECK-LABEL: @or_min_31_30( -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A:%.*]], -30 -; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP]], i8 [[A]], i8 -30 -; CHECK-NEXT: [[R:%.*]] = or i8 [[MIN]], 31 +; CHECK-NEXT: [[R:%.*]] = or i8 [[A:%.*]], 31 ; CHECK-NEXT: ret i8 [[R]] ; %cmp = icmp ult i8 %A, -30 @@ -203,9 +201,7 @@ define i8 @or_min_31_30(i8 %A) { define i8 @and_min_7_7(i8 %A) { ; CHECK-LABEL: @and_min_7_7( -; CHECK-NEXT: [[L2:%.*]] = icmp ult i8 [[A:%.*]], -7 -; CHECK-NEXT: [[MIN:%.*]] = select i1 [[L2]], i8 [[A]], i8 -7 -; CHECK-NEXT: [[R:%.*]] = and i8 [[MIN]], -8 +; CHECK-NEXT: [[R:%.*]] = and i8 [[A:%.*]], -8 ; CHECK-NEXT: ret i8 [[R]] ; %l2 = icmp ult i8 %A, -7 @@ -216,9 +212,7 @@ define i8 @and_min_7_7(i8 %A) { define i8 @and_min_7_8(i8 %A) { ; CHECK-LABEL: @and_min_7_8( -; CHECK-NEXT: [[L2:%.*]] = icmp ult i8 [[A:%.*]], -8 -; CHECK-NEXT: [[MIN:%.*]] = select i1 [[L2]], i8 [[A]], i8 -8 -; CHECK-NEXT: [[R:%.*]] = and i8 [[MIN]], -8 +; CHECK-NEXT: [[R:%.*]] = and i8 [[A:%.*]], -8 ; CHECK-NEXT: ret i8 [[R]] ; %l2 = icmp ult i8 %A, -8 -- 2.11.0