Commit 42ac51c8 authored by ivica.bogosavljevic's avatar ivica.bogosavljevic Committed by Commit bot

Fix int64 lowering on big-endian architectures.

Lowering of Int64Load, Int64Store, BitcastInt64ToFloat64 and
BitcastFloat64ToInt64 was using LE word ordering in memory,
causing failures on some tests.

BUG=mjsunit/regress/regress-599719,mjsunit/regress/regress-599717

Review-Url: https://codereview.chromium.org/2080213004
Cr-Commit-Position: refs/heads/master@{#37213}
parent f5d90fc9
......@@ -100,6 +100,27 @@ static int GetReturnCountAfterLowering(
return result;
}
void Int64Lowering::GetIndexNodes(Node* index, Node*& index_low,
Node*& index_high) {
#if defined(V8_TARGET_LITTLE_ENDIAN)
index_low = index;
index_high = graph()->NewNode(machine()->Int32Add(), index,
graph()->NewNode(common()->Int32Constant(4)));
#elif defined(V8_TARGET_BIG_ENDIAN)
index_low = graph()->NewNode(machine()->Int32Add(), index,
graph()->NewNode(common()->Int32Constant(4)));
index_high = index;
#endif
}
#if defined(V8_TARGET_LITTLE_ENDIAN)
const int Int64Lowering::kLowerWordOffset = 0;
const int Int64Lowering::kHigherWordOffset = 4;
#elif defined(V8_TARGET_BIG_ENDIAN)
const int Int64Lowering::kLowerWordOffset = 4;
const int Int64Lowering::kHigherWordOffset = 0;
#endif
void Int64Lowering::LowerNode(Node* node) {
switch (node->opcode()) {
case IrOpcode::kInt64Constant: {
......@@ -117,10 +138,9 @@ void Int64Lowering::LowerNode(Node* node) {
if (load_rep.representation() == MachineRepresentation::kWord64) {
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
Node* index_high =
graph()->NewNode(machine()->Int32Add(), index,
graph()->NewNode(common()->Int32Constant(4)));
Node* index_low;
Node* index_high;
GetIndexNodes(index, index_low, index_high);
const Operator* load_op = machine()->Load(MachineType::Int32());
Node* high_node;
if (node->InputCount() > 2) {
......@@ -134,6 +154,7 @@ void Int64Lowering::LowerNode(Node* node) {
} else {
high_node = graph()->NewNode(load_op, base, index_high);
}
node->ReplaceInput(1, index_low);
NodeProperties::ChangeOp(node, load_op);
ReplaceNode(node, node, high_node);
} else {
......@@ -152,10 +173,9 @@ void Int64Lowering::LowerNode(Node* node) {
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
Node* index_high =
graph()->NewNode(machine()->Int32Add(), index,
graph()->NewNode(common()->Int32Constant(4)));
Node* index_low;
Node* index_high;
GetIndexNodes(index, index_low, index_high);
Node* value = node->InputAt(2);
DCHECK(HasReplacementLow(value));
DCHECK(HasReplacementHigh(value));
......@@ -177,6 +197,7 @@ void Int64Lowering::LowerNode(Node* node) {
GetReplacementHigh(value));
}
node->ReplaceInput(1, index_low);
node->ReplaceInput(2, GetReplacementLow(value));
NodeProperties::ChangeOp(node, store_op);
ReplaceNode(node, node, high_node);
......@@ -505,14 +526,16 @@ void Int64Lowering::LowerNode(Node* node) {
machine()->Store(
StoreRepresentation(MachineRepresentation::kWord32,
WriteBarrierKind::kNoWriteBarrier)),
stack_slot, graph()->NewNode(common()->Int32Constant(4)),
stack_slot,
graph()->NewNode(common()->Int32Constant(kHigherWordOffset)),
GetReplacementHigh(input), graph()->start(), graph()->start());
Node* store_low_word = graph()->NewNode(
machine()->Store(
StoreRepresentation(MachineRepresentation::kWord32,
WriteBarrierKind::kNoWriteBarrier)),
stack_slot, graph()->NewNode(common()->Int32Constant(0)),
stack_slot,
graph()->NewNode(common()->Int32Constant(kLowerWordOffset)),
GetReplacementLow(input), store_high_word, graph()->start());
Node* load =
......@@ -538,15 +561,15 @@ void Int64Lowering::LowerNode(Node* node) {
stack_slot, graph()->NewNode(common()->Int32Constant(0)), input,
graph()->start(), graph()->start());
Node* high_node =
graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot,
graph()->NewNode(common()->Int32Constant(4)), store,
graph()->start());
Node* high_node = graph()->NewNode(
machine()->Load(MachineType::Int32()), stack_slot,
graph()->NewNode(common()->Int32Constant(kHigherWordOffset)), store,
graph()->start());
Node* low_node =
graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot,
graph()->NewNode(common()->Int32Constant(0)), store,
graph()->start());
Node* low_node = graph()->NewNode(
machine()->Load(MachineType::Int32()), stack_slot,
graph()->NewNode(common()->Int32Constant(kLowerWordOffset)), store,
graph()->start());
ReplaceNode(node, low_node, high_node);
break;
}
......
......@@ -26,6 +26,9 @@ class Int64Lowering {
static int GetParameterCountAfterLowering(
Signature<MachineRepresentation>* signature);
static const int kLowerWordOffset;
static const int kHigherWordOffset;
private:
enum class State : uint8_t { kUnvisited, kOnStack, kVisited };
......@@ -54,6 +57,7 @@ class Int64Lowering {
bool HasReplacementHigh(Node* node);
Node* GetReplacementHigh(Node* node);
void PreparePhiReplacement(Node* phi);
void GetIndexNodes(Node* index, Node*& index_low, Node*& index_high);
struct NodeState {
Node* node;
......
......@@ -423,8 +423,6 @@
'asm/sqlite3/*': [SKIP],
# TODO(mips-team): Fix Wasm for big-endian.
'wasm/*': [SKIP],
'regress/regress-599717': [SKIP],
'regress/regress-599719': [SKIP],
}], # 'byteorder == big'
##############################################################################
......
......@@ -133,6 +133,7 @@ TEST_F(Int64LoweringTest, Int64Load) {
MachineRepresentation::kWord64);
Capture<Node*> high_word_load;
#if defined(V8_TARGET_LITTLE_ENDIAN)
Matcher<Node*> high_word_load_matcher =
IsLoad(MachineType::Int32(), IsInt32Constant(base),
IsInt32Add(IsInt32Constant(index), IsInt32Constant(0x4)), start(),
......@@ -146,6 +147,21 @@ TEST_F(Int64LoweringTest, Int64Load) {
start()),
AllOf(CaptureEq(&high_word_load), high_word_load_matcher),
start(), start()));
#elif defined(V8_TARGET_BIG_ENDIAN)
Matcher<Node*> high_word_load_matcher =
IsLoad(MachineType::Int32(), IsInt32Constant(base),
IsInt32Constant(index), start(), start());
EXPECT_THAT(
graph()->end()->InputAt(1),
IsReturn2(
IsLoad(MachineType::Int32(), IsInt32Constant(base),
IsInt32Add(IsInt32Constant(index), IsInt32Constant(0x4)),
AllOf(CaptureEq(&high_word_load), high_word_load_matcher),
start()),
AllOf(CaptureEq(&high_word_load), high_word_load_matcher), start(),
start()));
#endif
}
TEST_F(Int64LoweringTest, Int64Store) {
......@@ -177,6 +193,7 @@ TEST_F(Int64LoweringTest, Int64Store) {
const StoreRepresentation rep(MachineRepresentation::kWord32,
kNoWriteBarrier);
#if defined(V8_TARGET_LITTLE_ENDIAN)
EXPECT_THAT(
graph()->end()->InputAt(1),
IsReturn(
......@@ -189,6 +206,20 @@ TEST_F(Int64LoweringTest, Int64Store) {
IsInt32Constant(high_word_value(0)), start(), start()),
start()),
start()));
#elif defined(V8_TARGET_BIG_ENDIAN)
EXPECT_THAT(
graph()->end()->InputAt(1),
IsReturn(
IsInt32Constant(return_value),
IsStore(
rep, IsInt32Constant(base),
IsInt32Add(IsInt32Constant(index), IsInt32Constant(4)),
IsInt32Constant(low_word_value(0)),
IsStore(rep, IsInt32Constant(base), IsInt32Constant(index),
IsInt32Constant(high_word_value(0)), start(), start()),
start()),
start()));
#endif
}
TEST_F(Int64LoweringTest, Int64And) {
......@@ -526,12 +557,13 @@ TEST_F(Int64LoweringTest, F64ReinterpretI64) {
IsStore(StoreRepresentation(MachineRepresentation::kWord32,
WriteBarrierKind::kNoWriteBarrier),
AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
IsInt32Constant(0), IsInt32Constant(low_word_value(0)),
IsInt32Constant(Int64Lowering::kLowerWordOffset),
IsInt32Constant(low_word_value(0)),
IsStore(StoreRepresentation(MachineRepresentation::kWord32,
WriteBarrierKind::kNoWriteBarrier),
AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
IsInt32Constant(4), IsInt32Constant(high_word_value(0)),
start(), start()),
IsInt32Constant(Int64Lowering::kHigherWordOffset),
IsInt32Constant(high_word_value(0)), start(), start()),
start());
EXPECT_THAT(
......@@ -563,11 +595,11 @@ TEST_F(Int64LoweringTest, I64ReinterpretF64) {
graph()->end()->InputAt(1),
IsReturn2(IsLoad(MachineType::Int32(),
AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
IsInt32Constant(0),
IsInt32Constant(Int64Lowering::kLowerWordOffset),
AllOf(CaptureEq(&store), store_matcher), start()),
IsLoad(MachineType::Int32(),
AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
IsInt32Constant(0x4),
IsInt32Constant(Int64Lowering::kHigherWordOffset),
AllOf(CaptureEq(&store), store_matcher), start()),
start(), start()));
}
......
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