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

Side by Side Diff: test/cctest/compiler/compiler/test-branch-combine.cc

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #include "test/cctest/cctest.h"
8 #include "test/cctest/compiler/codegen-tester.h"
9 #include "test/cctest/compiler/value-helper.h"
10
11 #if V8_TURBOFAN_TARGET
12
13 using namespace v8::internal;
14 using namespace v8::internal::compiler;
15
16 typedef RawMachineAssembler::Label MLabel;
17
18 static IrOpcode::Value int32cmp_opcodes[] = {
19 IrOpcode::kWord32Equal,
20 IrOpcode::kInt32LessThan,
21 IrOpcode::kInt32LessThanOrEqual,
22 IrOpcode::kUint32LessThan,
23 IrOpcode::kUint32LessThanOrEqual
24 };
25
26
27 TEST(BranchCombineWord32EqualZero_1) {
28 // Test combining a branch with x == 0
29 RawMachineAssemblerTester<int32_t> m(kMachineWord32);
30 int32_t eq_constant = -1033;
31 int32_t ne_constant = 825118;
32 Node* p0 = m.Parameter(0);
33
34 MLabel blocka, blockb;
35 m.Branch(m.Word32Equal(p0, m.Int32Constant(0)), &blocka, &blockb);
36 m.Bind(&blocka);
37 m.Return(m.Int32Constant(eq_constant));
38 m.Bind(&blockb);
39 m.Return(m.Int32Constant(ne_constant));
40
41 FOR_INT32_INPUTS(i) {
42 int32_t a = *i;
43 int32_t expect = a == 0 ? eq_constant : ne_constant;
44 CHECK_EQ(expect, m.Call(a));
45 }
46 }
47
48
49 TEST(BranchCombineWord32EqualZero_chain) {
50 // Test combining a branch with a chain of x == 0 == 0 == 0 ...
51 int32_t eq_constant = -1133;
52 int32_t ne_constant = 815118;
53
54 for (int k = 0; k < 6; k++) {
55 RawMachineAssemblerTester<int32_t> m(kMachineWord32);
56 Node* p0 = m.Parameter(0);
57 MLabel blocka, blockb;
58 Node* cond = p0;
59 for (int j = 0; j < k; j++) {
60 cond = m.Word32Equal(cond, m.Int32Constant(0));
61 }
62 m.Branch(cond, &blocka, &blockb);
63 m.Bind(&blocka);
64 m.Return(m.Int32Constant(eq_constant));
65 m.Bind(&blockb);
66 m.Return(m.Int32Constant(ne_constant));
67
68 FOR_INT32_INPUTS(i) {
69 int32_t a = *i;
70 int32_t expect = (k & 1) == 1 ?
71 (a == 0 ? eq_constant : ne_constant) :
72 (a == 0 ? ne_constant : eq_constant);
73 CHECK_EQ(expect, m.Call(a));
74 }
75 }
76 }
77
78
79 TEST(BranchCombineInt32LessThanZero_1) {
80 // Test combining a branch with x < 0
81 RawMachineAssemblerTester<int32_t> m(kMachineWord32);
82 int32_t eq_constant = -1433;
83 int32_t ne_constant = 845118;
84 Node* p0 = m.Parameter(0);
85
86 MLabel blocka, blockb;
87 m.Branch(m.Int32LessThan(p0, m.Int32Constant(0)), &blocka, &blockb);
88 m.Bind(&blocka);
89 m.Return(m.Int32Constant(eq_constant));
90 m.Bind(&blockb);
91 m.Return(m.Int32Constant(ne_constant));
92
93 FOR_INT32_INPUTS(i) {
94 int32_t a = *i;
95 int32_t expect = a < 0 ? eq_constant : ne_constant;
96 CHECK_EQ(expect, m.Call(a));
97 }
98 }
99
100
101 TEST(BranchCombineUint32LessThan100_1) {
102 // Test combining a branch with x < 100
103 RawMachineAssemblerTester<int32_t> m(kMachineWord32);
104 int32_t eq_constant = 1471;
105 int32_t ne_constant = 88845718;
106 Node* p0 = m.Parameter(0);
107
108 MLabel blocka, blockb;
109 m.Branch(m.Uint32LessThan(p0, m.Int32Constant(100)), &blocka, &blockb);
110 m.Bind(&blocka);
111 m.Return(m.Int32Constant(eq_constant));
112 m.Bind(&blockb);
113 m.Return(m.Int32Constant(ne_constant));
114
115 FOR_UINT32_INPUTS(i) {
116 uint32_t a = *i;
117 int32_t expect = a < 100 ? eq_constant : ne_constant;
118 CHECK_EQ(expect, m.Call(a));
119 }
120 }
121
122
123 TEST(BranchCombineUint32LessThanOrEqual100_1) {
124 // Test combining a branch with x <= 100
125 RawMachineAssemblerTester<int32_t> m(kMachineWord32);
126 int32_t eq_constant = 1479;
127 int32_t ne_constant = 77845719;
128 Node* p0 = m.Parameter(0);
129
130 MLabel blocka, blockb;
131 m.Branch(m.Uint32LessThanOrEqual(p0, m.Int32Constant(100)), &blocka, &blockb);
132 m.Bind(&blocka);
133 m.Return(m.Int32Constant(eq_constant));
134 m.Bind(&blockb);
135 m.Return(m.Int32Constant(ne_constant));
136
137 FOR_UINT32_INPUTS(i) {
138 uint32_t a = *i;
139 int32_t expect = a <= 100 ? eq_constant : ne_constant;
140 CHECK_EQ(expect, m.Call(a));
141 }
142 }
143
144
145 TEST(BranchCombineZeroLessThanInt32_1) {
146 // Test combining a branch with 0 < x
147 RawMachineAssemblerTester<int32_t> m(kMachineWord32);
148 int32_t eq_constant = -2033;
149 int32_t ne_constant = 225118;
150 Node* p0 = m.Parameter(0);
151
152 MLabel blocka, blockb;
153 m.Branch(m.Int32LessThan(m.Int32Constant(0), p0), &blocka, &blockb);
154 m.Bind(&blocka);
155 m.Return(m.Int32Constant(eq_constant));
156 m.Bind(&blockb);
157 m.Return(m.Int32Constant(ne_constant));
158
159 FOR_INT32_INPUTS(i) {
160 int32_t a = *i;
161 int32_t expect = 0 < a ? eq_constant : ne_constant;
162 CHECK_EQ(expect, m.Call(a));
163 }
164 }
165
166
167 TEST(BranchCombineInt32GreaterThanZero_1) {
168 // Test combining a branch with x > 0
169 RawMachineAssemblerTester<int32_t> m(kMachineWord32);
170 int32_t eq_constant = -1073;
171 int32_t ne_constant = 825178;
172 Node* p0 = m.Parameter(0);
173
174 MLabel blocka, blockb;
175 m.Branch(m.Int32GreaterThan(p0, m.Int32Constant(0)), &blocka, &blockb);
176 m.Bind(&blocka);
177 m.Return(m.Int32Constant(eq_constant));
178 m.Bind(&blockb);
179 m.Return(m.Int32Constant(ne_constant));
180
181 FOR_INT32_INPUTS(i) {
182 int32_t a = *i;
183 int32_t expect = a > 0 ? eq_constant : ne_constant;
184 CHECK_EQ(expect, m.Call(a));
185 }
186 }
187
188
189 TEST(BranchCombineWord32EqualP) {
190 // Test combining a branch with an Word32Equal.
191 RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
192 int32_t eq_constant = -1035;
193 int32_t ne_constant = 825018;
194 Node* p0 = m.Parameter(0);
195 Node* p1 = m.Parameter(1);
196
197 MLabel blocka, blockb;
198 m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb);
199 m.Bind(&blocka);
200 m.Return(m.Int32Constant(eq_constant));
201 m.Bind(&blockb);
202 m.Return(m.Int32Constant(ne_constant));
203
204 FOR_INT32_INPUTS(i) {
205 FOR_INT32_INPUTS(j) {
206 int32_t a = *i;
207 int32_t b = *j;
208 int32_t expect = a == b ? eq_constant : ne_constant;
209 CHECK_EQ(expect, m.Call(a, b));
210 }
211 }
212 }
213
214
215 TEST(BranchCombineWord32EqualI) {
216 int32_t eq_constant = -1135;
217 int32_t ne_constant = 925718;
218
219 for (int left = 0; left < 2; left++) {
220 FOR_INT32_INPUTS(i) {
221 RawMachineAssemblerTester<int32_t> m(kMachineWord32);
222 int32_t a = *i;
223
224 Node* p0 = m.Int32Constant(a);
225 Node* p1 = m.Parameter(0);
226
227 MLabel blocka, blockb;
228 if (left == 1) m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb);
229 if (left == 0) m.Branch(m.Word32Equal(p1, p0), &blocka, &blockb);
230 m.Bind(&blocka);
231 m.Return(m.Int32Constant(eq_constant));
232 m.Bind(&blockb);
233 m.Return(m.Int32Constant(ne_constant));
234
235 FOR_INT32_INPUTS(j) {
236 int32_t b = *j;
237 int32_t expect = a == b ? eq_constant : ne_constant;
238 CHECK_EQ(expect, m.Call(b));
239 }
240 }
241 }
242 }
243
244
245 TEST(BranchCombineInt32CmpP) {
246 int32_t eq_constant = -1235;
247 int32_t ne_constant = 725018;
248
249 for (int op = 0; op < 2; op++) {
250 RawMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
251 Node* p0 = m.Parameter(0);
252 Node* p1 = m.Parameter(1);
253
254 MLabel blocka, blockb;
255 if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb);
256 if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb);
257 m.Bind(&blocka);
258 m.Return(m.Int32Constant(eq_constant));
259 m.Bind(&blockb);
260 m.Return(m.Int32Constant(ne_constant));
261
262 FOR_INT32_INPUTS(i) {
263 FOR_INT32_INPUTS(j) {
264 int32_t a = *i;
265 int32_t b = *j;
266 int32_t expect = 0;
267 if (op == 0) expect = a < b ? eq_constant : ne_constant;
268 if (op == 1) expect = a <= b ? eq_constant : ne_constant;
269 CHECK_EQ(expect, m.Call(a, b));
270 }
271 }
272 }
273 }
274
275
276 TEST(BranchCombineInt32CmpI) {
277 int32_t eq_constant = -1175;
278 int32_t ne_constant = 927711;
279
280 for (int op = 0; op < 2; op++) {
281 FOR_INT32_INPUTS(i) {
282 RawMachineAssemblerTester<int32_t> m(kMachineWord32);
283 int32_t a = *i;
284 Node* p0 = m.Int32Constant(a);
285 Node* p1 = m.Parameter(0);
286
287 MLabel blocka, blockb;
288 if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb);
289 if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb);
290 m.Bind(&blocka);
291 m.Return(m.Int32Constant(eq_constant));
292 m.Bind(&blockb);
293 m.Return(m.Int32Constant(ne_constant));
294
295 FOR_INT32_INPUTS(j) {
296 int32_t b = *j;
297 int32_t expect = 0;
298 if (op == 0) expect = a < b ? eq_constant : ne_constant;
299 if (op == 1) expect = a <= b ? eq_constant : ne_constant;
300 CHECK_EQ(expect, m.Call(b));
301 }
302 }
303 }
304 }
305
306
307 // Now come the sophisticated tests for many input shape combinations.
308
309 // Materializes a boolean (1 or 0) from a comparison.
310 class CmpMaterializeBoolGen : public BinopGen<int32_t> {
311 public:
312 CompareWrapper w;
313 bool invert;
314
315 CmpMaterializeBoolGen(IrOpcode::Value opcode, bool i)
316 : w(opcode), invert(i) { }
317
318 virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
319 Node* cond = w.MakeNode(m, a, b);
320 if (invert) cond = m->Word32Equal(cond, m->Int32Constant(0));
321 m->Return(cond);
322 }
323 virtual int32_t expected(int32_t a, int32_t b) {
324 if (invert) return !w.Int32Compare(a, b) ? 1 : 0;
325 return w.Int32Compare(a, b) ? 1 : 0;
326 }
327 };
328
329
330 // Generates a branch and return one of two values from a comparison.
331 class CmpBranchGen : public BinopGen<int32_t> {
332 public:
333 CompareWrapper w;
334 bool invert;
335 bool true_first;
336 int32_t eq_constant;
337 int32_t ne_constant;
338
339 CmpBranchGen(IrOpcode::Value opcode, bool i, bool t, int32_t eq, int32_t ne)
340 : w(opcode),
341 invert(i),
342 true_first(t),
343 eq_constant(eq),
344 ne_constant(ne) { }
345
346 virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
347 MLabel blocka, blockb;
348 Node* cond = w.MakeNode(m, a, b);
349 if (invert) cond = m->Word32Equal(cond, m->Int32Constant(0));
350 m->Branch(cond, &blocka, &blockb);
351 if (true_first) {
352 m->Bind(&blocka);
353 m->Return(m->Int32Constant(eq_constant));
354 m->Bind(&blockb);
355 m->Return(m->Int32Constant(ne_constant));
356 } else {
357 m->Bind(&blockb);
358 m->Return(m->Int32Constant(ne_constant));
359 m->Bind(&blocka);
360 m->Return(m->Int32Constant(eq_constant));
361 }
362 }
363 virtual int32_t expected(int32_t a, int32_t b) {
364 if (invert) return !w.Int32Compare(a, b) ? eq_constant : ne_constant;
365 return w.Int32Compare(a, b) ? eq_constant : ne_constant;
366 }
367 };
368
369
370 TEST(BranchCombineInt32CmpAllInputShapes_materialized) {
371 for (size_t i = 0; i < ARRAY_SIZE(int32cmp_opcodes); i++) {
372 CmpMaterializeBoolGen gen(int32cmp_opcodes[i], false);
373 Int32BinopInputShapeTester tester(&gen);
374 tester.TestAllInputShapes();
375 }
376 }
377
378
379 TEST(BranchCombineInt32CmpAllInputShapes_inverted_materialized) {
380 for (size_t i = 0; i < ARRAY_SIZE(int32cmp_opcodes); i++) {
381 CmpMaterializeBoolGen gen(int32cmp_opcodes[i], true);
382 Int32BinopInputShapeTester tester(&gen);
383 tester.TestAllInputShapes();
384 }
385 }
386
387
388 TEST(BranchCombineInt32CmpAllInputShapes_branch_true) {
389 for (size_t i = 0; i < ARRAY_SIZE(int32cmp_opcodes); i++) {
390 CmpBranchGen gen(int32cmp_opcodes[i], false, false, 995+i, -1011-i);
391 Int32BinopInputShapeTester tester(&gen);
392 tester.TestAllInputShapes();
393 }
394 }
395
396
397 TEST(BranchCombineInt32CmpAllInputShapes_branch_false) {
398 for (size_t i = 0; i < ARRAY_SIZE(int32cmp_opcodes); i++) {
399 CmpBranchGen gen(int32cmp_opcodes[i], false, true, 795+i, -2011-i);
400 Int32BinopInputShapeTester tester(&gen);
401 tester.TestAllInputShapes();
402 }
403 }
404
405
406 TEST(BranchCombineInt32CmpAllInputShapes_inverse_branch_true) {
407 for (size_t i = 0; i < ARRAY_SIZE(int32cmp_opcodes); i++) {
408 CmpBranchGen gen(int32cmp_opcodes[i], true, false, 695+i, -3011-i);
409 Int32BinopInputShapeTester tester(&gen);
410 tester.TestAllInputShapes();
411 }
412 }
413
414
415 TEST(BranchCombineInt32CmpAllInputShapes_inverse_branch_false) {
416 for (size_t i = 0; i < ARRAY_SIZE(int32cmp_opcodes); i++) {
417 CmpBranchGen gen(int32cmp_opcodes[i], true, true, 595+i, -4011-i);
418 Int32BinopInputShapeTester tester(&gen);
419 tester.TestAllInputShapes();
420 }
421 }
422
423
424 TEST(BranchCombineFloat64Compares) {
425 double inf = V8_INFINITY;
426 double nan = v8::base::OS::nan_value();
427 double inputs[] = {0.0, 1.0, -1.0, -inf, inf, nan};
428
429 int32_t eq_constant = -1733;
430 int32_t ne_constant = 915118;
431
432 double input_a = 0.0;
433 double input_b = 0.0;
434
435 CompareWrapper cmps[] = {
436 CompareWrapper(IrOpcode::kFloat64Equal),
437 CompareWrapper(IrOpcode::kFloat64LessThan),
438 CompareWrapper(IrOpcode::kFloat64LessThanOrEqual)
439 };
440
441 for (size_t c = 0; c < ARRAY_SIZE(cmps); c++) {
442 CompareWrapper cmp = cmps[c];
443 for (int invert = 0; invert < 2; invert++) {
444 RawMachineAssemblerTester<int32_t> m;
445 Node* a = m.LoadFromPointer(&input_a, kMachineFloat64);
446 Node* b = m.LoadFromPointer(&input_b, kMachineFloat64);
447
448 MLabel blocka, blockb;
449 Node* cond = cmp.MakeNode(&m, a, b);
450 if (invert) cond = m.Word32Equal(cond, m.Int32Constant(0));
451 m.Branch(cond, &blocka, &blockb);
452 m.Bind(&blocka);
453 m.Return(m.Int32Constant(eq_constant));
454 m.Bind(&blockb);
455 m.Return(m.Int32Constant(ne_constant));
456
457 for (size_t i = 0; i < ARRAY_SIZE(inputs); i++) {
458 for (size_t j = 0; j < ARRAY_SIZE(inputs); j += 2) {
459 input_a = inputs[i];
460 input_b = inputs[i];
461 int32_t expected = invert ?
462 (cmp.Float64Compare(input_a, input_b) ? ne_constant : eq_constant) :
463 (cmp.Float64Compare(input_a, input_b) ? eq_constant : ne_constant);
464 CHECK_EQ(expected, m.Call());
465 }
466 }
467 }
468 }
469 }
470 #endif // V8_TURBOFAN_TARGET
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698