Index: lib/Transforms/Scalar/Reassociate.cpp =================================================================== --- lib/Transforms/Scalar/Reassociate.cpp +++ lib/Transforms/Scalar/Reassociate.cpp @@ -1978,11 +1978,12 @@ if (I->getOpcode() == Instruction::Shl && isa(I->getOperand(1))) // If an operand of this shift is a reassociable multiply, or if the shift - // is used by a reassociable multiply or add, turn into a multiply. + // is used by a reassociable multiply, add or negate, turn into a multiply. if (isReassociableOp(I->getOperand(0), Instruction::Mul) || (I->hasOneUse() && (isReassociableOp(I->user_back(), Instruction::Mul) || - isReassociableOp(I->user_back(), Instruction::Add)))) { + isReassociableOp(I->user_back(), Instruction::Add) || + BinaryOperator::isNeg(I->user_back())))) { Instruction *NI = ConvertShiftToMul(I); RedoInsts.insert(I); MadeChange = true; Index: test/Transforms/Reassociate/basictest.ll =================================================================== --- test/Transforms/Reassociate/basictest.ll +++ test/Transforms/Reassociate/basictest.ll @@ -222,3 +222,18 @@ ; CHECK-LABEL: @test15 ; CHECK: and i1 %A, %B } + +; -(a << 1)*2 + b --> -4a + b +define i32 @test16(i1 %cmp, i32 %a, i32 %b) { +entry: + %shl = shl i32 %a, 1 + %shl.neg = sub i32 0, %shl + %add1 = mul i32 %shl.neg, 2 + %add2 = add i32 %add1, %b + ret i32 %add2 + +; CHECK-LABEL: @test16 +; CHECK: %[[MUL:.*]] = mul i32 %a, -4 +; CHECK: %[[ADD:.*]] = add i32 %[[MUL]], %b +; CHECK: ret i32 %[[ADD]] +}