diff options
| author | David Green <david.green@arm.com> | 2018-10-11 11:04:09 +0000 |
|---|---|---|
| committer | David Green <david.green@arm.com> | 2018-10-11 11:04:09 +0000 |
| commit | 30c0e98b9cc9670f4990446a8c7938a16c9d073f (patch) | |
| tree | f3c459acbc1ef38be18f4fc22695225d70d2ba61 | |
| parent | 64151bdea0855b7fe834430daae05c640c7af511 (diff) | |
| download | bcm5719-llvm-30c0e98b9cc9670f4990446a8c7938a16c9d073f.tar.gz bcm5719-llvm-30c0e98b9cc9670f4990446a8c7938a16c9d073f.zip | |
[InstCombine] Demand bits of UMax
Use the demanded bits of umax(A,C) to prove we can just use A so long as the
lowest non-zero bit of DemandMask is higher than the highest non-zero bit of C
Differential Revision: https://reviews.llvm.org/D53033
llvm-svn: 344237
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 20 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/minmax-demandbits.ll | 28 |
2 files changed, 23 insertions, 25 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 936daa828a5..18a2b2fdbfe 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -314,11 +314,22 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, Known.One = std::move(IKnownOne); break; } - case Instruction::Select: - // If this is a select as part of a min/max pattern, don't simplify any - // further in case we break the structure. + case Instruction::Select: { Value *LHS, *RHS; - if (matchSelectPattern(I, LHS, RHS).Flavor != SPF_UNKNOWN) + SelectPatternFlavor SPF = matchSelectPattern(I, LHS, RHS).Flavor; + if (SPF == SPF_UMAX) { + // UMax(A, C) == A if ... + // The lowest non-zero bit of DemandMask is higher than the highest + // non-zero bit of C. + const APInt *C; + unsigned CTZ = DemandedMask.countTrailingZeros(); + if (match(RHS, m_APInt(C)) && CTZ >= C->getActiveBits()) + return LHS; + } + + // If this is a select as part of any other min/max pattern, don't simplify + // any further in case we break the structure. + if (SPF != SPF_UNKNOWN) return nullptr; if (SimplifyDemandedBits(I, 2, DemandedMask, RHSKnown, Depth + 1) || @@ -336,6 +347,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, Known.One = RHSKnown.One & LHSKnown.One; Known.Zero = RHSKnown.Zero & LHSKnown.Zero; break; + } case Instruction::ZExt: case Instruction::Trunc: { unsigned SrcBitWidth = I->getOperand(0)->getType()->getScalarSizeInBits(); diff --git a/llvm/test/Transforms/InstCombine/minmax-demandbits.ll b/llvm/test/Transforms/InstCombine/minmax-demandbits.ll index 8977c19856f..f838560f965 100644 --- a/llvm/test/Transforms/InstCombine/minmax-demandbits.ll +++ b/llvm/test/Transforms/InstCombine/minmax-demandbits.ll @@ -4,9 +4,7 @@ define i32 @and_umax_less(i32 %A) { ; CHECK-LABEL: @and_umax_less( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], 31 -; CHECK-NEXT: [[L1:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 31 -; CHECK-NEXT: [[X:%.*]] = and i32 [[L1]], -32 +; CHECK-NEXT: [[X:%.*]] = and i32 [[A:%.*]], -32 ; CHECK-NEXT: ret i32 [[X]] ; %l0 = icmp ugt i32 31, %A @@ -17,9 +15,7 @@ define i32 @and_umax_less(i32 %A) { define i32 @and_umax_muchless(i32 %A) { ; CHECK-LABEL: @and_umax_muchless( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], 12 -; CHECK-NEXT: [[L1:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 12 -; CHECK-NEXT: [[X:%.*]] = and i32 [[L1]], -32 +; CHECK-NEXT: [[X:%.*]] = and i32 [[A:%.*]], -32 ; CHECK-NEXT: ret i32 [[X]] ; %l0 = icmp ugt i32 12, %A @@ -43,9 +39,7 @@ define i32 @and_umax_more(i32 %A) { define i32 @shr_umax(i32 %A) { ; CHECK-LABEL: @shr_umax( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], 15 -; CHECK-NEXT: [[L1:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 15 -; CHECK-NEXT: [[X:%.*]] = lshr i32 [[L1]], 4 +; CHECK-NEXT: [[X:%.*]] = lshr i32 [[A:%.*]], 4 ; CHECK-NEXT: ret i32 [[X]] ; %l0 = icmp ugt i32 15, %A @@ -80,9 +74,7 @@ define i8 @t_0_10(i8 %A) { define i8 @t_1_10(i8 %A) { ; CHECK-LABEL: @t_1_10( -; CHECK-NEXT: [[L2:%.*]] = icmp ugt i8 [[A:%.*]], 1 -; CHECK-NEXT: [[L1:%.*]] = select i1 [[L2]], i8 [[A]], i8 1 -; CHECK-NEXT: [[X:%.*]] = and i8 [[L1]], 10 +; CHECK-NEXT: [[X:%.*]] = and i8 [[A:%.*]], 10 ; CHECK-NEXT: ret i8 [[X]] ; %l2 = icmp ugt i8 %A, 1 @@ -93,9 +85,7 @@ define i8 @t_1_10(i8 %A) { define i8 @t_2_4(i8 %A) { ; CHECK-LABEL: @t_2_4( -; CHECK-NEXT: [[L2:%.*]] = icmp ugt i8 [[A:%.*]], 2 -; CHECK-NEXT: [[L1:%.*]] = select i1 [[L2]], i8 [[A]], i8 2 -; CHECK-NEXT: [[X:%.*]] = and i8 [[L1]], 4 +; CHECK-NEXT: [[X:%.*]] = and i8 [[A:%.*]], 4 ; CHECK-NEXT: ret i8 [[X]] ; %l2 = icmp ugt i8 %A, 2 @@ -106,9 +96,7 @@ define i8 @t_2_4(i8 %A) { define i8 @t_2_192(i8 %A) { ; CHECK-LABEL: @t_2_192( -; CHECK-NEXT: [[L2:%.*]] = icmp ugt i8 [[A:%.*]], 2 -; CHECK-NEXT: [[L1:%.*]] = select i1 [[L2]], i8 [[A]], i8 2 -; CHECK-NEXT: [[X:%.*]] = and i8 [[L1]], -64 +; CHECK-NEXT: [[X:%.*]] = and i8 [[A:%.*]], -64 ; CHECK-NEXT: ret i8 [[X]] ; %l2 = icmp ugt i8 %A, 2 @@ -119,9 +107,7 @@ define i8 @t_2_192(i8 %A) { define i8 @t_2_63_or(i8 %A) { ; CHECK-LABEL: @t_2_63_or( -; CHECK-NEXT: [[L2:%.*]] = icmp ugt i8 [[A:%.*]], 2 -; CHECK-NEXT: [[L1:%.*]] = select i1 [[L2]], i8 [[A]], i8 2 -; CHECK-NEXT: [[X:%.*]] = or i8 [[L1]], 63 +; CHECK-NEXT: [[X:%.*]] = or i8 [[A:%.*]], 63 ; CHECK-NEXT: ret i8 [[X]] ; %l2 = icmp ugt i8 %A, 2 |

