| Index: src/arm/lithium-arm.cc
|
| diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
|
| index 17f3325b754c3449f682425313062cf438c8d581..73f377bf365d1e5250390917bbd27dae469088c5 100644
|
| --- a/src/arm/lithium-arm.cc
|
| +++ b/src/arm/lithium-arm.cc
|
| @@ -1303,8 +1303,21 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
|
| return DefineAsRegister(mul);
|
|
|
| } else if (instr->representation().IsDouble()) {
|
| - return DoArithmeticD(Token::MUL, instr);
|
| + if (instr->UseCount() == 1 && instr->uses().value()->IsAdd()) {
|
| + HAdd* add = HAdd::cast(instr->uses().value());
|
| + if (instr == add->left()) {
|
| + // This mul is the lhs of an add. The add and mul will be folded
|
| + // into a multiply-add.
|
| + return NULL;
|
| + }
|
| + if (instr == add->right() && !add->left()->IsMul()) {
|
| + // This mul is the rhs of an add, where the lhs is not another mul.
|
| + // The add and mul will be folded into a multiply-add.
|
| + return NULL;
|
| + }
|
| + }
|
|
|
| + return DoArithmeticD(Token::MUL, instr);
|
| } else {
|
| return DoArithmeticT(Token::MUL, instr);
|
| }
|
| @@ -1330,6 +1343,13 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) {
|
| }
|
| }
|
|
|
| +LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) {
|
| + LOperand* multiplier_op = UseRegisterAtStart(mul->left());
|
| + LOperand* multiplicand_op = UseRegisterAtStart(mul->right());
|
| + LOperand* addend_op = UseRegisterAtStart(addend);
|
| + return DefineSameAsFirst(new(zone()) LMultiplyAddD(addend_op, multiplier_op,
|
| + multiplicand_op));
|
| +}
|
|
|
| LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
|
| if (instr->representation().IsInteger32()) {
|
| @@ -1344,6 +1364,14 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
|
| }
|
| return result;
|
| } else if (instr->representation().IsDouble()) {
|
| + if (instr->left()->IsMul())
|
| + return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
|
| +
|
| + if (instr->right()->IsMul()) {
|
| + ASSERT(!instr->left()->IsMul());
|
| + return DoMultiplyAdd(HMul::cast(instr->right()), instr->left());
|
| + }
|
| +
|
| return DoArithmeticD(Token::ADD, instr);
|
| } else {
|
| ASSERT(instr->representation().IsTagged());
|
|
|