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

Side by Side Diff: test/unittests/compiler/x64/instruction-selector-x64-unittest.cc

Issue 738073002: [turbofan]: More optimizations to add and subtract operations on x64 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Latest version Created 6 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « src/compiler/x64/instruction-selector-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 ASSERT_EQ(1U, s[0]->OutputCount()); 237 ASSERT_EQ(1U, s[0]->OutputCount());
238 EXPECT_TRUE(s.IsSameAsFirst(s[0]->OutputAt(0))); 238 EXPECT_TRUE(s.IsSameAsFirst(s[0]->OutputAt(0)));
239 EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0))); 239 EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
240 } 240 }
241 241
242 242
243 // ----------------------------------------------------------------------------- 243 // -----------------------------------------------------------------------------
244 // Addition. 244 // Addition.
245 245
246 246
247 TEST_F(InstructionSelectorTest, Int32AddWithInt32AddWithParameters) { 247 TEST_F(InstructionSelectorTest, Int32AddWithInt32ParametersLea) {
248 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 248 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
249 Node* const p0 = m.Parameter(0); 249 Node* const p0 = m.Parameter(0);
250 Node* const p1 = m.Parameter(1); 250 Node* const p1 = m.Parameter(1);
251 Node* const a0 = m.Int32Add(p0, p1); 251 Node* const a0 = m.Int32Add(p0, p1);
252 m.Return(m.Int32Add(a0, p0)); 252 USE(a0);
253 // Additional uses of input to add chooses lea
254 Node* const a1 = m.Int32Add(p0, p1);
255 m.Return(m.Int32Add(a0, a1));
253 Stream s = m.Build(); 256 Stream s = m.Build();
254 ASSERT_EQ(2U, s.size()); 257 ASSERT_EQ(3U, s.size());
255 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode()); 258 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
256 ASSERT_EQ(2U, s[0]->InputCount()); 259 ASSERT_EQ(2U, s[0]->InputCount());
257 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 260 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
258 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 261 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
259 } 262 }
260 263
261 264
262 TEST_F(InstructionSelectorTest, Int32AddConstantAsLea) { 265 TEST_F(InstructionSelectorTest, Int32AddConstantAsLeaSingle) {
263 StreamBuilder m(this, kMachInt32, kMachInt32); 266 StreamBuilder m(this, kMachInt32, kMachInt32);
264 Node* const p0 = m.Parameter(0); 267 Node* const p0 = m.Parameter(0);
265 Node* const c0 = m.Int32Constant(15); 268 Node* const c0 = m.Int32Constant(15);
269 // If there is only a single use of an add's input, still use lea and not add,
270 // it is faster.
266 m.Return(m.Int32Add(p0, c0)); 271 m.Return(m.Int32Add(p0, c0));
267 Stream s = m.Build(); 272 Stream s = m.Build();
268 ASSERT_EQ(1U, s.size()); 273 ASSERT_EQ(1U, s.size());
269 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode()); 274 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
270 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); 275 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
271 ASSERT_EQ(2U, s[0]->InputCount()); 276 ASSERT_EQ(2U, s[0]->InputCount());
272 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 277 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
273 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 278 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
274 } 279 }
275 280
276 281
277 TEST_F(InstructionSelectorTest, Int32AddCommutedConstantAsLea) { 282 TEST_F(InstructionSelectorTest, Int32AddConstantAsInc) {
283 StreamBuilder m(this, kMachInt32, kMachInt32);
284 Node* const p0 = m.Parameter(0);
285 Node* const c0 = m.Int32Constant(1);
286 // If there is only a single use of an add's input and the immediate constant
287 // for the add is 1, use inc.
288 m.Return(m.Int32Add(p0, c0));
289 Stream s = m.Build();
290 ASSERT_EQ(1U, s.size());
291 EXPECT_EQ(kX64Inc32, s[0]->arch_opcode());
292 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
293 ASSERT_EQ(1U, s[0]->InputCount());
294 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
295 }
296
297
298 TEST_F(InstructionSelectorTest, Int32AddConstantAsDec) {
299 StreamBuilder m(this, kMachInt32, kMachInt32);
300 Node* const p0 = m.Parameter(0);
301 Node* const c0 = m.Int32Constant(-1);
302 // If there is only a single use of an add's input and the immediate constant
303 // for the add is -11, use dec.
304 m.Return(m.Int32Add(p0, c0));
305 Stream s = m.Build();
306 ASSERT_EQ(1U, s.size());
307 EXPECT_EQ(kX64Dec32, s[0]->arch_opcode());
308 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
309 ASSERT_EQ(1U, s[0]->InputCount());
310 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
311 }
312
313
314 TEST_F(InstructionSelectorTest, Int32AddConstantAsLeaDouble) {
278 StreamBuilder m(this, kMachInt32, kMachInt32); 315 StreamBuilder m(this, kMachInt32, kMachInt32);
279 Node* const p0 = m.Parameter(0); 316 Node* const p0 = m.Parameter(0);
280 Node* const c0 = m.Int32Constant(15); 317 Node* const c0 = m.Int32Constant(15);
318 // A second use of an add's input uses lea
319 Node* const a0 = m.Int32Add(p0, c0);
320 USE(a0);
321 m.Return(m.Int32Add(p0, c0));
322 Stream s = m.Build();
323 ASSERT_EQ(1U, s.size());
324 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
325 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
326 ASSERT_EQ(2U, s[0]->InputCount());
327 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
328 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
329 }
330
331
332 TEST_F(InstructionSelectorTest, Int32AddCommutedConstantAsLeaSingle) {
333 StreamBuilder m(this, kMachInt32, kMachInt32);
334 Node* const p0 = m.Parameter(0);
335 Node* const c0 = m.Int32Constant(15);
336 // If there is only a single use of an add's input, still use lea... it's
337 // generally faster than the add to reduce register pressure.
281 m.Return(m.Int32Add(c0, p0)); 338 m.Return(m.Int32Add(c0, p0));
282 Stream s = m.Build(); 339 Stream s = m.Build();
283 ASSERT_EQ(1U, s.size()); 340 ASSERT_EQ(1U, s.size());
341 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
342 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
343 ASSERT_EQ(2U, s[0]->InputCount());
344 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
345 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
346 }
347
348
349 TEST_F(InstructionSelectorTest, Int32AddCommutedConstantAsLeaDouble) {
350 StreamBuilder m(this, kMachInt32, kMachInt32);
351 Node* const p0 = m.Parameter(0);
352 Node* const c0 = m.Int32Constant(15);
353 // A second use of an add's input uses lea
354 Node* const a0 = m.Int32Add(c0, p0);
355 USE(a0);
356 m.Return(m.Int32Add(c0, p0));
357 Stream s = m.Build();
358 ASSERT_EQ(1U, s.size());
284 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode()); 359 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
285 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); 360 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
286 ASSERT_EQ(2U, s[0]->InputCount()); 361 ASSERT_EQ(2U, s[0]->InputCount());
287 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 362 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
288 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 363 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
289 } 364 }
290 365
291 366
292 TEST_F(InstructionSelectorTest, Int32AddScaled2Mul) { 367 TEST_F(InstructionSelectorTest, Int32AddScaled2Mul) {
293 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 368 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 ASSERT_EQ(1U, s.size()); 683 ASSERT_EQ(1U, s.size());
609 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode()); 684 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
610 EXPECT_EQ(kMode_MR8I, s[0]->addressing_mode()); 685 EXPECT_EQ(kMode_MR8I, s[0]->addressing_mode());
611 ASSERT_EQ(3U, s[0]->InputCount()); 686 ASSERT_EQ(3U, s[0]->InputCount());
612 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 687 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
613 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 688 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
614 EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate()); 689 EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
615 } 690 }
616 691
617 692
693 TEST_F(InstructionSelectorTest, Int32SubConstantAsInc) {
694 StreamBuilder m(this, kMachInt32, kMachInt32);
695 Node* const p0 = m.Parameter(0);
696 Node* const c0 = m.Int32Constant(-1);
697 // If there is only a single use of an add's input and the immediate constant
698 // for the add is 1, use inc.
699 m.Return(m.Int32Sub(p0, c0));
700 Stream s = m.Build();
701 ASSERT_EQ(1U, s.size());
702 EXPECT_EQ(kX64Inc32, s[0]->arch_opcode());
703 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
704 ASSERT_EQ(1U, s[0]->InputCount());
705 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
706 }
707
708
709 TEST_F(InstructionSelectorTest, Int32SubConstantAsDec) {
710 StreamBuilder m(this, kMachInt32, kMachInt32);
711 Node* const p0 = m.Parameter(0);
712 Node* const c0 = m.Int32Constant(1);
713 // If there is only a single use of an sub's input and the immediate constant
714 // for the add is 1, use dec.
715 m.Return(m.Int32Sub(p0, c0));
716 Stream s = m.Build();
717 ASSERT_EQ(1U, s.size());
718 EXPECT_EQ(kX64Dec32, s[0]->arch_opcode());
719 EXPECT_EQ(kMode_None, s[0]->addressing_mode());
720 ASSERT_EQ(1U, s[0]->InputCount());
721 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
722 }
723
724
618 // ----------------------------------------------------------------------------- 725 // -----------------------------------------------------------------------------
619 // Multiplication. 726 // Multiplication.
620 727
621 728
622 TEST_F(InstructionSelectorTest, Int32MulWithInt32MulWithParameters) { 729 TEST_F(InstructionSelectorTest, Int32MulWithInt32MulWithParameters) {
623 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 730 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
624 Node* const p0 = m.Parameter(0); 731 Node* const p0 = m.Parameter(0);
625 Node* const p1 = m.Parameter(1); 732 Node* const p1 = m.Parameter(1);
626 Node* const m0 = m.Int32Mul(p0, p1); 733 Node* const m0 = m.Int32Mul(p0, p1);
627 m.Return(m.Int32Mul(m0, p0)); 734 m.Return(m.Int32Mul(m0, p0));
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 EXPECT_EQ(x, s.ToInt32(s[0]->InputAt(1))); 824 EXPECT_EQ(x, s.ToInt32(s[0]->InputAt(1)));
718 ASSERT_EQ(1U, s[0]->OutputCount()); 825 ASSERT_EQ(1U, s[0]->OutputCount());
719 EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output())); 826 EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
720 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 827 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
721 } 828 }
722 } 829 }
723 830
724 } // namespace compiler 831 } // namespace compiler
725 } // namespace internal 832 } // namespace internal
726 } // namespace v8 833 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/x64/instruction-selector-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698