diff --git a/src/compiler/representation-change.cc b/src/compiler/representation-change.cc index 5ea7959070..1a07887288 100644 --- a/src/compiler/representation-change.cc +++ b/src/compiler/representation-change.cc @@ -810,19 +810,17 @@ Node* RepresentationChanger::GetWord32RepresentationFor( MachineRepresentation::kWord32); } } else if (output_rep == MachineRepresentation::kWord32) { - if (use_info.truncation().IdentifiesZeroAndMinusZero()) { - if (output_type.Is(Type::Signed32OrMinusZero()) || - output_type.Is(Type::Unsigned32OrMinusZero())) { - return node; - } - } // Only the checked case should get here, the non-checked case is // handled in GetRepresentationFor. if (use_info.type_check() == TypeCheckKind::kSignedSmall || use_info.type_check() == TypeCheckKind::kSigned32) { - if (output_type.Is(Type::Signed32())) { + bool indentify_zeros = use_info.truncation().IdentifiesZeroAndMinusZero(); + if (output_type.Is(Type::Signed32()) || + (indentify_zeros && output_type.Is(Type::Signed32OrMinusZero()))) { return node; - } else if (output_type.Is(Type::Unsigned32())) { + } else if (output_type.Is(Type::Unsigned32()) || + (indentify_zeros && + output_type.Is(Type::Unsigned32OrMinusZero()))) { op = simplified()->CheckedUint32ToInt32(use_info.feedback()); } else { return TypeError(node, output_rep, output_type, diff --git a/test/cctest/compiler/test-representation-change.cc b/test/cctest/compiler/test-representation-change.cc index 82fd10b946..064c0eea9d 100644 --- a/test/cctest/compiler/test-representation-change.cc +++ b/test/cctest/compiler/test-representation-change.cc @@ -615,6 +615,11 @@ TEST(SignednessInWord32) { IrOpcode::kTruncateFloat64ToWord32, MachineRepresentation::kFloat32, Type::Number(), MachineRepresentation::kWord32); + + CheckChange( + IrOpcode::kCheckedUint32ToInt32, MachineRepresentation::kWord32, + Type::Unsigned32(), + UseInfo::CheckedSigned32AsWord32(kIdentifyZeros, VectorSlotPair())); } static void TestMinusZeroCheck(IrOpcode::Value expected, Type from_type) { diff --git a/test/mjsunit/regress/regress-901798.js b/test/mjsunit/regress/regress-901798.js new file mode 100644 index 0000000000..67022a70e8 --- /dev/null +++ b/test/mjsunit/regress/regress-901798.js @@ -0,0 +1,14 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +function f(a) { + return (a >>> 1073741824) + -3; +} + +assertEquals(-3, f(0)); +assertEquals(-2, f(1)); +%OptimizeFunctionOnNextCall(f); +assertEquals(4294967291, f(-2));