Commit b2b2583d authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[turbofan] lea32 must create zero-extended value

The instruction selector currently sometimes emits a lea32 with an
offset of 0, which the code generator just ignores (emits no code at
all). This can result in the result of TruncateInt64ToInt32 to not be
zero extended.
This CL fixes that by disallowing lea32 instructions with 0 offset, and
fixing the instruction selector to generate a movl or just no code for
that case.

R=jarin@chromium.org

Bug: chromium:863810, v8:7947
Change-Id: I1b21fc5f0fda9ca3144917538c3d0bbf46601c33
Reviewed-on: https://chromium-review.googlesource.com/1137825Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54489}
parent 55a348ce
......@@ -1958,9 +1958,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
if (i.InputRegister(0) == i.OutputRegister()) {
if (mode == kMode_MRI) {
int32_t constant_summand = i.InputInt32(1);
DCHECK_NE(0, constant_summand);
if (constant_summand > 0) {
__ addl(i.OutputRegister(), Immediate(constant_summand));
} else if (constant_summand < 0) {
} else {
__ subl(i.OutputRegister(), Immediate(-constant_summand));
}
} else if (mode == kMode_MR1) {
......
......@@ -838,7 +838,6 @@ void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
VisitBinop(this, node, kX64Add, &cont);
}
void InstructionSelector::VisitInt32Sub(Node* node) {
X64OperandGenerator g(this);
DCHECK_EQ(node->InputCount(), 2);
......@@ -846,31 +845,38 @@ void InstructionSelector::VisitInt32Sub(Node* node) {
Node* input2 = node->InputAt(1);
if (input1->opcode() == IrOpcode::kTruncateInt64ToInt32 &&
g.CanBeImmediate(input2)) {
int32_t imm = g.GetImmediateIntegerValue(input2);
InstructionOperand int64_input = g.UseRegister(input1->InputAt(0));
if (imm == 0) {
// Emit "movl" for subtraction of 0.
Emit(kX64Movl, g.DefineAsRegister(node), int64_input);
} else {
// Omit truncation and turn subtractions of constant values into immediate
// "leal" instructions by negating the value.
Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), g.UseRegister(input1->InputAt(0)),
g.TempImmediate(-g.GetImmediateIntegerValue(input2)));
g.DefineAsRegister(node), int64_input, g.TempImmediate(-imm));
}
return;
}
Int32BinopMatcher m(node);
if (m.left().Is(0)) {
Emit(kX64Neg32, g.DefineSameAsFirst(node), g.UseRegister(m.right().node()));
} else {
if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) {
} else if (m.right().Is(0)) {
// TODO(jarin): We should be able to use {EmitIdentity} here
// (https://crbug.com/v8/7947).
Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(m.left().node()));
} else if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) {
// Turn subtractions of constant values into immediate "leal" instructions
// by negating the value.
Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
g.TempImmediate(-m.right().Value()));
return;
}
} else {
VisitBinop(this, node, kX64Sub32);
}
}
void InstructionSelector::VisitInt64Sub(Node* node) {
X64OperandGenerator g(this);
Int64BinopMatcher m(node);
......
// 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: --no-liftoff --no-wasm-tier-up --no-future --debug-code
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_i_v)
.addBody([
kExprI64Const, 0xa3, 0x82, 0x83, 0x86, 0x8c, 0xd8, 0xae, 0xb5, 0x40,
kExprI32ConvertI64,
kExprI32Const, 0x00,
kExprI32Sub,
]).exportFunc();
const instance = builder.instantiate();
print(instance.exports.main(1, 2, 3));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment