Chromium Code Reviews| Index: src/hydrogen-instructions.cc |
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
| index a685198ba6288e54e0913695f6e6f4e5cc797f09..ca5c02497fd04e4969027d364d4c1ca8951a92d7 100644 |
| --- a/src/hydrogen-instructions.cc |
| +++ b/src/hydrogen-instructions.cc |
| @@ -1237,6 +1237,19 @@ HValue* HMul::Canonicalize() { |
| } |
| +bool HMul::MulMinusOne() { |
| + ASSERT(left().IsSmiOrInteger32()); |
| + ASSERT(right().IsSmiOrInteger32()); |
| + |
| + if (left()->EqualsInteger32Constant(-1) || |
| + right()->EqualsInteger32Constant(-1)) { |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| + |
| HValue* HMod::Canonicalize() { |
| return this; |
| } |
| @@ -1622,10 +1635,13 @@ Range* HMul::InferRange(Zone* zone) { |
| Range* a = left()->range(); |
| Range* b = right()->range(); |
| Range* res = a->Copy(zone); |
| - if (!res->MulAndCheckOverflow(r, b)) { |
| - // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32 |
| - // would be wrong, because truncated integer multiplication is too |
| - // precise and therefore not the same as converting to Double and back. |
| + if (!res->MulAndCheckOverflow(r, b) || |
| + (((r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) || |
| + (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) && |
| + MulMinusOne())) { |
| + // Truncated int multiplication is too precise and therefore not the |
| + // same as converting to Double and back. |
| + // Special handle for truncated int multiplication with minus one. |
|
Toon Verwaest
2013/09/25 07:52:43
Handle truncated integer multiplication by -1 spec
weiliang.lin2
2013/09/25 08:02:45
Done.
|
| ClearFlag(kCanOverflow); |
| } |
| res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) && |
| @@ -1647,7 +1663,10 @@ Range* HDiv::InferRange(Zone* zone) { |
| result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
| (a->CanBeMinusZero() || |
| (a->CanBeZero() && b->CanBeNegative()))); |
| - if (!a->Includes(kMinInt) || !b->Includes(-1)) { |
| + if (!a->Includes(kMinInt) || |
| + !b->Includes(-1) || |
| + CheckFlag(kAllUsesTruncatingToInt32)) { |
| + // It is safe to clear kCanOverflow when kAllUsesTruncatingToInt32. |
| ClearFlag(HValue::kCanOverflow); |
| } |
| @@ -2620,6 +2639,12 @@ void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { |
| ASSERT(CheckFlag(kFlexibleRepresentation)); |
| Representation new_rep = RepresentationFromInputs(); |
| UpdateRepresentation(new_rep, h_infer, "inputs"); |
| + |
| + if (representation().IsSmi() && HasNonSmiUse()) { |
| + UpdateRepresentation( |
| + Representation::Integer32(), h_infer, "use requirements"); |
| + } |
| + |
| if (observed_output_representation_.IsNone()) { |
| new_rep = RepresentationFromUses(); |
| UpdateRepresentation(new_rep, h_infer, "uses"); |
| @@ -2627,11 +2652,6 @@ void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { |
| new_rep = RepresentationFromOutput(); |
| UpdateRepresentation(new_rep, h_infer, "output"); |
| } |
| - |
| - if (representation().IsSmi() && HasNonSmiUse()) { |
| - UpdateRepresentation( |
| - Representation::Integer32(), h_infer, "use requirements"); |
| - } |
| } |
| @@ -2657,8 +2677,9 @@ bool HBinaryOperation::IgnoreObservedOutputRepresentation( |
| Representation current_rep) { |
| return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) || |
| (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) && |
| - // Mul in Integer32 mode would be too precise. |
| - !this->IsMul(); |
| + // Mul in Integer32 mode would be too precise. |
| + (!this->IsMul() || |
|
Toon Verwaest
2013/09/25 07:52:43
nit: indent same as sibling expression (remove the
weiliang.lin2
2013/09/25 08:02:45
Done.
|
| + HMul::cast(this)->MulMinusOne()); |
| } |