diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -1069,13 +1069,16 @@ if (match(Op0, m_SExt(m_Value(X))) && (!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType()))) { - // Are we moving the sign bit to the low bit and widening with high zeros? unsigned SrcTyBitWidth = X->getType()->getScalarSizeInBits(); - if (ShAmtC == BitWidth - 1) { - // lshr (sext i1 X to iN), N-1 --> zext X to iN - if (SrcTyBitWidth == 1) - return new ZExtInst(X, Ty); + // lshr (sext i1 X to iN), C --> select (X, -1 >> C, 0) + if (SrcTyBitWidth == 1) { + auto *NewC = ConstantExpr::getLShr(ConstantInt::get(Ty, -1), + ConstantInt::get(Ty, ShAmtC)); + return SelectInst::Create(X, NewC, ConstantInt::getNullValue(Ty)); + } + // Are we moving the sign bit to the low bit and widening with high zeros? + if (ShAmtC == BitWidth - 1) { // lshr (sext iM X to iN), N-1 --> zext (lshr X, M-1) to iN if (Op0->hasOneUse()) { Value *NewLShr = Builder.CreateLShr(X, SrcTyBitWidth - 1); diff --git a/llvm/test/Transforms/InstCombine/pr52078.ll b/llvm/test/Transforms/InstCombine/pr52078.ll --- a/llvm/test/Transforms/InstCombine/pr52078.ll +++ b/llvm/test/Transforms/InstCombine/pr52078.ll @@ -3,8 +3,7 @@ define i16 @foo(i1 %a) { ; CHECK-LABEL: @foo( -; CHECK-NEXT: [[S:%.*]] = sext i1 [[A:%.*]] to i16 -; CHECK-NEXT: [[LSHR:%.*]] = lshr i16 [[S]], 1 +; CHECK-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0 ; CHECK-NEXT: ret i16 [[LSHR]] ; %s = sext i1 %a to i16 diff --git a/llvm/test/Transforms/PhaseOrdering/pr52078.ll b/llvm/test/Transforms/PhaseOrdering/pr52078.ll --- a/llvm/test/Transforms/PhaseOrdering/pr52078.ll +++ b/llvm/test/Transforms/PhaseOrdering/pr52078.ll @@ -11,8 +11,7 @@ ; IC-NEXT: ret i16 [[TRUNC]] ; ; AIC_AND_IC-LABEL: @foo( -; AIC_AND_IC-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i16 -; AIC_AND_IC-NEXT: [[LSHR:%.*]] = lshr i16 [[SEXT]], 1 +; AIC_AND_IC-NEXT: [[LSHR:%.*]] = select i1 [[A:%.*]], i16 32767, i16 0 ; AIC_AND_IC-NEXT: ret i16 [[LSHR]] ; %sext = sext i1 %a to i16