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 @@ -972,7 +972,10 @@ return BinaryOperator::CreateShl(ConstantExpr::getShl(C2, C1), X); // (X * C2) << C1 --> X * (C2 << C1) - if (match(Op0, m_Mul(m_Value(X), m_Constant(C2)))) + // The one-use check is not strictly necessary, but codegen may not be + // able to invert the transform and perf may suffer with an extra mul + // instruction. + if (match(Op0, m_OneUse(m_Mul(m_Value(X), m_Constant(C2))))) return BinaryOperator::CreateMul(X, ConstantExpr::getShl(C2, C1)); // shl (zext i1 X), C1 --> select (X, 1 << C1, 0) diff --git a/llvm/test/Transforms/InstCombine/apint-shift.ll b/llvm/test/Transforms/InstCombine/apint-shift.ll --- a/llvm/test/Transforms/InstCombine/apint-shift.ll +++ b/llvm/test/Transforms/InstCombine/apint-shift.ll @@ -28,7 +28,7 @@ define i55 @test6a_negative_oneuse(i55 %A) { ; CHECK-LABEL: @test6a_negative_oneuse( ; CHECK-NEXT: [[B:%.*]] = mul i55 [[A:%.*]], 3 -; CHECK-NEXT: [[C:%.*]] = mul i55 [[A]], 6 +; CHECK-NEXT: [[C:%.*]] = shl i55 [[B]], 1 ; CHECK-NEXT: call void @use(i55 [[B]]) ; CHECK-NEXT: ret i55 [[C]] ;