i965/vec4: Replace vec4_instruction::regs_written with ::size_written field in bytes.
[mesa.git] / src / mesa / drivers / dri / i965 / test_vec4_cmod_propagation.cpp
1 /*
2 * Copyright © 2015 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 * Based on test_fs_cmod_propagation.cpp
24 */
25
26 #include <gtest/gtest.h>
27 #include "brw_vec4.h"
28 #include "brw_vec4_builder.h"
29 #include "brw_cfg.h"
30 #include "program/program.h"
31
32 using namespace brw;
33
34 class cmod_propagation_test : public ::testing::Test {
35 virtual void SetUp();
36
37 public:
38 struct brw_compiler *compiler;
39 struct gen_device_info *devinfo;
40 struct gl_context *ctx;
41 struct gl_shader_program *shader_prog;
42 struct brw_vue_prog_data *prog_data;
43 vec4_visitor *v;
44 };
45
46 class cmod_propagation_vec4_visitor : public vec4_visitor
47 {
48 public:
49 cmod_propagation_vec4_visitor(struct brw_compiler *compiler,
50 nir_shader *shader,
51 struct brw_vue_prog_data *prog_data)
52 : vec4_visitor(compiler, NULL, NULL, prog_data, shader, NULL,
53 false, -1)
54 {
55 prog_data->dispatch_mode = DISPATCH_MODE_4X2_DUAL_OBJECT;
56 }
57
58 protected:
59 /* Dummy implementation for pure virtual methods */
60 virtual dst_reg *make_reg_for_system_value(int location)
61 {
62 unreachable("Not reached");
63 }
64
65 virtual void setup_payload()
66 {
67 unreachable("Not reached");
68 }
69
70 virtual void emit_prolog()
71 {
72 unreachable("Not reached");
73 }
74
75 virtual void emit_program_code()
76 {
77 unreachable("Not reached");
78 }
79
80 virtual void emit_thread_end()
81 {
82 unreachable("Not reached");
83 }
84
85 virtual void emit_urb_write_header(int mrf)
86 {
87 unreachable("Not reached");
88 }
89
90 virtual vec4_instruction *emit_urb_write_opcode(bool complete)
91 {
92 unreachable("Not reached");
93 }
94 };
95
96
97 void cmod_propagation_test::SetUp()
98 {
99 ctx = (struct gl_context *)calloc(1, sizeof(*ctx));
100 compiler = (struct brw_compiler *)calloc(1, sizeof(*compiler));
101 devinfo = (struct gen_device_info *)calloc(1, sizeof(*devinfo));
102 prog_data = (struct brw_vue_prog_data *)calloc(1, sizeof(*prog_data));
103 compiler->devinfo = devinfo;
104
105 nir_shader *shader = nir_shader_create(NULL, MESA_SHADER_VERTEX, NULL);
106
107 v = new cmod_propagation_vec4_visitor(compiler, shader, prog_data);
108
109 devinfo->gen = 4;
110 }
111
112 static vec4_instruction *
113 instruction(bblock_t *block, int num)
114 {
115 vec4_instruction *inst = (vec4_instruction *)block->start();
116 for (int i = 0; i < num; i++) {
117 inst = (vec4_instruction *)inst->next;
118 }
119 return inst;
120 }
121
122 static bool
123 cmod_propagation(vec4_visitor *v)
124 {
125 const bool print = getenv("TEST_DEBUG");
126
127 if (print) {
128 fprintf(stderr, "= Before =\n");
129 v->dump_instructions();
130 }
131
132 bool ret = v->opt_cmod_propagation();
133
134 if (print) {
135 fprintf(stderr, "\n= After =\n");
136 v->dump_instructions();
137 }
138
139 return ret;
140 }
141
142 TEST_F(cmod_propagation_test, basic)
143 {
144 const vec4_builder bld = vec4_builder(v).at_end();
145 dst_reg dest = dst_reg(v, glsl_type::float_type);
146 src_reg src0 = src_reg(v, glsl_type::float_type);
147 src_reg src1 = src_reg(v, glsl_type::float_type);
148 src_reg zero(brw_imm_f(0.0f));
149 dst_reg dest_null = bld.null_reg_f();
150 dest_null.writemask = WRITEMASK_X;
151
152 bld.ADD(dest, src0, src1);
153 bld.CMP(dest_null, src_reg(dest), zero, BRW_CONDITIONAL_GE);
154
155 /* = Before =
156 *
157 * 0: add dest.x src0.xxxx src1.xxxx
158 * 1: cmp.ge.f0 null.x dest.xxxx 0.0f
159 *
160 * = After =
161 * 0: add.ge.f0 dest.x src0.xxxx src1.xxxx
162 */
163
164 v->calculate_cfg();
165 bblock_t *block0 = v->cfg->blocks[0];
166
167 EXPECT_EQ(0, block0->start_ip);
168 EXPECT_EQ(1, block0->end_ip);
169
170 EXPECT_TRUE(cmod_propagation(v));
171
172 ASSERT_EQ(0, block0->start_ip);
173 ASSERT_EQ(0, block0->end_ip);
174 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
175 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
176 }
177
178 TEST_F(cmod_propagation_test, basic_different_dst_writemask)
179 {
180 const vec4_builder bld = vec4_builder(v).at_end();
181 dst_reg dest = dst_reg(v, glsl_type::float_type);
182 src_reg src0 = src_reg(v, glsl_type::float_type);
183 src_reg src1 = src_reg(v, glsl_type::float_type);
184 src_reg zero(brw_imm_f(0.0f));
185 dst_reg dest_null = bld.null_reg_f();
186
187 bld.ADD(dest, src0, src1);
188 bld.CMP(dest_null, src_reg(dest), zero, BRW_CONDITIONAL_GE);
189
190 /* = Before =
191 *
192 * 0: add dest.x src0 src1
193 * 1: cmp.ge.f0 null.xyzw dest 0.0f
194 *
195 * = After =
196 * (no changes)
197 */
198
199 v->calculate_cfg();
200 bblock_t *block0 = v->cfg->blocks[0];
201
202 EXPECT_EQ(0, block0->start_ip);
203 EXPECT_EQ(1, block0->end_ip);
204
205 EXPECT_FALSE(cmod_propagation(v));
206
207 ASSERT_EQ(0, block0->start_ip);
208 ASSERT_EQ(1, block0->end_ip);
209 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
210 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
211 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
212 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
213 }
214
215 TEST_F(cmod_propagation_test, andz_one)
216 {
217 const vec4_builder bld = vec4_builder(v).at_end();
218 dst_reg dest = dst_reg(v, glsl_type::int_type);
219 src_reg src0 = src_reg(v, glsl_type::float_type);
220 src_reg zero(brw_imm_f(0.0f));
221 src_reg one(brw_imm_d(1));
222
223 bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
224 set_condmod(BRW_CONDITIONAL_Z,
225 bld.AND(bld.null_reg_d(), src_reg(dest), one));
226
227 /* = Before =
228 * 0: cmp.l.f0 dest:F src0:F 0F
229 * 1: and.z.f0 null:D dest:D 1D
230 *
231 * = After =
232 * (no changes)
233 */
234
235 v->calculate_cfg();
236 bblock_t *block0 = v->cfg->blocks[0];
237
238 EXPECT_EQ(0, block0->start_ip);
239 EXPECT_EQ(1, block0->end_ip);
240
241 EXPECT_FALSE(cmod_propagation(v));
242
243 ASSERT_EQ(0, block0->start_ip);
244 ASSERT_EQ(1, block0->end_ip);
245 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
246 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
247 EXPECT_EQ(BRW_OPCODE_AND, instruction(block0, 1)->opcode);
248 EXPECT_EQ(BRW_CONDITIONAL_EQ, instruction(block0, 1)->conditional_mod);
249 }
250
251 TEST_F(cmod_propagation_test, non_cmod_instruction)
252 {
253 const vec4_builder bld = vec4_builder(v).at_end();
254 dst_reg dest = dst_reg(v, glsl_type::uint_type);
255 src_reg src0 = src_reg(v, glsl_type::uint_type);
256 src_reg zero(brw_imm_ud(0u));
257 bld.FBL(dest, src0);
258 bld.CMP(bld.null_reg_ud(), src_reg(dest), zero, BRW_CONDITIONAL_GE);
259
260 /* = Before =
261 *
262 * 0: fbl dest src0
263 * 1: cmp.ge.f0 null dest 0u
264 *
265 * = After =
266 * (no changes)
267 */
268
269 v->calculate_cfg();
270 bblock_t *block0 = v->cfg->blocks[0];
271
272 EXPECT_EQ(0, block0->start_ip);
273 EXPECT_EQ(1, block0->end_ip);
274
275 EXPECT_FALSE(cmod_propagation(v));
276
277 ASSERT_EQ(0, block0->start_ip);
278 ASSERT_EQ(1, block0->end_ip);
279 EXPECT_EQ(BRW_OPCODE_FBL, instruction(block0, 0)->opcode);
280 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
281 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
282 }
283
284 TEST_F(cmod_propagation_test, intervening_flag_write)
285 {
286 const vec4_builder bld = vec4_builder(v).at_end();
287 dst_reg dest = dst_reg(v, glsl_type::float_type);
288 src_reg src0 = src_reg(v, glsl_type::float_type);
289 src_reg src1 = src_reg(v, glsl_type::float_type);
290 src_reg src2 = src_reg(v, glsl_type::float_type);
291 src_reg zero(brw_imm_f(0.0f));
292 bld.ADD(dest, src0, src1);
293 bld.CMP(bld.null_reg_f(), src2, zero, BRW_CONDITIONAL_GE);
294 bld.CMP(bld.null_reg_f(), src_reg(dest), zero, BRW_CONDITIONAL_GE);
295
296 /* = Before =
297 *
298 * 0: add dest src0 src1
299 * 1: cmp.ge.f0 null src2 0.0f
300 * 2: cmp.ge.f0 null dest 0.0f
301 *
302 * = After =
303 * (no changes)
304 */
305
306 v->calculate_cfg();
307 bblock_t *block0 = v->cfg->blocks[0];
308
309 EXPECT_EQ(0, block0->start_ip);
310 EXPECT_EQ(2, block0->end_ip);
311
312 EXPECT_FALSE(cmod_propagation(v));
313
314 ASSERT_EQ(0, block0->start_ip);
315 ASSERT_EQ(2, block0->end_ip);
316 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
317 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
318 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
319 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
320 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
321 }
322
323 TEST_F(cmod_propagation_test, intervening_flag_read)
324 {
325 const vec4_builder bld = vec4_builder(v).at_end();
326 dst_reg dest0 = dst_reg(v, glsl_type::float_type);
327 dst_reg dest1 = dst_reg(v, glsl_type::float_type);
328 src_reg src0 = src_reg(v, glsl_type::float_type);
329 src_reg src1 = src_reg(v, glsl_type::float_type);
330 src_reg src2 = src_reg(v, glsl_type::float_type);
331 src_reg zero(brw_imm_f(0.0f));
332 bld.ADD(dest0, src0, src1);
333 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
334 bld.CMP(bld.null_reg_f(), src_reg(dest0), zero, BRW_CONDITIONAL_GE);
335
336 /* = Before =
337 *
338 * 0: add dest0 src0 src1
339 * 1: (+f0) sel dest1 src2 0.0f
340 * 2: cmp.ge.f0 null dest0 0.0f
341 *
342 * = After =
343 * (no changes)
344 */
345
346 v->calculate_cfg();
347 bblock_t *block0 = v->cfg->blocks[0];
348
349 EXPECT_EQ(0, block0->start_ip);
350 EXPECT_EQ(2, block0->end_ip);
351
352 EXPECT_FALSE(cmod_propagation(v));
353
354 ASSERT_EQ(0, block0->start_ip);
355 ASSERT_EQ(2, block0->end_ip);
356 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
357 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
358 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
359 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
360 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
361 }
362
363 TEST_F(cmod_propagation_test, intervening_dest_write)
364 {
365 const vec4_builder bld = vec4_builder(v).at_end();
366 dst_reg dest = dst_reg(v, glsl_type::vec4_type);
367 src_reg src0 = src_reg(v, glsl_type::float_type);
368 src_reg src1 = src_reg(v, glsl_type::float_type);
369 src_reg src2 = src_reg(v, glsl_type::vec2_type);
370 src_reg zero(brw_imm_f(0.0f));
371 bld.ADD(offset(dest, 2), src0, src1);
372 bld.emit(SHADER_OPCODE_TEX, dest, src2)
373 ->size_written = 4 * REG_SIZE;
374 bld.CMP(bld.null_reg_f(), offset(src_reg(dest), 2), zero, BRW_CONDITIONAL_GE);
375
376 /* = Before =
377 *
378 * 0: add dest+2 src0 src1
379 * 1: tex rlen 4 dest+0 src2
380 * 2: cmp.ge.f0 null dest+2 0.0f
381 *
382 * = After =
383 * (no changes)
384 */
385
386 v->calculate_cfg();
387 bblock_t *block0 = v->cfg->blocks[0];
388
389 EXPECT_EQ(0, block0->start_ip);
390 EXPECT_EQ(2, block0->end_ip);
391
392 EXPECT_FALSE(cmod_propagation(v));
393
394 ASSERT_EQ(0, block0->start_ip);
395 ASSERT_EQ(2, block0->end_ip);
396 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
397 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
398 EXPECT_EQ(SHADER_OPCODE_TEX, instruction(block0, 1)->opcode);
399 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
400 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
401 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
402 }
403
404 TEST_F(cmod_propagation_test, intervening_flag_read_same_value)
405 {
406 const vec4_builder bld = vec4_builder(v).at_end();
407 dst_reg dest0 = dst_reg(v, glsl_type::float_type);
408 dst_reg dest1 = dst_reg(v, glsl_type::float_type);
409 src_reg src0 = src_reg(v, glsl_type::float_type);
410 src_reg src1 = src_reg(v, glsl_type::float_type);
411 src_reg src2 = src_reg(v, glsl_type::float_type);
412 src_reg zero(brw_imm_f(0.0f));
413 dst_reg dest_null = bld.null_reg_f();
414 dest_null.writemask = WRITEMASK_X;
415
416 set_condmod(BRW_CONDITIONAL_GE, bld.ADD(dest0, src0, src1));
417 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
418 bld.CMP(dest_null, src_reg(dest0), zero, BRW_CONDITIONAL_GE);
419
420 /* = Before =
421 *
422 * 0: add.ge.f0 dest0 src0 src1
423 * 1: (+f0) sel dest1 src2 0.0f
424 * 2: cmp.ge.f0 null.x dest0 0.0f
425 *
426 * = After =
427 * 0: add.ge.f0 dest0 src0 src1
428 * 1: (+f0) sel dest1 src2 0.0f
429 */
430
431 v->calculate_cfg();
432 bblock_t *block0 = v->cfg->blocks[0];
433
434 EXPECT_EQ(0, block0->start_ip);
435 EXPECT_EQ(2, block0->end_ip);
436
437 EXPECT_TRUE(cmod_propagation(v));
438 ASSERT_EQ(0, block0->start_ip);
439 ASSERT_EQ(1, block0->end_ip);
440 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
441 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
442 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
443 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
444 }
445
446 TEST_F(cmod_propagation_test, negate)
447 {
448 const vec4_builder bld = vec4_builder(v).at_end();
449 dst_reg dest = dst_reg(v, glsl_type::float_type);
450 src_reg src0 = src_reg(v, glsl_type::float_type);
451 src_reg src1 = src_reg(v, glsl_type::float_type);
452 src_reg zero(brw_imm_f(0.0f));
453 bld.ADD(dest, src0, src1);
454 src_reg tmp_src = src_reg(dest);
455 tmp_src.negate = true;
456 dst_reg dest_null = bld.null_reg_f();
457 dest_null.writemask = WRITEMASK_X;
458 bld.CMP(dest_null, tmp_src, zero, BRW_CONDITIONAL_GE);
459
460 /* = Before =
461 *
462 * 0: add dest src0 src1
463 * 1: cmp.ge.f0 null.x -dest 0.0f
464 *
465 * = After =
466 * 0: add.le.f0 dest src0 src1
467 */
468
469 v->calculate_cfg();
470 bblock_t *block0 = v->cfg->blocks[0];
471
472 EXPECT_EQ(0, block0->start_ip);
473 EXPECT_EQ(1, block0->end_ip);
474
475 EXPECT_TRUE(cmod_propagation(v));
476 EXPECT_EQ(0, block0->start_ip);
477 EXPECT_EQ(0, block0->end_ip);
478 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
479 EXPECT_EQ(BRW_CONDITIONAL_LE, instruction(block0, 0)->conditional_mod);
480 }
481
482 TEST_F(cmod_propagation_test, movnz)
483 {
484 const vec4_builder bld = vec4_builder(v).at_end();
485 dst_reg dest = dst_reg(v, glsl_type::float_type);
486 src_reg src0 = src_reg(v, glsl_type::float_type);
487 src_reg src1 = src_reg(v, glsl_type::float_type);
488 dst_reg dest_null = bld.null_reg_f();
489 dest_null.writemask = WRITEMASK_X;
490
491 bld.CMP(dest, src0, src1, BRW_CONDITIONAL_L);
492 set_condmod(BRW_CONDITIONAL_NZ,
493 bld.MOV(dest_null, src_reg(dest)));
494
495 /* = Before =
496 *
497 * 0: cmp.l.f0 dest:F src0:F src1:F
498 * 1: mov.nz.f0 null.x dest:F
499 *
500 * = After =
501 * 0: cmp.l.f0 dest src0:F src1:F
502 */
503
504 v->calculate_cfg();
505 bblock_t *block0 = v->cfg->blocks[0];
506
507 EXPECT_EQ(0, block0->start_ip);
508 EXPECT_EQ(1, block0->end_ip);
509
510 EXPECT_TRUE(cmod_propagation(v));
511
512 ASSERT_EQ(0, block0->start_ip);
513 ASSERT_EQ(0, block0->end_ip);
514 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
515 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
516 }
517
518 TEST_F(cmod_propagation_test, different_types_cmod_with_zero)
519 {
520 const vec4_builder bld = vec4_builder(v).at_end();
521 dst_reg dest = dst_reg(v, glsl_type::int_type);
522 src_reg src0 = src_reg(v, glsl_type::int_type);
523 src_reg src1 = src_reg(v, glsl_type::int_type);
524 src_reg zero(brw_imm_f(0.0f));
525 bld.ADD(dest, src0, src1);
526 bld.CMP(bld.null_reg_f(), retype(src_reg(dest), BRW_REGISTER_TYPE_F), zero,
527 BRW_CONDITIONAL_GE);
528
529 /* = Before =
530 *
531 * 0: add dest:D src0:D src1:D
532 * 1: cmp.ge.f0 null:F dest:F 0.0f
533 *
534 * = After =
535 * (no changes)
536 */
537
538 v->calculate_cfg();
539 bblock_t *block0 = v->cfg->blocks[0];
540
541 EXPECT_EQ(0, block0->start_ip);
542 EXPECT_EQ(1, block0->end_ip);
543
544 EXPECT_FALSE(cmod_propagation(v));
545
546 ASSERT_EQ(0, block0->start_ip);
547 ASSERT_EQ(1, block0->end_ip);
548 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
549 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
550 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
551 }
552
553 TEST_F(cmod_propagation_test, andnz_non_one)
554 {
555 const vec4_builder bld = vec4_builder(v).at_end();
556 dst_reg dest = dst_reg(v, glsl_type::int_type);
557 src_reg src0 = src_reg(v, glsl_type::float_type);
558 src_reg zero(brw_imm_f(0.0f));
559 src_reg nonone(brw_imm_d(38));
560
561 bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
562 set_condmod(BRW_CONDITIONAL_NZ,
563 bld.AND(bld.null_reg_d(), src_reg(dest), nonone));
564
565 /* = Before =
566 * 0: cmp.l.f0 dest:F src0:F 0F
567 * 1: and.nz.f0 null:D dest:D 38D
568 *
569 * = After =
570 * (no changes)
571 */
572
573 v->calculate_cfg();
574 bblock_t *block0 = v->cfg->blocks[0];
575
576 EXPECT_EQ(0, block0->start_ip);
577 EXPECT_EQ(1, block0->end_ip);
578
579 EXPECT_FALSE(cmod_propagation(v));
580
581 ASSERT_EQ(0, block0->start_ip);
582 ASSERT_EQ(1, block0->end_ip);
583 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
584 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
585 EXPECT_EQ(BRW_OPCODE_AND, instruction(block0, 1)->opcode);
586 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
587 }
588
589 /* Note that basic is using glsl_type:float types, while this one is using
590 * glsl_type::vec4 */
591 TEST_F(cmod_propagation_test, basic_vec4)
592 {
593 const vec4_builder bld = vec4_builder(v).at_end();
594 dst_reg dest = dst_reg(v, glsl_type::vec4_type);
595 src_reg src0 = src_reg(v, glsl_type::vec4_type);
596 src_reg src1 = src_reg(v, glsl_type::vec4_type);
597 src_reg zero(brw_imm_f(0.0f));
598
599 bld.MUL(dest, src0, src1);
600 bld.CMP(bld.null_reg_f(), src_reg(dest), zero, BRW_CONDITIONAL_NZ);
601
602 /* = Before =
603 * 0: mul dest.xyzw src0.xyzw src1.xyzw
604 * 1: cmp.nz.f0.0 null.xyzw dest.xyzw 0.0f
605 *
606 * = After =
607 * 0: mul.nz.f0.0 dest.xyzw src0.xyzw src1.xyzw
608 */
609
610 v->calculate_cfg();
611 bblock_t *block0 = v->cfg->blocks[0];
612
613 EXPECT_EQ(0, block0->start_ip);
614 EXPECT_EQ(1, block0->end_ip);
615
616 EXPECT_TRUE(cmod_propagation(v));
617
618 ASSERT_EQ(0, block0->start_ip);
619 ASSERT_EQ(0, block0->end_ip);
620 EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
621 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 0)->conditional_mod);
622 }
623
624 TEST_F(cmod_propagation_test, basic_vec4_different_dst_writemask)
625 {
626 const vec4_builder bld = vec4_builder(v).at_end();
627 dst_reg dest = dst_reg(v, glsl_type::vec4_type);
628 dest.writemask = WRITEMASK_X;
629 src_reg src0 = src_reg(v, glsl_type::vec4_type);
630 src_reg src1 = src_reg(v, glsl_type::vec4_type);
631 src_reg zero(brw_imm_f(0.0f));
632 dst_reg dest_null = bld.null_reg_f();
633
634 bld.MUL(dest, src0, src1);
635 bld.CMP(dest_null, src_reg(dest), zero, BRW_CONDITIONAL_NZ);
636
637 /* = Before =
638 * 0: mul dest.x src0 src1
639 * 1: cmp.nz.f0.0 null dest 0.0f
640 *
641 * = After =
642 * (no changes)
643 */
644
645 v->calculate_cfg();
646 bblock_t *block0 = v->cfg->blocks[0];
647
648 EXPECT_EQ(0, block0->start_ip);
649 EXPECT_EQ(1, block0->end_ip);
650
651 EXPECT_FALSE(cmod_propagation(v));
652
653 ASSERT_EQ(0, block0->start_ip);
654 ASSERT_EQ(1, block0->end_ip);
655 EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
656 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
657 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
658 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
659 }
660
661 TEST_F(cmod_propagation_test, mad_one_component_vec4)
662 {
663 const vec4_builder bld = vec4_builder(v).at_end();
664 dst_reg dest = dst_reg(v, glsl_type::vec4_type);
665 dest.writemask = WRITEMASK_X;
666 src_reg src0 = src_reg(v, glsl_type::vec4_type);
667 src_reg src1 = src_reg(v, glsl_type::vec4_type);
668 src_reg src2 = src_reg(v, glsl_type::vec4_type);
669 src0.swizzle = src1.swizzle = src2.swizzle = BRW_SWIZZLE_XXXX;
670 src2.negate = true;
671 src_reg zero(brw_imm_f(0.0f));
672 src_reg tmp(dest);
673 tmp.swizzle = BRW_SWIZZLE_XXXX;
674 dst_reg dest_null = bld.null_reg_f();
675 dest_null.writemask = WRITEMASK_X;
676
677 bld.MAD(dest, src0, src1, src2);
678 bld.CMP(dest_null, tmp, zero, BRW_CONDITIONAL_L);
679
680 /* = Before =
681 *
682 * 0: mad dest.x:F src0.xxxx:F src10.xxxx:F -src2.xxxx:F
683 * 1: cmp.l.f0.0 null.x:F dest.xxxx:F 0.0f
684 *
685 * = After =
686 * 0: mad.l.f0 dest.x:F src0.xxxx:F src10.xxxx:F -src2.xxxx:F
687 */
688
689 v->calculate_cfg();
690 bblock_t *block0 = v->cfg->blocks[0];
691
692 EXPECT_EQ(0, block0->start_ip);
693 EXPECT_EQ(1, block0->end_ip);
694
695 EXPECT_TRUE(cmod_propagation(v));
696
697 ASSERT_EQ(0, block0->start_ip);
698 ASSERT_EQ(0, block0->end_ip);
699 EXPECT_EQ(BRW_OPCODE_MAD, instruction(block0, 0)->opcode);
700 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
701 }
702
703 TEST_F(cmod_propagation_test, mad_more_one_component_vec4)
704 {
705 const vec4_builder bld = vec4_builder(v).at_end();
706 dst_reg dest = dst_reg(v, glsl_type::vec4_type);
707 dest.writemask = WRITEMASK_XW;
708 src_reg src0 = src_reg(v, glsl_type::vec4_type);
709 src_reg src1 = src_reg(v, glsl_type::vec4_type);
710 src_reg src2 = src_reg(v, glsl_type::vec4_type);
711 src0.swizzle = src1.swizzle = src2.swizzle = BRW_SWIZZLE_XXXX;
712 src2.negate = true;
713 src_reg zero(brw_imm_f(0.0f));
714 src_reg tmp(dest);
715 tmp.swizzle = BRW_SWIZZLE_XXXX;
716 dst_reg dest_null = bld.null_reg_f();
717
718 bld.MAD(dest, src0, src1, src2);
719 bld.CMP(dest_null, tmp, zero, BRW_CONDITIONAL_L);
720
721 /* = Before =
722 *
723 * 0: mad dest.xw:F src0.xxxx:F src10.xxxx:F -src2.xxxx:F
724 * 1: cmp.l.f0.0 null:F dest.xxxx:F zeroF
725 *
726 * = After =
727 * (No changes)
728 */
729
730 v->calculate_cfg();
731 bblock_t *block0 = v->cfg->blocks[0];
732
733 EXPECT_EQ(0, block0->start_ip);
734 EXPECT_EQ(1, block0->end_ip);
735
736 EXPECT_FALSE(cmod_propagation(v));
737
738 ASSERT_EQ(0, block0->start_ip);
739 ASSERT_EQ(1, block0->end_ip);
740 EXPECT_EQ(BRW_OPCODE_MAD, instruction(block0, 0)->opcode);
741 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
742 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
743 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 1)->conditional_mod);
744 }
745
746 TEST_F(cmod_propagation_test, cmp_mov_vec4)
747 {
748 const vec4_builder bld = vec4_builder(v).at_end();
749 dst_reg dest = dst_reg(v, glsl_type::ivec4_type);
750 dest.writemask = WRITEMASK_X;
751 src_reg src0 = src_reg(v, glsl_type::ivec4_type);
752 src0.swizzle = BRW_SWIZZLE_XXXX;
753 src0.file = UNIFORM;
754 src_reg nonone = retype(brw_imm_d(16), BRW_REGISTER_TYPE_D);
755 src_reg mov_src = src_reg(dest);
756 mov_src.swizzle = BRW_SWIZZLE_XXXX;
757 dst_reg dest_null = bld.null_reg_d();
758 dest_null.writemask = WRITEMASK_X;
759
760 bld.CMP(dest, src0, nonone, BRW_CONDITIONAL_GE);
761 set_condmod(BRW_CONDITIONAL_NZ,
762 bld.MOV(dest_null, mov_src));
763
764 /* = Before =
765 *
766 * 0: cmp.ge.f0 dest.x:D u.xxxx:D 16D
767 * 1: mov.nz.f0 null.x:D dest.xxxx:D
768 *
769 * = After =
770 * 0: cmp.ge.f0 dest.x:D u.xxxx:D 16D
771 */
772
773 v->calculate_cfg();
774 bblock_t *block0 = v->cfg->blocks[0];
775
776 EXPECT_EQ(0, block0->start_ip);
777 EXPECT_EQ(1, block0->end_ip);
778
779 EXPECT_TRUE(cmod_propagation(v));
780
781 ASSERT_EQ(0, block0->start_ip);
782 ASSERT_EQ(0, block0->end_ip);
783 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
784 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
785 }
786
787 TEST_F(cmod_propagation_test, mul_cmp_different_channels_vec4)
788 {
789 const vec4_builder bld = vec4_builder(v).at_end();
790 dst_reg dest = dst_reg(v, glsl_type::vec4_type);
791 src_reg src0 = src_reg(v, glsl_type::vec4_type);
792 src_reg src1 = src_reg(v, glsl_type::vec4_type);
793 src_reg zero(brw_imm_f(0.0f));
794 src_reg cmp_src = src_reg(dest);
795 cmp_src.swizzle = BRW_SWIZZLE4(0,1,3,2);
796
797 bld.MUL(dest, src0, src1);
798 bld.CMP(bld.null_reg_f(), cmp_src, zero, BRW_CONDITIONAL_NZ);
799
800 /* = Before =
801 * 0: mul dest src0 src1
802 * 1: cmp.nz.f0.0 null dest.xywz 0.0f
803 *
804 * = After =
805 * (No changes)
806 */
807
808 v->calculate_cfg();
809 bblock_t *block0 = v->cfg->blocks[0];
810
811 EXPECT_EQ(0, block0->start_ip);
812 EXPECT_EQ(1, block0->end_ip);
813
814 EXPECT_FALSE(cmod_propagation(v));
815
816 ASSERT_EQ(0, block0->start_ip);
817 ASSERT_EQ(1, block0->end_ip);
818 EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
819 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
820 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
821 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
822 }