Index: lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -314,11 +314,23 @@ 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; + if (match(RHS, m_APInt(C)) && + DemandedMask.countTrailingZeros() + 1 > + C->getBitWidth() - C->countLeadingZeros()) + 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 +348,7 @@ 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(); Index: test/Transforms/InstCombine/minmax-demandbits.ll =================================================================== --- test/Transforms/InstCombine/minmax-demandbits.ll +++ 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_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 @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_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_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_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