intel/compiler: Fix pointer arithmetic when reading shader assembly
[mesa.git] / src / intel / compiler / test_fs_scoreboard.cpp
1 /*
2 * Copyright © 2019 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <gtest/gtest.h>
25 #include "brw_fs.h"
26 #include "brw_cfg.h"
27 #include "program/program.h"
28
29 using namespace brw;
30
31 class scoreboard_test : public ::testing::Test {
32 virtual void SetUp();
33
34 public:
35 struct brw_compiler *compiler;
36 struct gen_device_info *devinfo;
37 struct gl_context *ctx;
38 struct brw_wm_prog_data *prog_data;
39 struct gl_shader_program *shader_prog;
40 fs_visitor *v;
41 };
42
43 void scoreboard_test::SetUp()
44 {
45 ctx = (struct gl_context *)calloc(1, sizeof(*ctx));
46 compiler = (struct brw_compiler *)calloc(1, sizeof(*compiler));
47 devinfo = (struct gen_device_info *)calloc(1, sizeof(*devinfo));
48 compiler->devinfo = devinfo;
49
50 prog_data = ralloc(NULL, struct brw_wm_prog_data);
51 nir_shader *shader =
52 nir_shader_create(NULL, MESA_SHADER_FRAGMENT, NULL, NULL);
53
54 v = new fs_visitor(compiler, NULL, NULL, NULL, &prog_data->base, shader, 8, -1);
55
56 devinfo->gen = 12;
57 }
58
59 static fs_inst *
60 instruction(bblock_t *block, int num)
61 {
62 fs_inst *inst = (fs_inst *)block->start();
63 for (int i = 0; i < num; i++) {
64 inst = (fs_inst *)inst->next;
65 }
66 return inst;
67 }
68
69 static void
70 lower_scoreboard(fs_visitor *v)
71 {
72 const bool print = getenv("TEST_DEBUG");
73
74 if (print) {
75 fprintf(stderr, "= Before =\n");
76 v->cfg->dump();
77 }
78
79 v->lower_scoreboard();
80
81 if (print) {
82 fprintf(stderr, "\n= After =\n");
83 v->cfg->dump();
84 }
85 }
86
87 fs_inst *
88 emit_SEND(const fs_builder &bld, const fs_reg &dst,
89 const fs_reg &desc, const fs_reg &payload)
90 {
91 fs_inst *inst = bld.emit(SHADER_OPCODE_SEND, dst, desc, desc, payload);
92 inst->mlen = 1;
93 return inst;
94 }
95
96 bool operator ==(const tgl_swsb &a, const tgl_swsb &b)
97 {
98 return a.mode == b.mode &&
99 a.regdist == b.regdist &&
100 (a.mode == TGL_SBID_NULL || a.sbid == b.sbid);
101 }
102
103 std::ostream &operator<<(std::ostream &os, const tgl_swsb &swsb) {
104 if (swsb.regdist)
105 os << "@" << swsb.regdist;
106
107 if (swsb.mode) {
108 if (swsb.regdist)
109 os << " ";
110 os << "$" << swsb.sbid;
111 if (swsb.mode & TGL_SBID_DST)
112 os << ".dst";
113 if (swsb.mode & TGL_SBID_SRC)
114 os << ".src";
115 }
116
117 return os;
118 }
119
120 TEST_F(scoreboard_test, RAW_inorder_inorder)
121 {
122 const fs_builder &bld = v->bld;
123 fs_reg g[16];
124 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
125 g[i] = v->vgrf(glsl_type::int_type);
126
127 fs_reg x = v->vgrf(glsl_type::int_type);
128 fs_reg y = v->vgrf(glsl_type::int_type);
129 bld.ADD( x, g[1], g[2]);
130 bld.MUL( y, g[3], g[4]);
131 bld.AND(g[5], x, y);
132
133 v->calculate_cfg();
134 bblock_t *block0 = v->cfg->blocks[0];
135 ASSERT_EQ(0, block0->start_ip);
136 ASSERT_EQ(2, block0->end_ip);
137
138 lower_scoreboard(v);
139 ASSERT_EQ(0, block0->start_ip);
140 ASSERT_EQ(2, block0->end_ip);
141
142 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
143 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
144 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_regdist(1));
145 }
146
147 TEST_F(scoreboard_test, RAW_inorder_outoforder)
148 {
149 const fs_builder &bld = v->bld;
150 fs_reg g[16];
151 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
152 g[i] = v->vgrf(glsl_type::int_type);
153
154 fs_reg x = v->vgrf(glsl_type::int_type);
155 bld.ADD( x, g[1], g[2]);
156 bld.MUL( g[3], g[4], g[5]);
157 emit_SEND(bld, g[6], g[7], x);
158
159 v->calculate_cfg();
160 bblock_t *block0 = v->cfg->blocks[0];
161 ASSERT_EQ(0, block0->start_ip);
162 ASSERT_EQ(2, block0->end_ip);
163
164 lower_scoreboard(v);
165 ASSERT_EQ(0, block0->start_ip);
166 ASSERT_EQ(2, block0->end_ip);
167
168 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
169 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
170 EXPECT_EQ(instruction(block0, 2)->sched,
171 (tgl_swsb { .regdist = 2, .sbid = 0, .mode = TGL_SBID_SET }));
172 }
173
174 TEST_F(scoreboard_test, RAW_outoforder_inorder)
175 {
176 const fs_builder &bld = v->bld;
177 fs_reg g[16];
178 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
179 g[i] = v->vgrf(glsl_type::int_type);
180
181 fs_reg x = v->vgrf(glsl_type::int_type);
182 fs_reg y = v->vgrf(glsl_type::int_type);
183 emit_SEND(bld, x, g[1], g[2]);
184 bld.MUL( y, g[3], g[4]);
185 bld.AND( g[5], x, y);
186
187 v->calculate_cfg();
188 bblock_t *block0 = v->cfg->blocks[0];
189 ASSERT_EQ(0, block0->start_ip);
190 ASSERT_EQ(2, block0->end_ip);
191
192 lower_scoreboard(v);
193 ASSERT_EQ(0, block0->start_ip);
194 ASSERT_EQ(2, block0->end_ip);
195
196 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
197 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
198 EXPECT_EQ(instruction(block0, 2)->sched,
199 (tgl_swsb { .regdist = 1, .sbid = 0, .mode = TGL_SBID_DST }));
200 }
201
202 TEST_F(scoreboard_test, RAW_outoforder_outoforder)
203 {
204 const fs_builder &bld = v->bld;
205 fs_reg g[16];
206 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
207 g[i] = v->vgrf(glsl_type::int_type);
208
209 /* The second SEND depends on the first, and would need to refer to two
210 * SBIDs. Since it is not possible we expect a SYNC instruction to be
211 * added.
212 */
213 fs_reg x = v->vgrf(glsl_type::int_type);
214 emit_SEND(bld, x, g[1], g[2]);
215 emit_SEND(bld, g[3], x, g[4])->sfid++;
216
217 v->calculate_cfg();
218 bblock_t *block0 = v->cfg->blocks[0];
219 ASSERT_EQ(0, block0->start_ip);
220 ASSERT_EQ(1, block0->end_ip);
221
222 lower_scoreboard(v);
223 ASSERT_EQ(0, block0->start_ip);
224 ASSERT_EQ(2, block0->end_ip);
225
226 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
227
228 fs_inst *sync = instruction(block0, 1);
229 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
230 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
231
232 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
233 }
234
235 TEST_F(scoreboard_test, WAR_inorder_inorder)
236 {
237 const fs_builder &bld = v->bld;
238 fs_reg g[16];
239 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
240 g[i] = v->vgrf(glsl_type::int_type);
241
242 fs_reg x = v->vgrf(glsl_type::int_type);
243 bld.ADD(g[1], x, g[2]);
244 bld.MUL(g[3], g[4], g[5]);
245 bld.AND( x, g[6], g[7]);
246
247 v->calculate_cfg();
248 bblock_t *block0 = v->cfg->blocks[0];
249 ASSERT_EQ(0, block0->start_ip);
250 ASSERT_EQ(2, block0->end_ip);
251
252 lower_scoreboard(v);
253 ASSERT_EQ(0, block0->start_ip);
254 ASSERT_EQ(2, block0->end_ip);
255
256 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
257 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
258 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_null());
259 }
260
261 TEST_F(scoreboard_test, WAR_inorder_outoforder)
262 {
263 const fs_builder &bld = v->bld;
264 fs_reg g[16];
265 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
266 g[i] = v->vgrf(glsl_type::int_type);
267
268 fs_reg x = v->vgrf(glsl_type::int_type);
269 bld.ADD( g[1], x, g[2]);
270 bld.MUL( g[3], g[4], g[5]);
271 emit_SEND(bld, x, g[6], g[7]);
272
273 v->calculate_cfg();
274 bblock_t *block0 = v->cfg->blocks[0];
275 ASSERT_EQ(0, block0->start_ip);
276 ASSERT_EQ(2, block0->end_ip);
277
278 lower_scoreboard(v);
279 ASSERT_EQ(0, block0->start_ip);
280 ASSERT_EQ(2, block0->end_ip);
281
282 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
283 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
284 EXPECT_EQ(instruction(block0, 2)->sched,
285 (tgl_swsb { .regdist = 2, .sbid = 0, .mode = TGL_SBID_SET }));
286 }
287
288 TEST_F(scoreboard_test, WAR_outoforder_inorder)
289 {
290 const fs_builder &bld = v->bld;
291 fs_reg g[16];
292 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
293 g[i] = v->vgrf(glsl_type::int_type);
294
295 fs_reg x = v->vgrf(glsl_type::int_type);
296 emit_SEND(bld, g[1], g[2], x);
297 bld.MUL( g[4], g[5], g[6]);
298 bld.AND( x, g[7], g[8]);
299
300 v->calculate_cfg();
301 bblock_t *block0 = v->cfg->blocks[0];
302 ASSERT_EQ(0, block0->start_ip);
303 ASSERT_EQ(2, block0->end_ip);
304
305 lower_scoreboard(v);
306 ASSERT_EQ(0, block0->start_ip);
307 ASSERT_EQ(2, block0->end_ip);
308
309 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
310 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
311 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
312 }
313
314 TEST_F(scoreboard_test, WAR_outoforder_outoforder)
315 {
316 const fs_builder &bld = v->bld;
317 fs_reg g[16];
318 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
319 g[i] = v->vgrf(glsl_type::int_type);
320
321 fs_reg x = v->vgrf(glsl_type::int_type);
322 emit_SEND(bld, g[1], g[2], x);
323 emit_SEND(bld, x, g[3], g[4])->sfid++;
324
325 v->calculate_cfg();
326 bblock_t *block0 = v->cfg->blocks[0];
327 ASSERT_EQ(0, block0->start_ip);
328 ASSERT_EQ(1, block0->end_ip);
329
330 lower_scoreboard(v);
331 ASSERT_EQ(0, block0->start_ip);
332 ASSERT_EQ(2, block0->end_ip);
333
334 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
335
336 fs_inst *sync = instruction(block0, 1);
337 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
338 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
339
340 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
341 }
342
343 TEST_F(scoreboard_test, WAW_inorder_inorder)
344 {
345 const fs_builder &bld = v->bld;
346 fs_reg g[16];
347 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
348 g[i] = v->vgrf(glsl_type::int_type);
349
350 fs_reg x = v->vgrf(glsl_type::int_type);
351 bld.ADD( x, g[1], g[2]);
352 bld.MUL(g[3], g[4], g[5]);
353 bld.AND( x, g[6], g[7]);
354
355 v->calculate_cfg();
356 bblock_t *block0 = v->cfg->blocks[0];
357 ASSERT_EQ(0, block0->start_ip);
358 ASSERT_EQ(2, block0->end_ip);
359
360 lower_scoreboard(v);
361 ASSERT_EQ(0, block0->start_ip);
362 ASSERT_EQ(2, block0->end_ip);
363
364 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
365 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
366
367 /* NOTE: We only need this RegDist if a long instruction is followed by a
368 * short one. The pass is currently conservative about this and adding the
369 * annotation.
370 */
371 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_regdist(2));
372 }
373
374 TEST_F(scoreboard_test, WAW_inorder_outoforder)
375 {
376 const fs_builder &bld = v->bld;
377 fs_reg g[16];
378 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
379 g[i] = v->vgrf(glsl_type::int_type);
380
381 fs_reg x = v->vgrf(glsl_type::int_type);
382 bld.ADD( x, g[1], g[2]);
383 bld.MUL( g[3], g[4], g[5]);
384 emit_SEND(bld, x, g[6], g[7]);
385
386 v->calculate_cfg();
387 bblock_t *block0 = v->cfg->blocks[0];
388 ASSERT_EQ(0, block0->start_ip);
389 ASSERT_EQ(2, block0->end_ip);
390
391 lower_scoreboard(v);
392 ASSERT_EQ(0, block0->start_ip);
393 ASSERT_EQ(2, block0->end_ip);
394
395 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
396 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
397 EXPECT_EQ(instruction(block0, 2)->sched,
398 (tgl_swsb { .regdist = 2, .sbid = 0, .mode = TGL_SBID_SET }));
399 }
400
401 TEST_F(scoreboard_test, WAW_outoforder_inorder)
402 {
403 const fs_builder &bld = v->bld;
404 fs_reg g[16];
405 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
406 g[i] = v->vgrf(glsl_type::int_type);
407
408 fs_reg x = v->vgrf(glsl_type::int_type);
409 emit_SEND(bld, x, g[1], g[2]);
410 bld.MUL( g[3], g[4], g[5]);
411 bld.AND( x, g[6], g[7]);
412
413 v->calculate_cfg();
414 bblock_t *block0 = v->cfg->blocks[0];
415 ASSERT_EQ(0, block0->start_ip);
416 ASSERT_EQ(2, block0->end_ip);
417
418 lower_scoreboard(v);
419 ASSERT_EQ(0, block0->start_ip);
420 ASSERT_EQ(2, block0->end_ip);
421
422 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
423 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
424 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
425 }
426
427 TEST_F(scoreboard_test, WAW_outoforder_outoforder)
428 {
429 const fs_builder &bld = v->bld;
430 fs_reg g[16];
431 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
432 g[i] = v->vgrf(glsl_type::int_type);
433
434 fs_reg x = v->vgrf(glsl_type::int_type);
435 emit_SEND(bld, x, g[1], g[2]);
436 emit_SEND(bld, x, g[3], g[4])->sfid++;
437
438 v->calculate_cfg();
439 bblock_t *block0 = v->cfg->blocks[0];
440 ASSERT_EQ(0, block0->start_ip);
441 ASSERT_EQ(1, block0->end_ip);
442
443 lower_scoreboard(v);
444 ASSERT_EQ(0, block0->start_ip);
445 ASSERT_EQ(2, block0->end_ip);
446
447 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
448
449 fs_inst *sync = instruction(block0, 1);
450 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
451 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
452
453 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
454 }
455
456
457 TEST_F(scoreboard_test, loop1)
458 {
459 const fs_builder &bld = v->bld;
460 fs_reg g[16];
461 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
462 g[i] = v->vgrf(glsl_type::int_type);
463
464 fs_reg x = v->vgrf(glsl_type::int_type);
465 bld.XOR( x, g[1], g[2]);
466
467 bld.emit(BRW_OPCODE_DO);
468
469 bld.ADD( x, g[1], g[2]);
470 bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
471
472 bld.MUL( x, g[1], g[2]);
473
474 v->calculate_cfg();
475 lower_scoreboard(v);
476
477 bblock_t *body = v->cfg->blocks[2];
478 fs_inst *add = instruction(body, 0);
479 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
480 EXPECT_EQ(add->sched, tgl_swsb_regdist(1));
481
482 bblock_t *last_block = v->cfg->blocks[3];
483 fs_inst *mul = instruction(last_block, 0);
484 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
485 EXPECT_EQ(mul->sched, tgl_swsb_regdist(1));
486 }
487
488 TEST_F(scoreboard_test, loop2)
489 {
490 const fs_builder &bld = v->bld;
491 fs_reg g[16];
492 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
493 g[i] = v->vgrf(glsl_type::int_type);
494
495 fs_reg x = v->vgrf(glsl_type::int_type);
496 bld.XOR( x, g[1], g[2]);
497 bld.XOR(g[3], g[1], g[2]);
498 bld.XOR(g[4], g[1], g[2]);
499 bld.XOR(g[5], g[1], g[2]);
500
501 bld.emit(BRW_OPCODE_DO);
502
503 bld.ADD( x, g[1], g[2]);
504 bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
505
506 bld.MUL( x, g[1], g[2]);
507
508 v->calculate_cfg();
509 lower_scoreboard(v);
510
511 /* Now the write in ADD has the tightest RegDist for both ADD and MUL. */
512
513 bblock_t *body = v->cfg->blocks[2];
514 fs_inst *add = instruction(body, 0);
515 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
516 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
517
518 bblock_t *last_block = v->cfg->blocks[3];
519 fs_inst *mul = instruction(last_block, 0);
520 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
521 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
522 }
523
524 TEST_F(scoreboard_test, loop3)
525 {
526 const fs_builder &bld = v->bld;
527 fs_reg g[16];
528 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
529 g[i] = v->vgrf(glsl_type::int_type);
530
531 fs_reg x = v->vgrf(glsl_type::int_type);
532 bld.XOR( x, g[1], g[2]);
533
534 bld.emit(BRW_OPCODE_DO);
535
536 /* For the ADD in the loop body this extra distance will always apply. */
537 bld.XOR(g[3], g[1], g[2]);
538 bld.XOR(g[4], g[1], g[2]);
539 bld.XOR(g[5], g[1], g[2]);
540 bld.XOR(g[6], g[1], g[2]);
541
542 bld.ADD( x, g[1], g[2]);
543 bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
544
545 bld.MUL( x, g[1], g[2]);
546
547 v->calculate_cfg();
548 lower_scoreboard(v);
549
550 bblock_t *body = v->cfg->blocks[2];
551 fs_inst *add = instruction(body, 4);
552 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
553 EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
554
555 bblock_t *last_block = v->cfg->blocks[3];
556 fs_inst *mul = instruction(last_block, 0);
557 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
558 EXPECT_EQ(mul->sched, tgl_swsb_regdist(1));
559 }
560
561
562 TEST_F(scoreboard_test, conditional1)
563 {
564 const fs_builder &bld = v->bld;
565 fs_reg g[16];
566 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
567 g[i] = v->vgrf(glsl_type::int_type);
568
569 fs_reg x = v->vgrf(glsl_type::int_type);
570 bld.XOR( x, g[1], g[2]);
571 bld.emit(BRW_OPCODE_IF);
572
573 bld.ADD( x, g[1], g[2]);
574
575 bld.emit(BRW_OPCODE_ENDIF);
576 bld.MUL( x, g[1], g[2]);
577
578 v->calculate_cfg();
579 lower_scoreboard(v);
580
581 bblock_t *body = v->cfg->blocks[1];
582 fs_inst *add = instruction(body, 0);
583 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
584 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
585
586 bblock_t *last_block = v->cfg->blocks[2];
587 fs_inst *mul = instruction(last_block, 1);
588 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
589 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
590 }
591
592 TEST_F(scoreboard_test, conditional2)
593 {
594 const fs_builder &bld = v->bld;
595 fs_reg g[16];
596 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
597 g[i] = v->vgrf(glsl_type::int_type);
598
599 fs_reg x = v->vgrf(glsl_type::int_type);
600 bld.XOR( x, g[1], g[2]);
601 bld.XOR(g[3], g[1], g[2]);
602 bld.XOR(g[4], g[1], g[2]);
603 bld.XOR(g[5], g[1], g[2]);
604 bld.emit(BRW_OPCODE_IF);
605
606 bld.ADD( x, g[1], g[2]);
607
608 bld.emit(BRW_OPCODE_ENDIF);
609 bld.MUL( x, g[1], g[2]);
610
611 v->calculate_cfg();
612 lower_scoreboard(v);
613
614 bblock_t *body = v->cfg->blocks[1];
615 fs_inst *add = instruction(body, 0);
616 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
617 EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
618
619 bblock_t *last_block = v->cfg->blocks[2];
620 fs_inst *mul = instruction(last_block, 1);
621 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
622 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
623 }
624
625 TEST_F(scoreboard_test, conditional3)
626 {
627 const fs_builder &bld = v->bld;
628 fs_reg g[16];
629 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
630 g[i] = v->vgrf(glsl_type::int_type);
631
632 fs_reg x = v->vgrf(glsl_type::int_type);
633 bld.XOR( x, g[1], g[2]);
634 bld.emit(BRW_OPCODE_IF);
635
636 bld.XOR(g[3], g[1], g[2]);
637 bld.XOR(g[4], g[1], g[2]);
638 bld.XOR(g[5], g[1], g[2]);
639 bld.ADD( x, g[1], g[2]);
640
641 bld.emit(BRW_OPCODE_ENDIF);
642 bld.MUL( x, g[1], g[2]);
643
644 v->calculate_cfg();
645 lower_scoreboard(v);
646
647 bblock_t *body = v->cfg->blocks[1];
648 fs_inst *add = instruction(body, 3);
649 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
650 EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
651
652 bblock_t *last_block = v->cfg->blocks[2];
653 fs_inst *mul = instruction(last_block, 1);
654 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
655 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
656 }
657
658 TEST_F(scoreboard_test, conditional4)
659 {
660 const fs_builder &bld = v->bld;
661 fs_reg g[16];
662 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
663 g[i] = v->vgrf(glsl_type::int_type);
664
665 fs_reg x = v->vgrf(glsl_type::int_type);
666 bld.XOR( x, g[1], g[2]);
667 bld.emit(BRW_OPCODE_IF);
668
669 bld.ADD( x, g[1], g[2]);
670 bld.XOR(g[3], g[1], g[2]);
671 bld.XOR(g[4], g[1], g[2]);
672 bld.XOR(g[5], g[1], g[2]);
673
674 bld.emit(BRW_OPCODE_ENDIF);
675 bld.MUL( x, g[1], g[2]);
676
677 v->calculate_cfg();
678 lower_scoreboard(v);
679
680 bblock_t *body = v->cfg->blocks[1];
681 fs_inst *add = instruction(body, 0);
682 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
683 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
684
685 bblock_t *last_block = v->cfg->blocks[2];
686 fs_inst *mul = instruction(last_block, 1);
687 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
688 EXPECT_EQ(mul->sched, tgl_swsb_regdist(3));
689 }
690
691 TEST_F(scoreboard_test, conditional5)
692 {
693 const fs_builder &bld = v->bld;
694 fs_reg g[16];
695 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
696 g[i] = v->vgrf(glsl_type::int_type);
697
698 fs_reg x = v->vgrf(glsl_type::int_type);
699 bld.XOR( x, g[1], g[2]);
700 bld.emit(BRW_OPCODE_IF);
701
702 bld.ADD( x, g[1], g[2]);
703 bld.emit(BRW_OPCODE_ELSE);
704
705 bld.ROL( x, g[1], g[2]);
706
707 bld.emit(BRW_OPCODE_ENDIF);
708 bld.MUL( x, g[1], g[2]);
709
710 v->calculate_cfg();
711 lower_scoreboard(v);
712
713 bblock_t *then_body = v->cfg->blocks[1];
714 fs_inst *add = instruction(then_body, 0);
715 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
716 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
717
718 bblock_t *else_body = v->cfg->blocks[2];
719 fs_inst *rol = instruction(else_body, 0);
720 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
721 EXPECT_EQ(rol->sched, tgl_swsb_regdist(2));
722
723 bblock_t *last_block = v->cfg->blocks[3];
724 fs_inst *mul = instruction(last_block, 1);
725 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
726 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
727 }
728
729 TEST_F(scoreboard_test, conditional6)
730 {
731 const fs_builder &bld = v->bld;
732 fs_reg g[16];
733 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
734 g[i] = v->vgrf(glsl_type::int_type);
735
736 fs_reg x = v->vgrf(glsl_type::int_type);
737 bld.XOR( x, g[1], g[2]);
738 bld.emit(BRW_OPCODE_IF);
739
740 bld.XOR(g[3], g[1], g[2]);
741 bld.XOR(g[4], g[1], g[2]);
742 bld.XOR(g[5], g[1], g[2]);
743 bld.ADD( x, g[1], g[2]);
744 bld.emit(BRW_OPCODE_ELSE);
745
746 bld.XOR(g[6], g[1], g[2]);
747 bld.XOR(g[7], g[1], g[2]);
748 bld.XOR(g[8], g[1], g[2]);
749 bld.XOR(g[9], g[1], g[2]);
750 bld.ROL( x, g[1], g[2]);
751
752 bld.emit(BRW_OPCODE_ENDIF);
753 bld.MUL( x, g[1], g[2]);
754
755 v->calculate_cfg();
756 lower_scoreboard(v);
757
758 bblock_t *then_body = v->cfg->blocks[1];
759 fs_inst *add = instruction(then_body, 3);
760 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
761 EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
762
763 bblock_t *else_body = v->cfg->blocks[2];
764 fs_inst *rol = instruction(else_body, 4);
765 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
766 EXPECT_EQ(rol->sched, tgl_swsb_regdist(6));
767
768 bblock_t *last_block = v->cfg->blocks[3];
769 fs_inst *mul = instruction(last_block, 1);
770 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
771 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
772 }
773
774 TEST_F(scoreboard_test, conditional7)
775 {
776 const fs_builder &bld = v->bld;
777 fs_reg g[16];
778 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
779 g[i] = v->vgrf(glsl_type::int_type);
780
781 fs_reg x = v->vgrf(glsl_type::int_type);
782 bld.XOR( x, g[1], g[2]);
783 bld.emit(BRW_OPCODE_IF);
784
785 bld.ADD( x, g[1], g[2]);
786 bld.XOR(g[3], g[1], g[2]);
787 bld.XOR(g[4], g[1], g[2]);
788 bld.XOR(g[5], g[1], g[2]);
789 bld.emit(BRW_OPCODE_ELSE);
790
791 bld.ROL( x, g[1], g[2]);
792 bld.XOR(g[6], g[1], g[2]);
793 bld.XOR(g[7], g[1], g[2]);
794 bld.XOR(g[8], g[1], g[2]);
795 bld.XOR(g[9], g[1], g[2]);
796
797 bld.emit(BRW_OPCODE_ENDIF);
798 bld.MUL( x, g[1], g[2]);
799
800 v->calculate_cfg();
801 lower_scoreboard(v);
802
803 bblock_t *then_body = v->cfg->blocks[1];
804 fs_inst *add = instruction(then_body, 0);
805 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
806 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
807
808 bblock_t *else_body = v->cfg->blocks[2];
809 fs_inst *rol = instruction(else_body, 0);
810 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
811 EXPECT_EQ(rol->sched, tgl_swsb_regdist(2));
812
813 bblock_t *last_block = v->cfg->blocks[3];
814 fs_inst *mul = instruction(last_block, 1);
815 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
816 EXPECT_EQ(mul->sched, tgl_swsb_regdist(6));
817 }
818
819 TEST_F(scoreboard_test, conditional8)
820 {
821 const fs_builder &bld = v->bld;
822 fs_reg g[16];
823 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
824 g[i] = v->vgrf(glsl_type::int_type);
825
826 fs_reg x = v->vgrf(glsl_type::int_type);
827 bld.XOR( x, g[1], g[2]);
828 bld.XOR(g[3], g[1], g[2]);
829 bld.XOR(g[4], g[1], g[2]);
830 bld.XOR(g[5], g[1], g[2]);
831 bld.XOR(g[6], g[1], g[2]);
832 bld.XOR(g[7], g[1], g[2]);
833 bld.emit(BRW_OPCODE_IF);
834
835 bld.ADD( x, g[1], g[2]);
836 bld.emit(BRW_OPCODE_ELSE);
837
838 bld.ROL( x, g[1], g[2]);
839
840 bld.emit(BRW_OPCODE_ENDIF);
841 bld.MUL( x, g[1], g[2]);
842
843 v->calculate_cfg();
844 lower_scoreboard(v);
845
846 bblock_t *then_body = v->cfg->blocks[1];
847 fs_inst *add = instruction(then_body, 0);
848 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
849 EXPECT_EQ(add->sched, tgl_swsb_regdist(7));
850
851 /* Note that the ROL will have RegDist 2 and not 7, illustrating the
852 * physical CFG edge between the then-block and the else-block.
853 */
854 bblock_t *else_body = v->cfg->blocks[2];
855 fs_inst *rol = instruction(else_body, 0);
856 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
857 EXPECT_EQ(rol->sched, tgl_swsb_regdist(2));
858
859 bblock_t *last_block = v->cfg->blocks[3];
860 fs_inst *mul = instruction(last_block, 1);
861 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
862 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
863 }