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()); |