From 63134966fda12fb4dfb51413d545aa0ea7c67db5 Mon Sep 17 00:00:00 2001 From: Qifan Pan Date: Wed, 4 Jan 2023 14:16:52 +0100 Subject: [PATCH] [turbofan] Fix a bug of SignedBigInt64 in representation changer The expected behavior of the optimized code is deoptimizing when using a BigInt as an index and throwing an error (from CheckedTaggedToInt64). The representation changer tries to insert conversions for this case where - The output node is represented in Word64 (SignedBigInt64) - The use info is CheckedSigned64AsWord64 The representation changer first rematerializes the output node to TaggedPointer because the type check is not BigInt. Then it falls wrongly to the branch where the output representation is TaggedPointer, the output type is SignedBigInt64 in GetWord64RepresentationFor. Bug: v8:9407, chromium:1403574, chromium:1404607 Change-Id: I9d7ef4c94c1dc0aa3b4f49871ec35ef0877efc24 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4135876 Reviewed-by: Nico Hartmann Commit-Queue: Qifan Pan Cr-Commit-Position: refs/heads/main@{#85094} --- src/compiler/representation-change.cc | 4 +--- .../compiler/test-representation-change.cc | 7 ------- test/mjsunit/regress/regress-1404607.js | 18 ++++++++++++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 test/mjsunit/regress/regress-1404607.js diff --git a/src/compiler/representation-change.cc b/src/compiler/representation-change.cc index 5182369fcf..32ff14f3bb 100644 --- a/src/compiler/representation-change.cc +++ b/src/compiler/representation-change.cc @@ -1249,9 +1249,7 @@ Node* RepresentationChanger::GetWord64RepresentationFor( ((use_info.truncation().IsUsedAsWord64() && (use_info.type_check() == TypeCheckKind::kBigInt || output_type.Is(Type::BigInt()))) || - (use_info.type_check() == TypeCheckKind::kBigInt64 || - output_type.Is(Type::SignedBigInt64()) || - output_type.Is(Type::UnsignedBigInt64())))) { + use_info.type_check() == TypeCheckKind::kBigInt64)) { node = GetTaggedPointerRepresentationFor(node, output_rep, output_type, use_node, use_info); op = simplified()->TruncateBigIntToWord64(); diff --git a/test/cctest/compiler/test-representation-change.cc b/test/cctest/compiler/test-representation-change.cc index a9fee37e14..b1e1d51d2a 100644 --- a/test/cctest/compiler/test-representation-change.cc +++ b/test/cctest/compiler/test-representation-change.cc @@ -530,13 +530,6 @@ TEST(Word64) { IrOpcode::kChangeInt64ToFloat64, IrOpcode::kChangeFloat64ToTaggedPointer, MachineRepresentation::kWord64, TypeCache::Get()->kSafeInteger, MachineRepresentation::kTaggedPointer); - - CheckChange(IrOpcode::kTruncateBigIntToWord64, - MachineRepresentation::kTaggedPointer, Type::SignedBigInt64(), - MachineRepresentation::kWord64); - CheckChange(IrOpcode::kTruncateBigIntToWord64, - MachineRepresentation::kTaggedPointer, Type::UnsignedBigInt64(), - MachineRepresentation::kWord64); } TEST(SingleChanges) { diff --git a/test/mjsunit/regress/regress-1404607.js b/test/mjsunit/regress/regress-1404607.js new file mode 100644 index 0000000000..8ced478320 --- /dev/null +++ b/test/mjsunit/regress/regress-1404607.js @@ -0,0 +1,18 @@ +// Copyright 2023 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 opt() { + const buffer = new ArrayBuffer(64); + const view = new DataView(buffer); + let i = 1n; + i += 1n; + view.setUint8(i); +} + +%PrepareFunctionForOptimization(opt); +assertThrows(opt, TypeError); +%OptimizeFunctionOnNextCall(opt); +assertThrows(opt, TypeError);