Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(358)

Unified Diff: test/unittests/compiler/arm/instruction-selector-arm-unittest.cc

Issue 1883133002: [turbofan] ARM: elide masks on loads and stores (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase on master's machine-operator-reducer changes Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/arm/instruction-selector-arm.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
diff --git a/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
index b088d8e76ec12afbefbb01cafdf47fc72bbf79a7..4dc01657464341b3f7347afd2406bf21c9c38bbc 100644
--- a/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
+++ b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
@@ -1398,6 +1398,68 @@ TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
}
}
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithWord32And0xff) {
+ const MemoryAccess mem = GetParam();
+ if (!(mem.type == MachineType::Float32() ||
+ mem.type == MachineType::Float64())) {
+ {
+ StreamBuilder m(this, mem.type, MachineType::Pointer(),
+ MachineType::Int32());
+ m.Return(m.Word32And(m.Int32Constant(0xff),
+ m.Load(mem.type, m.Parameter(0), m.Parameter(1))));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmLdrb, s[0]->arch_opcode());
+ EXPECT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ {
+ StreamBuilder m(this, mem.type, MachineType::Pointer(),
+ MachineType::Int32());
+ m.Return(m.Word32And(m.Load(mem.type, m.Parameter(0), m.Parameter(1)),
+ m.Int32Constant(0xff)));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArmLdrb, s[0]->arch_opcode());
+ EXPECT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ }
+}
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithWord32And0xffff) {
+ const MemoryAccess mem = GetParam();
+ MachineRepresentation load_rep = mem.type.representation();
+ if (!(mem.type == MachineType::Float32() ||
+ mem.type == MachineType::Float64())) {
+ {
+ StreamBuilder m(this, mem.type, MachineType::Pointer(),
+ MachineType::Int32());
+ m.Return(m.Word32And(m.Int32Constant(0xffff),
+ m.Load(mem.type, m.Parameter(0), m.Parameter(1))));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(
+ (load_rep == MachineRepresentation::kWord8) ? kArmLdrb : kArmLdrh,
+ s[0]->arch_opcode());
+ EXPECT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ {
+ StreamBuilder m(this, mem.type, MachineType::Pointer(),
+ MachineType::Int32());
+ m.Return(m.Word32And(m.Load(mem.type, m.Parameter(0), m.Parameter(1)),
+ m.Int32Constant(0xffff)));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(
+ (load_rep == MachineRepresentation::kWord8) ? kArmLdrb : kArmLdrh,
+ s[0]->arch_opcode());
+ EXPECT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ }
+ }
+}
INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
InstructionSelectorMemoryAccessTest,
@@ -2939,6 +3001,152 @@ TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrAnd0xffff) {
}
}
+TEST_F(InstructionSelectorTest, LoadWordWithWord32And) {
+ TRACED_FORRANGE(int32_t, shift, 0, 15) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ uint32_t mask = 0x12340000 | (1 << shift);
+ Node* const r = m.Word32And(
+ m.Load(MachineType::Uint16(), m.Parameter(0), m.Parameter(1)),
+ m.Int32Constant(mask));
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArmLdrh, s[0]->arch_opcode());
+ EXPECT_EQ(kArmAnd, s[1]->arch_opcode());
+ ASSERT_EQ(2U, s[1]->InputCount());
+ EXPECT_EQ(mask & 0xffff, s.ToInt32(s[1]->InputAt(1)));
+ }
+ TRACED_FORRANGE(int32_t, shift, 0, 15) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ uint32_t mask = 0x12340000 | (1 << shift);
+ Node* const r = m.Word32And(
+ m.Int32Constant(mask),
+ m.Load(MachineType::Uint16(), m.Parameter(0), m.Parameter(1)));
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArmLdrh, s[0]->arch_opcode());
+ EXPECT_EQ(kArmAnd, s[1]->arch_opcode());
+ ASSERT_EQ(2U, s[1]->InputCount());
+ EXPECT_EQ(mask & 0xffff, s.ToInt32(s[1]->InputAt(1)));
+ }
+ TRACED_FORRANGE(int32_t, shift, 0, 7) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ uint32_t mask = 0x12345600 | (1 << shift);
+ Node* const r = m.Word32And(
+ m.Int32Constant(mask),
+ m.Load(MachineType::Uint8(), m.Parameter(0), m.Parameter(1)));
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArmLdrb, s[0]->arch_opcode());
+ EXPECT_EQ(kArmAnd, s[1]->arch_opcode());
+ ASSERT_EQ(2U, s[1]->InputCount());
+ EXPECT_EQ(mask & 0xff, s.ToInt32(s[1]->InputAt(1)));
+ }
+}
+
+TEST_F(InstructionSelectorTest, LoadWord16WithWord32Bic) {
+ TRACED_FORRANGE(int32_t, shift, 0, 15) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ uint32_t mask = 0x12340000 | (0xffff & ~(1 << shift));
+ Node* const r = m.Word32And(
+ m.Load(MachineType::Uint16(), m.Parameter(0), m.Parameter(1)),
+ m.Int32Constant(mask));
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArmLdrh, s[0]->arch_opcode());
+ EXPECT_EQ(kArmBic, s[1]->arch_opcode());
+ ASSERT_EQ(2U, s[1]->InputCount());
+ EXPECT_EQ(~mask & 0xffff, s.ToInt32(s[1]->InputAt(1)));
+ }
+ TRACED_FORRANGE(int32_t, shift, 0, 15) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ uint32_t mask = 0x12340000 | (0xffff & ~(1 << shift));
+ Node* const r = m.Word32And(
+ m.Int32Constant(mask),
+ m.Load(MachineType::Uint16(), m.Parameter(0), m.Parameter(1)));
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArmLdrh, s[0]->arch_opcode());
+ EXPECT_EQ(kArmBic, s[1]->arch_opcode());
+ ASSERT_EQ(2U, s[1]->InputCount());
+ EXPECT_EQ(~mask & 0xffff, s.ToInt32(s[1]->InputAt(1)));
+ }
+}
+
+TEST_F(InstructionSelectorTest, StoreWord16WithWord32And) {
+ TRACED_FORRANGE(int32_t, shift, 0, 15) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ uint32_t mask = 0x12340000 | (1 << shift);
+ Node* const r = m.Store(MachineRepresentation::kWord16, m.Parameter(0),
+ m.Word32And(m.Parameter(1), m.Int32Constant(mask)),
+ kNoWriteBarrier);
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArmAnd, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(mask & 0xffff, s.ToInt32(s[0]->InputAt(1)));
+ EXPECT_EQ(kArmStrh, s[1]->arch_opcode());
+ }
+ TRACED_FORRANGE(int32_t, shift, 0, 15) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ uint32_t mask = 0x12340000 | (1 << shift);
+ Node* const r = m.Store(MachineRepresentation::kWord16, m.Parameter(0),
+ m.Word32And(m.Int32Constant(mask), m.Parameter(1)),
+ kNoWriteBarrier);
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArmAnd, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(mask & 0xffff, s.ToInt32(s[0]->InputAt(1)));
+ EXPECT_EQ(kArmStrh, s[1]->arch_opcode());
+ }
+}
+
+TEST_F(InstructionSelectorTest, StoreWord16WithWord32Bic) {
+ TRACED_FORRANGE(int32_t, shift, 0, 15) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ uint32_t mask = 0x12340000 | (0xffff & ~(1 << shift));
+ Node* const r = m.Store(MachineRepresentation::kWord16, m.Parameter(0),
+ m.Word32And(m.Parameter(1), m.Int32Constant(mask)),
+ kNoWriteBarrier);
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArmBic, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(~mask & 0xffff, s.ToInt32(s[0]->InputAt(1)));
+ EXPECT_EQ(kArmStrh, s[1]->arch_opcode());
+ }
+ TRACED_FORRANGE(int32_t, shift, 0, 15) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Int32());
+ uint32_t mask = 0x12340000 | (0xffff & ~(1 << shift));
+ Node* const r = m.Store(MachineRepresentation::kWord16, m.Parameter(0),
+ m.Word32And(m.Int32Constant(mask), m.Parameter(1)),
+ kNoWriteBarrier);
+ m.Return(r);
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArmBic, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(~mask & 0xffff, s.ToInt32(s[0]->InputAt(1)));
+ EXPECT_EQ(kArmStrh, s[1]->arch_opcode());
+ }
+}
TEST_F(InstructionSelectorTest, Word32Clz) {
StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32());
« no previous file with comments | « src/compiler/arm/instruction-selector-arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698