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 @@ -241,9 +241,11 @@ Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); assert(Op0->getType() == Op1->getType()); - // If the shift amount is a one-use `sext`, we can demote it to `zext`. + // If the shift amount is a `sext`, we can demote it to `zext`. + // We indeed don't check use-count here, shift-by-zext is considered much + // more friendly for any further analysis. Value *Y; - if (match(Op1, m_OneUse(m_SExt(m_Value(Y))))) { + if (match(Op1, m_SExt(m_Value(Y)))) { Value *NewExt = Builder.CreateZExt(Y, I.getType(), Op1->getName()); return BinaryOperator::Create(I.getOpcode(), Op0, NewExt); } diff --git a/llvm/test/Transforms/InstCombine/shift-by-signext.ll b/llvm/test/Transforms/InstCombine/shift-by-signext.ll --- a/llvm/test/Transforms/InstCombine/shift-by-signext.ll +++ b/llvm/test/Transforms/InstCombine/shift-by-signext.ll @@ -69,13 +69,14 @@ define i32 @t6_twoshifts(i32 %x, i8 %shamt) { ; CHECK-LABEL: @t6_twoshifts( ; CHECK-NEXT: bb: -; CHECK-NEXT: [[SHAMT_WIDE:%.*]] = sext i8 [[SHAMT:%.*]] to i32 ; CHECK-NEXT: br label [[WORK:%.*]] ; CHECK: work: ; CHECK-NEXT: br label [[END:%.*]] ; CHECK: end: -; CHECK-NEXT: [[N0:%.*]] = shl i32 [[X:%.*]], [[SHAMT_WIDE]] -; CHECK-NEXT: [[R:%.*]] = ashr i32 [[N0]], [[SHAMT_WIDE]] +; CHECK-NEXT: [[SHAMT_WIDE1:%.*]] = zext i8 [[SHAMT:%.*]] to i32 +; CHECK-NEXT: [[N0:%.*]] = shl i32 [[X:%.*]], [[SHAMT_WIDE1]] +; CHECK-NEXT: [[SHAMT_WIDE2:%.*]] = zext i8 [[SHAMT]] to i32 +; CHECK-NEXT: [[R:%.*]] = ashr i32 [[N0]], [[SHAMT_WIDE2]] ; CHECK-NEXT: ret i32 [[R]] ; bb: @@ -141,7 +142,8 @@ ; CHECK-LABEL: @n11_extrause( ; CHECK-NEXT: [[SHAMT_WIDE:%.*]] = sext i8 [[SHAMT:%.*]] to i32 ; CHECK-NEXT: call void @use32(i32 [[SHAMT_WIDE]]) -; CHECK-NEXT: [[R:%.*]] = shl i32 [[X:%.*]], [[SHAMT_WIDE]] +; CHECK-NEXT: [[SHAMT_WIDE1:%.*]] = zext i8 [[SHAMT]] to i32 +; CHECK-NEXT: [[R:%.*]] = shl i32 [[X:%.*]], [[SHAMT_WIDE1]] ; CHECK-NEXT: ret i32 [[R]] ; %shamt_wide = sext i8 %shamt to i32 @@ -156,8 +158,10 @@ ; CHECK: work: ; CHECK-NEXT: br label [[END:%.*]] ; CHECK: end: -; CHECK-NEXT: [[N0:%.*]] = shl i32 [[X:%.*]], [[SHAMT_WIDE]] -; CHECK-NEXT: [[R:%.*]] = ashr i32 [[N0]], [[SHAMT_WIDE]] +; CHECK-NEXT: [[SHAMT_WIDE1:%.*]] = zext i8 [[SHAMT]] to i32 +; CHECK-NEXT: [[N0:%.*]] = shl i32 [[X:%.*]], [[SHAMT_WIDE1]] +; CHECK-NEXT: [[SHAMT_WIDE2:%.*]] = zext i8 [[SHAMT]] to i32 +; CHECK-NEXT: [[R:%.*]] = ashr i32 [[N0]], [[SHAMT_WIDE2]] ; CHECK-NEXT: call void @use32(i32 [[SHAMT_WIDE]]) ; CHECK-NEXT: ret i32 [[R]] ;