From 5c4267d52fa5227eeeaf3cc7c54281afc78f429c Mon Sep 17 00:00:00 2001 From: Qifan Pan Date: Fri, 12 Aug 2022 15:02:26 +0200 Subject: [PATCH] [turbofan] Lower BigInt multiply with truncation information Bug: v8:9407 Change-Id: Id4ca4682d3fe4b2222a656c80dff95e5c099d5ed Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3822671 Reviewed-by: Nico Hartmann Commit-Queue: Qifan Pan Cr-Commit-Position: refs/heads/main@{#82524} --- src/compiler/simplified-lowering.cc | 19 +++++++++---- .../compiler/bigint-multiply-truncate.js | 28 +++++++++++++++++++ test/mjsunit/compiler/bigint-multiply.js | 8 +++--- test/mjsunit/mjsunit.status | 5 +++- 4 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 test/mjsunit/compiler/bigint-multiply-truncate.js diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc index 694295ed50..55ac7ad6c0 100644 --- a/src/compiler/simplified-lowering.cc +++ b/src/compiler/simplified-lowering.cc @@ -3225,11 +3225,20 @@ class RepresentationSelector { return; } case IrOpcode::kSpeculativeBigIntMultiply: { - VisitBinop(node, - UseInfo::CheckedBigIntAsTaggedPointer(FeedbackSource{}), - MachineRepresentation::kTaggedPointer); - if (lower()) { - ChangeOp(node, lowering->simplified()->BigIntMultiply()); + if (truncation.IsUsedAsWord64()) { + VisitBinop( + node, UseInfo::CheckedBigIntTruncatingWord64(FeedbackSource{}), + MachineRepresentation::kWord64); + if (lower()) { + ChangeToPureOp(node, lowering->machine()->Int64Mul()); + } + } else { + VisitBinop(node, + UseInfo::CheckedBigIntAsTaggedPointer(FeedbackSource{}), + MachineRepresentation::kTaggedPointer); + if (lower()) { + ChangeOp(node, lowering->simplified()->BigIntMultiply()); + } } return; } diff --git a/test/mjsunit/compiler/bigint-multiply-truncate.js b/test/mjsunit/compiler/bigint-multiply-truncate.js new file mode 100644 index 0000000000..6f25571591 --- /dev/null +++ b/test/mjsunit/compiler/bigint-multiply-truncate.js @@ -0,0 +1,28 @@ +// Copyright 2022 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 --turbofan --no-always-turbofan + +function TestMultiplyAndTruncate(a, b) { + return BigInt.asIntN(3, a * b); +} + +function OptimizeAndTest(fn) { + let bi = 2n ** (2n ** 29n); + // Before optimization, a BigIntTooBig exception is expected + assertThrows(() => fn(bi + 3n, bi + 4n), RangeError); + if (%Is64Bit()) { + %PrepareFunctionForOptimization(fn); + assertEquals(-4n, fn(3n, 4n)); + assertEquals(-2n, fn(5n, 6n)); + %OptimizeFunctionOnNextCall(fn); + // After optimization, operands are truncated to Word64 + // before being multiplied. No exceptions should be thrown + // and the correct result is expected. + assertEquals(-4n, fn(bi + 3n, bi + 4n)); + assertOptimized(fn); + } +} + +OptimizeAndTest(TestMultiplyAndTruncate); diff --git a/test/mjsunit/compiler/bigint-multiply.js b/test/mjsunit/compiler/bigint-multiply.js index df6357f906..f56fa53c22 100644 --- a/test/mjsunit/compiler/bigint-multiply.js +++ b/test/mjsunit/compiler/bigint-multiply.js @@ -10,12 +10,12 @@ function TestMultiply(a, b) { function OptimizeAndTest(fn) { %PrepareFunctionForOptimization(fn); - assertEquals(fn(3n, 4n), 12n); - assertEquals(fn(5n, 6n), 30n); + assertEquals(12n, fn(3n, 4n)); + assertEquals(30n, fn(5n, 6n)); %OptimizeFunctionOnNextCall(fn); - assertEquals(fn(7n, 8n), 56n); + assertEquals(56n, fn(7n, 8n)); assertOptimized(fn); - assertEquals(fn(7, 8), 56); + assertEquals(56, fn(7, 8)); assertUnoptimized(fn); } diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status index 49d9f4b24b..4ebb1311f0 100644 --- a/test/mjsunit/mjsunit.status +++ b/test/mjsunit/mjsunit.status @@ -1361,7 +1361,10 @@ # which in turn can lead to different deopt behavior. 'compiler/number-abs': [SKIP], 'compiler/number-toboolean': [SKIP], - 'wasm/bigint-opt': [SKIP], + # Type assertions block the propagation of word64 truncation useinfo, + # leading to differences in representation selection. + 'compiler/bigint-multiply-truncate': [SKIP], + 'wasm/bigint-opt': [SKIP] }], # variant == assert_types ##############################################################################