xref: /aosp_15_r20/external/mesa3d/src/intel/compiler/test_fs_scoreboard.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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_fs_builder.h"
27 #include "brw_cfg.h"
28 
29 using namespace brw;
30 
31 class scoreboard_test : public ::testing::Test {
32 protected:
33    scoreboard_test();
34    ~scoreboard_test() override;
35 
36    struct brw_compiler *compiler;
37    struct brw_compile_params params;
38    struct intel_device_info *devinfo;
39    void *ctx;
40    struct brw_wm_prog_data *prog_data;
41    struct gl_shader_program *shader_prog;
42    fs_visitor *v;
43    fs_builder bld;
44 };
45 
scoreboard_test()46 scoreboard_test::scoreboard_test()
47    : bld(NULL, 0)
48 {
49    ctx = ralloc_context(NULL);
50    compiler = rzalloc(ctx, struct brw_compiler);
51    devinfo = rzalloc(ctx, struct intel_device_info);
52    devinfo->ver = 12;
53    devinfo->verx10 = devinfo->ver * 10;
54 
55    compiler->devinfo = devinfo;
56    brw_init_isa_info(&compiler->isa, devinfo);
57 
58    params = {};
59    params.mem_ctx = ctx;
60 
61    prog_data = ralloc(ctx, struct brw_wm_prog_data);
62    nir_shader *shader =
63       nir_shader_create(ctx, MESA_SHADER_FRAGMENT, NULL, NULL);
64 
65    v = new fs_visitor(compiler, &params, NULL, &prog_data->base, shader, 8,
66                       false, false);
67 
68    bld = fs_builder(v).at_end();
69 }
70 
~scoreboard_test()71 scoreboard_test::~scoreboard_test()
72 {
73    delete v;
74    v = NULL;
75 
76    ralloc_free(ctx);
77    ctx = NULL;
78 }
79 
80 static fs_inst *
instruction(bblock_t * block,int num)81 instruction(bblock_t *block, int num)
82 {
83    fs_inst *inst = (fs_inst *)block->start();
84    for (int i = 0; i < num; i++) {
85       inst = (fs_inst *)inst->next;
86    }
87    return inst;
88 }
89 
90 static void
lower_scoreboard(fs_visitor * v)91 lower_scoreboard(fs_visitor *v)
92 {
93    const bool print = getenv("TEST_DEBUG");
94 
95    if (print) {
96       fprintf(stderr, "= Before =\n");
97       v->cfg->dump();
98    }
99 
100    brw_fs_lower_scoreboard(*v);
101 
102    if (print) {
103       fprintf(stderr, "\n= After =\n");
104       v->cfg->dump();
105    }
106 }
107 
108 fs_inst *
emit_SEND(const fs_builder & bld,const brw_reg & dst,const brw_reg & desc,const brw_reg & payload)109 emit_SEND(const fs_builder &bld, const brw_reg &dst,
110           const brw_reg &desc, const brw_reg &payload)
111 {
112    fs_inst *inst = bld.emit(SHADER_OPCODE_SEND, dst, desc, desc, payload);
113    inst->mlen = 1;
114    return inst;
115 }
116 
117 static tgl_swsb
tgl_swsb_testcase(unsigned regdist,unsigned sbid,enum tgl_sbid_mode mode)118 tgl_swsb_testcase(unsigned regdist, unsigned sbid, enum tgl_sbid_mode mode)
119 {
120    tgl_swsb swsb = tgl_swsb_sbid(mode, sbid);
121    swsb.regdist = regdist;
122    return swsb;
123 }
124 
operator ==(const tgl_swsb & a,const tgl_swsb & b)125 bool operator ==(const tgl_swsb &a, const tgl_swsb &b)
126 {
127    return a.mode == b.mode &&
128           a.regdist == b.regdist &&
129           (a.mode == TGL_SBID_NULL || a.sbid == b.sbid);
130 }
131 
operator <<(std::ostream & os,const tgl_swsb & swsb)132 std::ostream &operator<<(std::ostream &os, const tgl_swsb &swsb) {
133    char *buf;
134    size_t len;
135    FILE *f = open_memstream(&buf, &len);
136 
137    /* Because we don't have a devinfo to pass here, for TGL we'll see
138     * F@1 annotations instead of @1 since the float pipe is the only one
139     * used there.
140     */
141    brw_print_swsb(f, NULL, swsb);
142    fflush(f);
143    fclose(f);
144 
145    os << buf;
146    free(buf);
147 
148    return os;
149 }
150 
TEST_F(scoreboard_test,RAW_inorder_inorder)151 TEST_F(scoreboard_test, RAW_inorder_inorder)
152 {
153    brw_reg g[16];
154    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
155       g[i] = bld.vgrf(BRW_TYPE_D);
156 
157    brw_reg x = bld.vgrf(BRW_TYPE_D);
158    brw_reg y = bld.vgrf(BRW_TYPE_D);
159    bld.ADD(   x, g[1], g[2]);
160    bld.MUL(   y, g[3], g[4]);
161    bld.AND(g[5],    x,    y);
162 
163    brw_calculate_cfg(*v);
164    bblock_t *block0 = v->cfg->blocks[0];
165    ASSERT_EQ(0, block0->start_ip);
166    ASSERT_EQ(2, block0->end_ip);
167 
168    lower_scoreboard(v);
169    ASSERT_EQ(0, block0->start_ip);
170    ASSERT_EQ(2, block0->end_ip);
171 
172    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
173    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
174    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_regdist(1));
175 }
176 
TEST_F(scoreboard_test,RAW_inorder_outoforder)177 TEST_F(scoreboard_test, RAW_inorder_outoforder)
178 {
179    brw_reg g[16];
180    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
181       g[i] = bld.vgrf(BRW_TYPE_D);
182 
183    brw_reg x = bld.vgrf(BRW_TYPE_D);
184    bld.ADD(          x, g[1], g[2]);
185    bld.MUL(       g[3], g[4], g[5]);
186    emit_SEND(bld, g[6], g[7],    x);
187 
188    brw_calculate_cfg(*v);
189    bblock_t *block0 = v->cfg->blocks[0];
190    ASSERT_EQ(0, block0->start_ip);
191    ASSERT_EQ(2, block0->end_ip);
192 
193    lower_scoreboard(v);
194    ASSERT_EQ(0, block0->start_ip);
195    ASSERT_EQ(2, block0->end_ip);
196 
197    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
198    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
199    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_testcase(2, 0, TGL_SBID_SET));
200 }
201 
TEST_F(scoreboard_test,RAW_outoforder_inorder)202 TEST_F(scoreboard_test, RAW_outoforder_inorder)
203 {
204    brw_reg g[16];
205    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
206       g[i] = bld.vgrf(BRW_TYPE_D);
207 
208    brw_reg x = bld.vgrf(BRW_TYPE_D);
209    brw_reg y = bld.vgrf(BRW_TYPE_D);
210    emit_SEND(bld,    x, g[1], g[2]);
211    bld.MUL(          y, g[3], g[4]);
212    bld.AND(       g[5],    x,    y);
213 
214    brw_calculate_cfg(*v);
215    bblock_t *block0 = v->cfg->blocks[0];
216    ASSERT_EQ(0, block0->start_ip);
217    ASSERT_EQ(2, block0->end_ip);
218 
219    lower_scoreboard(v);
220    ASSERT_EQ(0, block0->start_ip);
221    ASSERT_EQ(2, block0->end_ip);
222 
223    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
224    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
225    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_testcase(1, 0, TGL_SBID_DST));
226 }
227 
TEST_F(scoreboard_test,RAW_outoforder_outoforder)228 TEST_F(scoreboard_test, RAW_outoforder_outoforder)
229 {
230    brw_reg g[16];
231    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
232       g[i] = bld.vgrf(BRW_TYPE_D);
233 
234    /* The second SEND depends on the first, and would need to refer to two
235     * SBIDs.  Since it is not possible we expect a SYNC instruction to be
236     * added.
237     */
238    brw_reg x = bld.vgrf(BRW_TYPE_D);
239    emit_SEND(bld,    x, g[1], g[2]);
240    emit_SEND(bld, g[3],    x, g[4])->sfid++;
241 
242    brw_calculate_cfg(*v);
243    bblock_t *block0 = v->cfg->blocks[0];
244    ASSERT_EQ(0, block0->start_ip);
245    ASSERT_EQ(1, block0->end_ip);
246 
247    lower_scoreboard(v);
248    ASSERT_EQ(0, block0->start_ip);
249    ASSERT_EQ(2, block0->end_ip);
250 
251    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
252 
253    fs_inst *sync = instruction(block0, 1);
254    EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
255    EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
256 
257    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
258 }
259 
TEST_F(scoreboard_test,WAR_inorder_inorder)260 TEST_F(scoreboard_test, WAR_inorder_inorder)
261 {
262    brw_reg g[16];
263    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
264       g[i] = bld.vgrf(BRW_TYPE_D);
265 
266    brw_reg x = bld.vgrf(BRW_TYPE_D);
267    bld.ADD(g[1],    x, g[2]);
268    bld.MUL(g[3], g[4], g[5]);
269    bld.AND(   x, g[6], g[7]);
270 
271    brw_calculate_cfg(*v);
272    bblock_t *block0 = v->cfg->blocks[0];
273    ASSERT_EQ(0, block0->start_ip);
274    ASSERT_EQ(2, block0->end_ip);
275 
276    lower_scoreboard(v);
277    ASSERT_EQ(0, block0->start_ip);
278    ASSERT_EQ(2, block0->end_ip);
279 
280    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
281    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
282    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_null());
283 }
284 
TEST_F(scoreboard_test,WAR_inorder_outoforder)285 TEST_F(scoreboard_test, WAR_inorder_outoforder)
286 {
287    brw_reg g[16];
288    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
289       g[i] = bld.vgrf(BRW_TYPE_D);
290 
291    brw_reg x = bld.vgrf(BRW_TYPE_D);
292    bld.ADD(       g[1],    x, g[2]);
293    bld.MUL(       g[3], g[4], g[5]);
294    emit_SEND(bld,    x, g[6], g[7]);
295 
296    brw_calculate_cfg(*v);
297    bblock_t *block0 = v->cfg->blocks[0];
298    ASSERT_EQ(0, block0->start_ip);
299    ASSERT_EQ(2, block0->end_ip);
300 
301    lower_scoreboard(v);
302    ASSERT_EQ(0, block0->start_ip);
303    ASSERT_EQ(2, block0->end_ip);
304 
305    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
306    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
307    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_testcase(2, 0, TGL_SBID_SET));
308 }
309 
TEST_F(scoreboard_test,WAR_outoforder_inorder)310 TEST_F(scoreboard_test, WAR_outoforder_inorder)
311 {
312    brw_reg g[16];
313    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
314       g[i] = bld.vgrf(BRW_TYPE_D);
315 
316    brw_reg x = bld.vgrf(BRW_TYPE_D);
317    emit_SEND(bld, g[1], g[2],    x);
318    bld.MUL(       g[4], g[5], g[6]);
319    bld.AND(          x, g[7], g[8]);
320 
321    brw_calculate_cfg(*v);
322    bblock_t *block0 = v->cfg->blocks[0];
323    ASSERT_EQ(0, block0->start_ip);
324    ASSERT_EQ(2, block0->end_ip);
325 
326    lower_scoreboard(v);
327    ASSERT_EQ(0, block0->start_ip);
328    ASSERT_EQ(2, block0->end_ip);
329 
330    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
331    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
332    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
333 }
334 
TEST_F(scoreboard_test,WAR_outoforder_outoforder)335 TEST_F(scoreboard_test, WAR_outoforder_outoforder)
336 {
337    brw_reg g[16];
338    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
339       g[i] = bld.vgrf(BRW_TYPE_D);
340 
341    brw_reg x = bld.vgrf(BRW_TYPE_D);
342    emit_SEND(bld, g[1], g[2],    x);
343    emit_SEND(bld,    x, g[3], g[4])->sfid++;
344 
345    brw_calculate_cfg(*v);
346    bblock_t *block0 = v->cfg->blocks[0];
347    ASSERT_EQ(0, block0->start_ip);
348    ASSERT_EQ(1, block0->end_ip);
349 
350    lower_scoreboard(v);
351    ASSERT_EQ(0, block0->start_ip);
352    ASSERT_EQ(2, block0->end_ip);
353 
354    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
355 
356    fs_inst *sync = instruction(block0, 1);
357    EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
358    EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
359 
360    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
361 }
362 
TEST_F(scoreboard_test,WAW_inorder_inorder)363 TEST_F(scoreboard_test, WAW_inorder_inorder)
364 {
365    brw_reg g[16];
366    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
367       g[i] = bld.vgrf(BRW_TYPE_D);
368 
369    brw_reg x = bld.vgrf(BRW_TYPE_D);
370    bld.ADD(   x, g[1], g[2]);
371    bld.MUL(g[3], g[4], g[5]);
372    bld.AND(   x, g[6], g[7]);
373 
374    brw_calculate_cfg(*v);
375    bblock_t *block0 = v->cfg->blocks[0];
376    ASSERT_EQ(0, block0->start_ip);
377    ASSERT_EQ(2, block0->end_ip);
378 
379    lower_scoreboard(v);
380    ASSERT_EQ(0, block0->start_ip);
381    ASSERT_EQ(2, block0->end_ip);
382 
383    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
384    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
385 
386    /* NOTE: We only need this RegDist if a long instruction is followed by a
387     * short one.  The pass is currently conservative about this and adding the
388     * annotation.
389     */
390    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_regdist(2));
391 }
392 
TEST_F(scoreboard_test,WAW_inorder_outoforder)393 TEST_F(scoreboard_test, WAW_inorder_outoforder)
394 {
395    brw_reg g[16];
396    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
397       g[i] = bld.vgrf(BRW_TYPE_D);
398 
399    brw_reg x = bld.vgrf(BRW_TYPE_D);
400    bld.ADD(          x, g[1], g[2]);
401    bld.MUL(       g[3], g[4], g[5]);
402    emit_SEND(bld,    x, g[6], g[7]);
403 
404    brw_calculate_cfg(*v);
405    bblock_t *block0 = v->cfg->blocks[0];
406    ASSERT_EQ(0, block0->start_ip);
407    ASSERT_EQ(2, block0->end_ip);
408 
409    lower_scoreboard(v);
410    ASSERT_EQ(0, block0->start_ip);
411    ASSERT_EQ(2, block0->end_ip);
412 
413    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
414    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
415    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_testcase(2, 0, TGL_SBID_SET));
416 }
417 
TEST_F(scoreboard_test,WAW_outoforder_inorder)418 TEST_F(scoreboard_test, WAW_outoforder_inorder)
419 {
420    brw_reg g[16];
421    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
422       g[i] = bld.vgrf(BRW_TYPE_D);
423 
424    brw_reg x = bld.vgrf(BRW_TYPE_D);
425    emit_SEND(bld,    x, g[1], g[2]);
426    bld.MUL(       g[3], g[4], g[5]);
427    bld.AND(          x, g[6], g[7]);
428 
429    brw_calculate_cfg(*v);
430    bblock_t *block0 = v->cfg->blocks[0];
431    ASSERT_EQ(0, block0->start_ip);
432    ASSERT_EQ(2, block0->end_ip);
433 
434    lower_scoreboard(v);
435    ASSERT_EQ(0, block0->start_ip);
436    ASSERT_EQ(2, block0->end_ip);
437 
438    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
439    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
440    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
441 }
442 
TEST_F(scoreboard_test,WAW_outoforder_outoforder)443 TEST_F(scoreboard_test, WAW_outoforder_outoforder)
444 {
445    brw_reg g[16];
446    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
447       g[i] = bld.vgrf(BRW_TYPE_D);
448 
449    brw_reg x = bld.vgrf(BRW_TYPE_D);
450    emit_SEND(bld, x, g[1], g[2]);
451    emit_SEND(bld, x, g[3], g[4])->sfid++;
452 
453    brw_calculate_cfg(*v);
454    bblock_t *block0 = v->cfg->blocks[0];
455    ASSERT_EQ(0, block0->start_ip);
456    ASSERT_EQ(1, block0->end_ip);
457 
458    lower_scoreboard(v);
459    ASSERT_EQ(0, block0->start_ip);
460    ASSERT_EQ(2, block0->end_ip);
461 
462    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
463 
464    fs_inst *sync = instruction(block0, 1);
465    EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
466    EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
467 
468    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
469 }
470 
471 
TEST_F(scoreboard_test,loop1)472 TEST_F(scoreboard_test, loop1)
473 {
474    brw_reg g[16];
475    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
476       g[i] = bld.vgrf(BRW_TYPE_D);
477 
478    brw_reg x = bld.vgrf(BRW_TYPE_D);
479    bld.XOR(   x, g[1], g[2]);
480 
481    bld.emit(BRW_OPCODE_DO);
482 
483    bld.ADD(   x, g[1], g[2]);
484    bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
485 
486    bld.MUL(   x, g[1], g[2]);
487 
488    brw_calculate_cfg(*v);
489    lower_scoreboard(v);
490 
491    bblock_t *body = v->cfg->blocks[2];
492    fs_inst *add = instruction(body, 0);
493    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
494    EXPECT_EQ(add->sched, tgl_swsb_regdist(1));
495 
496    bblock_t *last_block = v->cfg->blocks[3];
497    fs_inst *mul = instruction(last_block, 0);
498    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
499    EXPECT_EQ(mul->sched, tgl_swsb_regdist(1));
500 }
501 
TEST_F(scoreboard_test,loop2)502 TEST_F(scoreboard_test, loop2)
503 {
504    brw_reg g[16];
505    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
506       g[i] = bld.vgrf(BRW_TYPE_D);
507 
508    brw_reg x = bld.vgrf(BRW_TYPE_D);
509    bld.XOR(   x, g[1], g[2]);
510    bld.XOR(g[3], g[1], g[2]);
511    bld.XOR(g[4], g[1], g[2]);
512    bld.XOR(g[5], g[1], g[2]);
513 
514    bld.emit(BRW_OPCODE_DO);
515 
516    bld.ADD(   x, g[1], g[2]);
517    bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
518 
519    bld.MUL(   x, g[1], g[2]);
520 
521    brw_calculate_cfg(*v);
522    lower_scoreboard(v);
523 
524    /* Now the write in ADD has the tightest RegDist for both ADD and MUL. */
525 
526    bblock_t *body = v->cfg->blocks[2];
527    fs_inst *add = instruction(body, 0);
528    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
529    EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
530 
531    bblock_t *last_block = v->cfg->blocks[3];
532    fs_inst *mul = instruction(last_block, 0);
533    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
534    EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
535 }
536 
TEST_F(scoreboard_test,loop3)537 TEST_F(scoreboard_test, loop3)
538 {
539    brw_reg g[16];
540    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
541       g[i] = bld.vgrf(BRW_TYPE_D);
542 
543    brw_reg x = bld.vgrf(BRW_TYPE_D);
544    bld.XOR(   x, g[1], g[2]);
545 
546    bld.emit(BRW_OPCODE_DO);
547 
548    /* For the ADD in the loop body this extra distance will always apply. */
549    bld.XOR(g[3], g[1], g[2]);
550    bld.XOR(g[4], g[1], g[2]);
551    bld.XOR(g[5], g[1], g[2]);
552    bld.XOR(g[6], g[1], g[2]);
553 
554    bld.ADD(   x, g[1], g[2]);
555    bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
556 
557    bld.MUL(   x, g[1], g[2]);
558 
559    brw_calculate_cfg(*v);
560    lower_scoreboard(v);
561 
562    bblock_t *body = v->cfg->blocks[2];
563    fs_inst *add = instruction(body, 4);
564    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
565    EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
566 
567    bblock_t *last_block = v->cfg->blocks[3];
568    fs_inst *mul = instruction(last_block, 0);
569    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
570    EXPECT_EQ(mul->sched, tgl_swsb_regdist(1));
571 }
572 
573 
TEST_F(scoreboard_test,conditional1)574 TEST_F(scoreboard_test, conditional1)
575 {
576    brw_reg g[16];
577    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
578       g[i] = bld.vgrf(BRW_TYPE_D);
579 
580    brw_reg x = bld.vgrf(BRW_TYPE_D);
581    bld.XOR(   x, g[1], g[2]);
582    bld.emit(BRW_OPCODE_IF);
583 
584    bld.ADD(   x, g[1], g[2]);
585 
586    bld.emit(BRW_OPCODE_ENDIF);
587    bld.MUL(   x, g[1], g[2]);
588 
589    brw_calculate_cfg(*v);
590    lower_scoreboard(v);
591 
592    bblock_t *body = v->cfg->blocks[1];
593    fs_inst *add = instruction(body, 0);
594    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
595    EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
596 
597    bblock_t *last_block = v->cfg->blocks[2];
598    fs_inst *mul = instruction(last_block, 1);
599    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
600    EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
601 }
602 
TEST_F(scoreboard_test,conditional2)603 TEST_F(scoreboard_test, conditional2)
604 {
605    brw_reg g[16];
606    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
607       g[i] = bld.vgrf(BRW_TYPE_D);
608 
609    brw_reg x = bld.vgrf(BRW_TYPE_D);
610    bld.XOR(   x, g[1], g[2]);
611    bld.XOR(g[3], g[1], g[2]);
612    bld.XOR(g[4], g[1], g[2]);
613    bld.XOR(g[5], g[1], g[2]);
614    bld.emit(BRW_OPCODE_IF);
615 
616    bld.ADD(   x, g[1], g[2]);
617 
618    bld.emit(BRW_OPCODE_ENDIF);
619    bld.MUL(   x, g[1], g[2]);
620 
621    brw_calculate_cfg(*v);
622    lower_scoreboard(v);
623 
624    bblock_t *body = v->cfg->blocks[1];
625    fs_inst *add = instruction(body, 0);
626    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
627    EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
628 
629    bblock_t *last_block = v->cfg->blocks[2];
630    fs_inst *mul = instruction(last_block, 1);
631    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
632    EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
633 }
634 
TEST_F(scoreboard_test,conditional3)635 TEST_F(scoreboard_test, conditional3)
636 {
637    brw_reg g[16];
638    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
639       g[i] = bld.vgrf(BRW_TYPE_D);
640 
641    brw_reg x = bld.vgrf(BRW_TYPE_D);
642    bld.XOR(   x, g[1], g[2]);
643    bld.emit(BRW_OPCODE_IF);
644 
645    bld.XOR(g[3], g[1], g[2]);
646    bld.XOR(g[4], g[1], g[2]);
647    bld.XOR(g[5], g[1], g[2]);
648    bld.ADD(   x, g[1], g[2]);
649 
650    bld.emit(BRW_OPCODE_ENDIF);
651    bld.MUL(   x, g[1], g[2]);
652 
653    brw_calculate_cfg(*v);
654    lower_scoreboard(v);
655 
656    bblock_t *body = v->cfg->blocks[1];
657    fs_inst *add = instruction(body, 3);
658    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
659    EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
660 
661    bblock_t *last_block = v->cfg->blocks[2];
662    fs_inst *mul = instruction(last_block, 1);
663    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
664    EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
665 }
666 
TEST_F(scoreboard_test,conditional4)667 TEST_F(scoreboard_test, conditional4)
668 {
669    brw_reg g[16];
670    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
671       g[i] = bld.vgrf(BRW_TYPE_D);
672 
673    brw_reg x = bld.vgrf(BRW_TYPE_D);
674    bld.XOR(   x, g[1], g[2]);
675    bld.emit(BRW_OPCODE_IF);
676 
677    bld.ADD(   x, g[1], g[2]);
678    bld.XOR(g[3], g[1], g[2]);
679    bld.XOR(g[4], g[1], g[2]);
680    bld.XOR(g[5], g[1], g[2]);
681 
682    bld.emit(BRW_OPCODE_ENDIF);
683    bld.MUL(   x, g[1], g[2]);
684 
685    brw_calculate_cfg(*v);
686    lower_scoreboard(v);
687 
688    bblock_t *body = v->cfg->blocks[1];
689    fs_inst *add = instruction(body, 0);
690    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
691    EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
692 
693    bblock_t *last_block = v->cfg->blocks[2];
694    fs_inst *mul = instruction(last_block, 1);
695    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
696    EXPECT_EQ(mul->sched, tgl_swsb_regdist(3));
697 }
698 
TEST_F(scoreboard_test,conditional5)699 TEST_F(scoreboard_test, conditional5)
700 {
701    brw_reg g[16];
702    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
703       g[i] = bld.vgrf(BRW_TYPE_D);
704 
705    brw_reg x = bld.vgrf(BRW_TYPE_D);
706    bld.XOR(   x, g[1], g[2]);
707    bld.emit(BRW_OPCODE_IF);
708 
709    bld.ADD(   x, g[1], g[2]);
710    bld.emit(BRW_OPCODE_ELSE);
711 
712    bld.ROL(   x, g[1], g[2]);
713 
714    bld.emit(BRW_OPCODE_ENDIF);
715    bld.MUL(   x, g[1], g[2]);
716 
717    brw_calculate_cfg(*v);
718    lower_scoreboard(v);
719 
720    bblock_t *then_body = v->cfg->blocks[1];
721    fs_inst *add = instruction(then_body, 0);
722    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
723    EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
724 
725    bblock_t *else_body = v->cfg->blocks[2];
726    fs_inst *rol = instruction(else_body, 0);
727    EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
728    EXPECT_EQ(rol->sched, tgl_swsb_regdist(2));
729 
730    bblock_t *last_block = v->cfg->blocks[3];
731    fs_inst *mul = instruction(last_block, 1);
732    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
733    EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
734 }
735 
TEST_F(scoreboard_test,conditional6)736 TEST_F(scoreboard_test, conditional6)
737 {
738    brw_reg g[16];
739    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
740       g[i] = bld.vgrf(BRW_TYPE_D);
741 
742    brw_reg x = bld.vgrf(BRW_TYPE_D);
743    bld.XOR(   x, g[1], g[2]);
744    bld.emit(BRW_OPCODE_IF);
745 
746    bld.XOR(g[3], g[1], g[2]);
747    bld.XOR(g[4], g[1], g[2]);
748    bld.XOR(g[5], g[1], g[2]);
749    bld.ADD(   x, g[1], g[2]);
750    bld.emit(BRW_OPCODE_ELSE);
751 
752    bld.XOR(g[6], g[1], g[2]);
753    bld.XOR(g[7], g[1], g[2]);
754    bld.XOR(g[8], g[1], g[2]);
755    bld.XOR(g[9], g[1], g[2]);
756    bld.ROL(   x, g[1], g[2]);
757 
758    bld.emit(BRW_OPCODE_ENDIF);
759    bld.MUL(   x, g[1], g[2]);
760 
761    brw_calculate_cfg(*v);
762    lower_scoreboard(v);
763 
764    bblock_t *then_body = v->cfg->blocks[1];
765    fs_inst *add = instruction(then_body, 3);
766    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
767    EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
768 
769    bblock_t *else_body = v->cfg->blocks[2];
770    fs_inst *rol = instruction(else_body, 4);
771    EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
772    EXPECT_EQ(rol->sched, tgl_swsb_regdist(6));
773 
774    bblock_t *last_block = v->cfg->blocks[3];
775    fs_inst *mul = instruction(last_block, 1);
776    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
777    EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
778 }
779 
TEST_F(scoreboard_test,conditional7)780 TEST_F(scoreboard_test, conditional7)
781 {
782    brw_reg g[16];
783    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
784       g[i] = bld.vgrf(BRW_TYPE_D);
785 
786    brw_reg x = bld.vgrf(BRW_TYPE_D);
787    bld.XOR(   x, g[1], g[2]);
788    bld.emit(BRW_OPCODE_IF);
789 
790    bld.ADD(   x, g[1], g[2]);
791    bld.XOR(g[3], g[1], g[2]);
792    bld.XOR(g[4], g[1], g[2]);
793    bld.XOR(g[5], g[1], g[2]);
794    bld.emit(BRW_OPCODE_ELSE);
795 
796    bld.ROL(   x, g[1], g[2]);
797    bld.XOR(g[6], g[1], g[2]);
798    bld.XOR(g[7], g[1], g[2]);
799    bld.XOR(g[8], g[1], g[2]);
800    bld.XOR(g[9], g[1], g[2]);
801 
802    bld.emit(BRW_OPCODE_ENDIF);
803    bld.MUL(   x, g[1], g[2]);
804 
805    brw_calculate_cfg(*v);
806    lower_scoreboard(v);
807 
808    bblock_t *then_body = v->cfg->blocks[1];
809    fs_inst *add = instruction(then_body, 0);
810    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
811    EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
812 
813    bblock_t *else_body = v->cfg->blocks[2];
814    fs_inst *rol = instruction(else_body, 0);
815    EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
816    EXPECT_EQ(rol->sched, tgl_swsb_regdist(2));
817 
818    bblock_t *last_block = v->cfg->blocks[3];
819    fs_inst *mul = instruction(last_block, 1);
820    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
821    EXPECT_EQ(mul->sched, tgl_swsb_regdist(6));
822 }
823 
TEST_F(scoreboard_test,conditional8)824 TEST_F(scoreboard_test, conditional8)
825 {
826    brw_reg g[16];
827    for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
828       g[i] = bld.vgrf(BRW_TYPE_D);
829 
830    brw_reg x = bld.vgrf(BRW_TYPE_D);
831    bld.XOR(   x, g[1], g[2]);
832    bld.XOR(g[3], g[1], g[2]);
833    bld.XOR(g[4], g[1], g[2]);
834    bld.XOR(g[5], g[1], g[2]);
835    bld.XOR(g[6], g[1], g[2]);
836    bld.XOR(g[7], g[1], g[2]);
837    bld.emit(BRW_OPCODE_IF);
838 
839    bld.ADD(   x, g[1], g[2]);
840    bld.emit(BRW_OPCODE_ELSE);
841 
842    bld.ROL(   x, g[1], g[2]);
843 
844    bld.emit(BRW_OPCODE_ENDIF);
845    bld.MUL(   x, g[1], g[2]);
846 
847    brw_calculate_cfg(*v);
848    lower_scoreboard(v);
849 
850    bblock_t *then_body = v->cfg->blocks[1];
851    fs_inst *add = instruction(then_body, 0);
852    EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
853    EXPECT_EQ(add->sched, tgl_swsb_regdist(7));
854 
855    /* Note that the ROL will have RegDist 2 and not 7, illustrating the
856     * physical CFG edge between the then-block and the else-block.
857     */
858    bblock_t *else_body = v->cfg->blocks[2];
859    fs_inst *rol = instruction(else_body, 0);
860    EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
861    EXPECT_EQ(rol->sched, tgl_swsb_regdist(2));
862 
863    bblock_t *last_block = v->cfg->blocks[3];
864    fs_inst *mul = instruction(last_block, 1);
865    EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
866    EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
867 }
868 
TEST_F(scoreboard_test,gfx125_RaR_over_different_pipes)869 TEST_F(scoreboard_test, gfx125_RaR_over_different_pipes)
870 {
871    devinfo->verx10 = 125;
872    brw_init_isa_info(&compiler->isa, devinfo);
873 
874    brw_reg a = bld.vgrf(BRW_TYPE_D);
875    brw_reg b = bld.vgrf(BRW_TYPE_D);
876    brw_reg f = bld.vgrf(BRW_TYPE_F);
877    brw_reg x = bld.vgrf(BRW_TYPE_D);
878 
879    bld.ADD(f, x, x);
880    bld.ADD(a, x, x);
881    bld.ADD(x, b, b);
882 
883    brw_calculate_cfg(*v);
884    bblock_t *block0 = v->cfg->blocks[0];
885    ASSERT_EQ(0, block0->start_ip);
886    ASSERT_EQ(2, block0->end_ip);
887 
888    lower_scoreboard(v);
889    ASSERT_EQ(0, block0->start_ip);
890    ASSERT_EQ(2, block0->end_ip);
891 
892    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
893    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
894    EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_regdist(1));
895 }
896 
TEST_F(scoreboard_test,gitlab_issue_from_mr_29723)897 TEST_F(scoreboard_test, gitlab_issue_from_mr_29723)
898 {
899    brw_init_isa_info(&compiler->isa, devinfo);
900 
901    struct brw_reg a = brw_ud8_grf(29, 0);
902    struct brw_reg b = brw_ud8_grf(2, 0);
903 
904    auto bld1 = bld.exec_all().group(1, 0);
905    bld1.ADD(             a, stride(b, 0, 1, 0),    brw_imm_ud(256));
906    bld1.CMP(brw_null_reg(), stride(a, 2, 1, 2), stride(b, 0, 1, 0), BRW_CONDITIONAL_L);
907 
908    brw_calculate_cfg(*v);
909    bblock_t *block0 = v->cfg->blocks[0];
910    ASSERT_EQ(0, block0->start_ip);
911    ASSERT_EQ(1, block0->end_ip);
912 
913    lower_scoreboard(v);
914    ASSERT_EQ(0, block0->start_ip);
915    ASSERT_EQ(1, block0->end_ip);
916 
917    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
918    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_regdist(1));
919 }
920 
TEST_F(scoreboard_test,gitlab_issue_11069)921 TEST_F(scoreboard_test, gitlab_issue_11069)
922 {
923    brw_init_isa_info(&compiler->isa, devinfo);
924 
925    struct brw_reg a = brw_ud8_grf(76, 0);
926    struct brw_reg b = brw_ud8_grf(2, 0);
927 
928    auto bld1 = bld.exec_all().group(1, 0);
929    bld1.ADD(stride(a, 2, 1, 2), stride(b, 0, 1, 0),   brw_imm_ud(0x80));
930    bld1.CMP(    brw_null_reg(), stride(a, 0, 1, 0), stride(b, 0, 1, 0), BRW_CONDITIONAL_L);
931 
932    brw_calculate_cfg(*v);
933    bblock_t *block0 = v->cfg->blocks[0];
934    ASSERT_EQ(0, block0->start_ip);
935    ASSERT_EQ(1, block0->end_ip);
936 
937    lower_scoreboard(v);
938    ASSERT_EQ(0, block0->start_ip);
939    ASSERT_EQ(1, block0->end_ip);
940 
941    EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
942    EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_regdist(1));
943 }
944