OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
6 | 6 |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 m.Return(m.ChangeUint32ToUint64((m.*bop.constructor)(p0, p1))); | 234 m.Return(m.ChangeUint32ToUint64((m.*bop.constructor)(p0, p1))); |
235 Stream s = m.Build(); | 235 Stream s = m.Build(); |
236 ASSERT_EQ(1U, s.size()); | 236 ASSERT_EQ(1U, s.size()); |
237 } | 237 } |
238 | 238 |
239 | 239 |
240 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 240 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
241 InstructionSelectorChangeUint32ToUint64Test, | 241 InstructionSelectorChangeUint32ToUint64Test, |
242 ::testing::ValuesIn(kWord32BinaryOperations)); | 242 ::testing::ValuesIn(kWord32BinaryOperations)); |
243 | 243 |
| 244 // ----------------------------------------------------------------------------- |
| 245 // CanElideChangeUint32ToUint64 |
| 246 |
| 247 namespace { |
| 248 |
| 249 template <typename T> |
| 250 struct MachInst { |
| 251 T constructor; |
| 252 const char* constructor_name; |
| 253 ArchOpcode arch_opcode; |
| 254 MachineType machine_type; |
| 255 }; |
| 256 |
| 257 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2; |
| 258 |
| 259 // X64 instructions that clear the top 32 bits of the destination. |
| 260 const MachInst2 kCanElideChangeUint32ToUint64[] = { |
| 261 {&RawMachineAssembler::Word32And, "Word32And", kX64And32, |
| 262 MachineType::Uint32()}, |
| 263 {&RawMachineAssembler::Word32Or, "Word32Or", kX64Or32, |
| 264 MachineType::Uint32()}, |
| 265 {&RawMachineAssembler::Word32Xor, "Word32Xor", kX64Xor32, |
| 266 MachineType::Uint32()}, |
| 267 {&RawMachineAssembler::Word32Shl, "Word32Shl", kX64Shl32, |
| 268 MachineType::Uint32()}, |
| 269 {&RawMachineAssembler::Word32Shr, "Word32Shr", kX64Shr32, |
| 270 MachineType::Uint32()}, |
| 271 {&RawMachineAssembler::Word32Sar, "Word32Sar", kX64Sar32, |
| 272 MachineType::Uint32()}, |
| 273 {&RawMachineAssembler::Word32Ror, "Word32Ror", kX64Ror32, |
| 274 MachineType::Uint32()}, |
| 275 {&RawMachineAssembler::Word32Equal, "Word32Equal", kX64Cmp32, |
| 276 MachineType::Uint32()}, |
| 277 {&RawMachineAssembler::Int32Add, "Int32Add", kX64Lea32, |
| 278 MachineType::Int32()}, |
| 279 {&RawMachineAssembler::Int32Sub, "Int32Sub", kX64Sub32, |
| 280 MachineType::Int32()}, |
| 281 {&RawMachineAssembler::Int32Mul, "Int32Mul", kX64Imul32, |
| 282 MachineType::Int32()}, |
| 283 {&RawMachineAssembler::Int32MulHigh, "Int32MulHigh", kX64ImulHigh32, |
| 284 MachineType::Int32()}, |
| 285 {&RawMachineAssembler::Int32Div, "Int32Div", kX64Idiv32, |
| 286 MachineType::Int32()}, |
| 287 {&RawMachineAssembler::Int32LessThan, "Int32LessThan", kX64Cmp32, |
| 288 MachineType::Int32()}, |
| 289 {&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", |
| 290 kX64Cmp32, MachineType::Int32()}, |
| 291 {&RawMachineAssembler::Int32Mod, "Int32Mod", kX64Idiv32, |
| 292 MachineType::Int32()}, |
| 293 {&RawMachineAssembler::Uint32Div, "Uint32Div", kX64Udiv32, |
| 294 MachineType::Uint32()}, |
| 295 {&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kX64Cmp32, |
| 296 MachineType::Uint32()}, |
| 297 {&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", |
| 298 kX64Cmp32, MachineType::Uint32()}, |
| 299 {&RawMachineAssembler::Uint32Mod, "Uint32Mod", kX64Udiv32, |
| 300 MachineType::Uint32()}, |
| 301 }; |
| 302 |
| 303 } // namespace |
| 304 |
| 305 typedef InstructionSelectorTestWithParam<MachInst2> |
| 306 InstructionSelectorElidedChangeUint32ToUint64Test; |
| 307 |
| 308 TEST_P(InstructionSelectorElidedChangeUint32ToUint64Test, Parameter) { |
| 309 const MachInst2 binop = GetParam(); |
| 310 StreamBuilder m(this, MachineType::Uint64(), binop.machine_type, |
| 311 binop.machine_type); |
| 312 m.Return(m.ChangeUint32ToUint64( |
| 313 (m.*binop.constructor)(m.Parameter(0), m.Parameter(1)))); |
| 314 Stream s = m.Build(); |
| 315 // Make sure the `ChangeUint32ToUint64` node turned into a no-op. |
| 316 ASSERT_EQ(1U, s.size()); |
| 317 EXPECT_EQ(binop.arch_opcode, s[0]->arch_opcode()); |
| 318 EXPECT_EQ(2U, s[0]->InputCount()); |
| 319 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 320 } |
| 321 |
| 322 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 323 InstructionSelectorElidedChangeUint32ToUint64Test, |
| 324 ::testing::ValuesIn(kCanElideChangeUint32ToUint64)); |
| 325 |
| 326 // ChangeUint32ToUint64AfterLoad |
| 327 TEST_F(InstructionSelectorTest, ChangeUint32ToUint64AfterLoad) { |
| 328 // For each case, make sure the `ChangeUint32ToUint64` node turned into a |
| 329 // no-op. |
| 330 |
| 331 // movzxbl |
| 332 { |
| 333 StreamBuilder m(this, MachineType::Uint64(), MachineType::Pointer(), |
| 334 MachineType::Int32()); |
| 335 m.Return(m.ChangeUint32ToUint64( |
| 336 m.Load(MachineType::Uint8(), m.Parameter(0), m.Parameter(1)))); |
| 337 Stream s = m.Build(); |
| 338 ASSERT_EQ(1U, s.size()); |
| 339 EXPECT_EQ(kX64Movzxbl, s[0]->arch_opcode()); |
| 340 EXPECT_EQ(kMode_MR1, s[0]->addressing_mode()); |
| 341 EXPECT_EQ(2U, s[0]->InputCount()); |
| 342 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 343 } |
| 344 // movsxbl |
| 345 { |
| 346 StreamBuilder m(this, MachineType::Uint64(), MachineType::Pointer(), |
| 347 MachineType::Int32()); |
| 348 m.Return(m.ChangeUint32ToUint64( |
| 349 m.Load(MachineType::Int8(), m.Parameter(0), m.Parameter(1)))); |
| 350 Stream s = m.Build(); |
| 351 ASSERT_EQ(1U, s.size()); |
| 352 EXPECT_EQ(kX64Movsxbl, s[0]->arch_opcode()); |
| 353 EXPECT_EQ(kMode_MR1, s[0]->addressing_mode()); |
| 354 EXPECT_EQ(2U, s[0]->InputCount()); |
| 355 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 356 } |
| 357 // movzxwl |
| 358 { |
| 359 StreamBuilder m(this, MachineType::Uint64(), MachineType::Pointer(), |
| 360 MachineType::Int32()); |
| 361 m.Return(m.ChangeUint32ToUint64( |
| 362 m.Load(MachineType::Uint16(), m.Parameter(0), m.Parameter(1)))); |
| 363 Stream s = m.Build(); |
| 364 ASSERT_EQ(1U, s.size()); |
| 365 EXPECT_EQ(kX64Movzxwl, s[0]->arch_opcode()); |
| 366 EXPECT_EQ(kMode_MR1, s[0]->addressing_mode()); |
| 367 EXPECT_EQ(2U, s[0]->InputCount()); |
| 368 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 369 } |
| 370 // movsxwl |
| 371 { |
| 372 StreamBuilder m(this, MachineType::Uint64(), MachineType::Pointer(), |
| 373 MachineType::Int32()); |
| 374 m.Return(m.ChangeUint32ToUint64( |
| 375 m.Load(MachineType::Int16(), m.Parameter(0), m.Parameter(1)))); |
| 376 Stream s = m.Build(); |
| 377 ASSERT_EQ(1U, s.size()); |
| 378 EXPECT_EQ(kX64Movsxwl, s[0]->arch_opcode()); |
| 379 EXPECT_EQ(kMode_MR1, s[0]->addressing_mode()); |
| 380 EXPECT_EQ(2U, s[0]->InputCount()); |
| 381 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 382 } |
| 383 } |
244 | 384 |
245 // ----------------------------------------------------------------------------- | 385 // ----------------------------------------------------------------------------- |
246 // TruncateInt64ToInt32. | 386 // TruncateInt64ToInt32. |
247 | 387 |
248 | 388 |
249 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) { | 389 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) { |
250 StreamBuilder m(this, MachineType::Int32(), MachineType::Int64()); | 390 StreamBuilder m(this, MachineType::Int32(), MachineType::Int64()); |
251 Node* const p = m.Parameter(0); | 391 Node* const p = m.Parameter(0); |
252 Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32))); | 392 Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32))); |
253 m.Return(t); | 393 m.Return(t); |
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 1488 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
1349 EXPECT_EQ(4, s.ToInt32(s[0]->InputAt(1))); | 1489 EXPECT_EQ(4, s.ToInt32(s[0]->InputAt(1))); |
1350 ASSERT_EQ(1U, s[0]->OutputCount()); | 1490 ASSERT_EQ(1U, s[0]->OutputCount()); |
1351 EXPECT_EQ(s.ToVreg(shift), s.ToVreg(s[0]->Output())); | 1491 EXPECT_EQ(s.ToVreg(shift), s.ToVreg(s[0]->Output())); |
1352 } | 1492 } |
1353 } | 1493 } |
1354 | 1494 |
1355 } // namespace compiler | 1495 } // namespace compiler |
1356 } // namespace internal | 1496 } // namespace internal |
1357 } // namespace v8 | 1497 } // namespace v8 |
OLD | NEW |