intel/fs: Drop the gl_program from fs_visitor
[mesa.git] / src / intel / compiler / test_fs_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
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 cmod_propagation_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 void test_positive_float_saturate_prop(enum brw_conditional_mod before,
43 enum brw_conditional_mod after,
44 enum opcode op);
45
46 void test_negative_float_saturate_prop(enum brw_conditional_mod before,
47 enum opcode op);
48
49 void test_negative_int_saturate_prop(enum brw_conditional_mod before,
50 enum opcode op);
51 };
52
53 class cmod_propagation_fs_visitor : public fs_visitor
54 {
55 public:
56 cmod_propagation_fs_visitor(struct brw_compiler *compiler,
57 struct brw_wm_prog_data *prog_data,
58 nir_shader *shader)
59 : fs_visitor(compiler, NULL, NULL, NULL,
60 &prog_data->base, shader, 8, -1) {}
61 };
62
63
64 void cmod_propagation_test::SetUp()
65 {
66 ctx = (struct gl_context *)calloc(1, sizeof(*ctx));
67 compiler = (struct brw_compiler *)calloc(1, sizeof(*compiler));
68 devinfo = (struct gen_device_info *)calloc(1, sizeof(*devinfo));
69 compiler->devinfo = devinfo;
70
71 prog_data = ralloc(NULL, struct brw_wm_prog_data);
72 nir_shader *shader =
73 nir_shader_create(NULL, MESA_SHADER_FRAGMENT, NULL, NULL);
74
75 v = new cmod_propagation_fs_visitor(compiler, prog_data, shader);
76
77 devinfo->gen = 7;
78 }
79
80 static fs_inst *
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 bool
91 cmod_propagation(fs_visitor *v)
92 {
93 const bool print = getenv("TEST_DEBUG");
94
95 if (print) {
96 fprintf(stderr, "= Before =\n");
97 v->cfg->dump(v);
98 }
99
100 bool ret = v->opt_cmod_propagation();
101
102 if (print) {
103 fprintf(stderr, "\n= After =\n");
104 v->cfg->dump(v);
105 }
106
107 return ret;
108 }
109
110 TEST_F(cmod_propagation_test, basic)
111 {
112 const fs_builder &bld = v->bld;
113 fs_reg dest = v->vgrf(glsl_type::float_type);
114 fs_reg src0 = v->vgrf(glsl_type::float_type);
115 fs_reg src1 = v->vgrf(glsl_type::float_type);
116 fs_reg zero(brw_imm_f(0.0f));
117 bld.ADD(dest, src0, src1);
118 bld.CMP(bld.null_reg_f(), dest, zero, BRW_CONDITIONAL_GE);
119
120 /* = Before =
121 *
122 * 0: add(8) dest src0 src1
123 * 1: cmp.ge.f0(8) null dest 0.0f
124 *
125 * = After =
126 * 0: add.ge.f0(8) dest src0 src1
127 */
128
129 v->calculate_cfg();
130 bblock_t *block0 = v->cfg->blocks[0];
131
132 EXPECT_EQ(0, block0->start_ip);
133 EXPECT_EQ(1, block0->end_ip);
134
135 EXPECT_TRUE(cmod_propagation(v));
136 EXPECT_EQ(0, block0->start_ip);
137 EXPECT_EQ(0, block0->end_ip);
138 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
139 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
140 }
141
142 TEST_F(cmod_propagation_test, basic_other_flag)
143 {
144 const fs_builder &bld = v->bld;
145 fs_reg dest = v->vgrf(glsl_type::float_type);
146 fs_reg src0 = v->vgrf(glsl_type::float_type);
147 fs_reg src1 = v->vgrf(glsl_type::float_type);
148 fs_reg zero(brw_imm_f(0.0f));
149 bld.ADD(dest, src0, src1);
150 bld.CMP(bld.null_reg_f(), dest, zero, BRW_CONDITIONAL_GE)
151 ->flag_subreg = 1;
152
153 /* = Before =
154 *
155 * 0: add(8) dest src0 src1
156 * 1: cmp.ge.f0.1(8) null dest 0.0f
157 *
158 * = After =
159 * 0: add.ge.f0.1(8) dest src0 src1
160 */
161
162 v->calculate_cfg();
163 bblock_t *block0 = v->cfg->blocks[0];
164
165 EXPECT_EQ(0, block0->start_ip);
166 EXPECT_EQ(1, block0->end_ip);
167
168 EXPECT_TRUE(cmod_propagation(v));
169 EXPECT_EQ(0, block0->start_ip);
170 EXPECT_EQ(0, block0->end_ip);
171 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
172 EXPECT_EQ(1, instruction(block0, 0)->flag_subreg);
173 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
174 }
175
176 TEST_F(cmod_propagation_test, cmp_nonzero)
177 {
178 const fs_builder &bld = v->bld;
179 fs_reg dest = v->vgrf(glsl_type::float_type);
180 fs_reg src0 = v->vgrf(glsl_type::float_type);
181 fs_reg src1 = v->vgrf(glsl_type::float_type);
182 fs_reg nonzero(brw_imm_f(1.0f));
183 bld.ADD(dest, src0, src1);
184 bld.CMP(bld.null_reg_f(), dest, nonzero, BRW_CONDITIONAL_GE);
185
186 /* = Before =
187 *
188 * 0: add(8) dest src0 src1
189 * 1: cmp.ge.f0(8) null dest 1.0f
190 *
191 * = After =
192 * (no changes)
193 */
194
195 v->calculate_cfg();
196 bblock_t *block0 = v->cfg->blocks[0];
197
198 EXPECT_EQ(0, block0->start_ip);
199 EXPECT_EQ(1, block0->end_ip);
200
201 EXPECT_FALSE(cmod_propagation(v));
202 EXPECT_EQ(0, block0->start_ip);
203 EXPECT_EQ(1, block0->end_ip);
204 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
205 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
206 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
207 }
208
209 TEST_F(cmod_propagation_test, non_cmod_instruction)
210 {
211 const fs_builder &bld = v->bld;
212 fs_reg dest = v->vgrf(glsl_type::uint_type);
213 fs_reg src0 = v->vgrf(glsl_type::uint_type);
214 fs_reg zero(brw_imm_ud(0u));
215 bld.FBL(dest, src0);
216 bld.CMP(bld.null_reg_ud(), dest, zero, BRW_CONDITIONAL_GE);
217
218 /* = Before =
219 *
220 * 0: fbl(8) dest src0
221 * 1: cmp.ge.f0(8) null dest 0u
222 *
223 * = After =
224 * (no changes)
225 */
226
227 v->calculate_cfg();
228 bblock_t *block0 = v->cfg->blocks[0];
229
230 EXPECT_EQ(0, block0->start_ip);
231 EXPECT_EQ(1, block0->end_ip);
232
233 EXPECT_FALSE(cmod_propagation(v));
234 EXPECT_EQ(0, block0->start_ip);
235 EXPECT_EQ(1, block0->end_ip);
236 EXPECT_EQ(BRW_OPCODE_FBL, instruction(block0, 0)->opcode);
237 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
238 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
239 }
240
241 TEST_F(cmod_propagation_test, intervening_flag_write)
242 {
243 const fs_builder &bld = v->bld;
244 fs_reg dest = v->vgrf(glsl_type::float_type);
245 fs_reg src0 = v->vgrf(glsl_type::float_type);
246 fs_reg src1 = v->vgrf(glsl_type::float_type);
247 fs_reg src2 = v->vgrf(glsl_type::float_type);
248 fs_reg zero(brw_imm_f(0.0f));
249 bld.ADD(dest, src0, src1);
250 bld.CMP(bld.null_reg_f(), src2, zero, BRW_CONDITIONAL_GE);
251 bld.CMP(bld.null_reg_f(), dest, zero, BRW_CONDITIONAL_GE);
252
253 /* = Before =
254 *
255 * 0: add(8) dest src0 src1
256 * 1: cmp.ge.f0(8) null src2 0.0f
257 * 2: cmp.ge.f0(8) null dest 0.0f
258 *
259 * = After =
260 * (no changes)
261 */
262
263 v->calculate_cfg();
264 bblock_t *block0 = v->cfg->blocks[0];
265
266 EXPECT_EQ(0, block0->start_ip);
267 EXPECT_EQ(2, block0->end_ip);
268
269 EXPECT_FALSE(cmod_propagation(v));
270 EXPECT_EQ(0, block0->start_ip);
271 EXPECT_EQ(2, block0->end_ip);
272 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
273 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
274 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
275 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
276 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
277 }
278
279 TEST_F(cmod_propagation_test, intervening_mismatch_flag_write)
280 {
281 const fs_builder &bld = v->bld;
282 fs_reg dest = v->vgrf(glsl_type::float_type);
283 fs_reg src0 = v->vgrf(glsl_type::float_type);
284 fs_reg src1 = v->vgrf(glsl_type::float_type);
285 fs_reg src2 = v->vgrf(glsl_type::float_type);
286 fs_reg zero(brw_imm_f(0.0f));
287 bld.ADD(dest, src0, src1);
288 bld.CMP(bld.null_reg_f(), src2, zero, BRW_CONDITIONAL_GE)
289 ->flag_subreg = 1;
290 bld.CMP(bld.null_reg_f(), dest, zero, BRW_CONDITIONAL_GE);
291
292 /* = Before =
293 *
294 * 0: add(8) dest src0 src1
295 * 1: cmp.ge.f0.1(8) null src2 0.0f
296 * 2: cmp.ge.f0(8) null dest 0.0f
297 *
298 * = After =
299 * 0: add.ge.f0(8) dest src0 src1
300 * 1: cmp.ge.f0.1(8) null src2 0.0f
301 */
302
303 v->calculate_cfg();
304 bblock_t *block0 = v->cfg->blocks[0];
305
306 EXPECT_EQ(0, block0->start_ip);
307 EXPECT_EQ(2, block0->end_ip);
308
309 EXPECT_TRUE(cmod_propagation(v));
310 EXPECT_EQ(0, block0->start_ip);
311 EXPECT_EQ(1, block0->end_ip);
312 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
313 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
314 EXPECT_EQ(0, instruction(block0, 0)->flag_subreg);
315 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
316 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
317 EXPECT_EQ(1, instruction(block0, 1)->flag_subreg);
318 }
319
320 TEST_F(cmod_propagation_test, intervening_flag_read)
321 {
322 const fs_builder &bld = v->bld;
323 fs_reg dest0 = v->vgrf(glsl_type::float_type);
324 fs_reg dest1 = v->vgrf(glsl_type::float_type);
325 fs_reg src0 = v->vgrf(glsl_type::float_type);
326 fs_reg src1 = v->vgrf(glsl_type::float_type);
327 fs_reg src2 = v->vgrf(glsl_type::float_type);
328 fs_reg zero(brw_imm_f(0.0f));
329 bld.ADD(dest0, src0, src1);
330 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
331 bld.CMP(bld.null_reg_f(), dest0, zero, BRW_CONDITIONAL_GE);
332
333 /* = Before =
334 *
335 * 0: add(8) dest0 src0 src1
336 * 1: (+f0) sel(8) dest1 src2 0.0f
337 * 2: cmp.ge.f0(8) null dest0 0.0f
338 *
339 * = After =
340 * (no changes)
341 */
342
343 v->calculate_cfg();
344 bblock_t *block0 = v->cfg->blocks[0];
345
346 EXPECT_EQ(0, block0->start_ip);
347 EXPECT_EQ(2, block0->end_ip);
348
349 EXPECT_FALSE(cmod_propagation(v));
350 EXPECT_EQ(0, block0->start_ip);
351 EXPECT_EQ(2, block0->end_ip);
352 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
353 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
354 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
355 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
356 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
357 }
358
359 TEST_F(cmod_propagation_test, intervening_mismatch_flag_read)
360 {
361 const fs_builder &bld = v->bld;
362 fs_reg dest0 = v->vgrf(glsl_type::float_type);
363 fs_reg dest1 = v->vgrf(glsl_type::float_type);
364 fs_reg src0 = v->vgrf(glsl_type::float_type);
365 fs_reg src1 = v->vgrf(glsl_type::float_type);
366 fs_reg src2 = v->vgrf(glsl_type::float_type);
367 fs_reg zero(brw_imm_f(0.0f));
368 bld.ADD(dest0, src0, src1);
369 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero))
370 ->flag_subreg = 1;
371 bld.CMP(bld.null_reg_f(), dest0, zero, BRW_CONDITIONAL_GE);
372
373 /* = Before =
374 *
375 * 0: add(8) dest0 src0 src1
376 * 1: (+f0.1) sel(8) dest1 src2 0.0f
377 * 2: cmp.ge.f0(8) null dest0 0.0f
378 *
379 * = After =
380 * 0: add.ge.f0(8) dest0 src0 src1
381 * 1: (+f0.1) sel(8) dest1 src2 0.0f
382 */
383
384 v->calculate_cfg();
385 bblock_t *block0 = v->cfg->blocks[0];
386
387 EXPECT_EQ(0, block0->start_ip);
388 EXPECT_EQ(2, block0->end_ip);
389
390 EXPECT_TRUE(cmod_propagation(v));
391 EXPECT_EQ(0, block0->start_ip);
392 EXPECT_EQ(1, block0->end_ip);
393 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
394 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
395 EXPECT_EQ(0, instruction(block0, 0)->flag_subreg);
396 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
397 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
398 EXPECT_EQ(1, instruction(block0, 1)->flag_subreg);
399 }
400
401 TEST_F(cmod_propagation_test, intervening_dest_write)
402 {
403 const fs_builder &bld = v->bld;
404 fs_reg dest = v->vgrf(glsl_type::vec4_type);
405 fs_reg src0 = v->vgrf(glsl_type::float_type);
406 fs_reg src1 = v->vgrf(glsl_type::float_type);
407 fs_reg src2 = v->vgrf(glsl_type::vec2_type);
408 fs_reg zero(brw_imm_f(0.0f));
409 bld.ADD(offset(dest, bld, 2), src0, src1);
410 bld.emit(SHADER_OPCODE_TEX, dest, src2)
411 ->size_written = 4 * REG_SIZE;
412 bld.CMP(bld.null_reg_f(), offset(dest, bld, 2), zero, BRW_CONDITIONAL_GE);
413
414 /* = Before =
415 *
416 * 0: add(8) dest+2 src0 src1
417 * 1: tex(8) rlen 4 dest+0 src2
418 * 2: cmp.ge.f0(8) null dest+2 0.0f
419 *
420 * = After =
421 * (no changes)
422 */
423
424 v->calculate_cfg();
425 bblock_t *block0 = v->cfg->blocks[0];
426
427 EXPECT_EQ(0, block0->start_ip);
428 EXPECT_EQ(2, block0->end_ip);
429
430 EXPECT_FALSE(cmod_propagation(v));
431 EXPECT_EQ(0, block0->start_ip);
432 EXPECT_EQ(2, block0->end_ip);
433 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
434 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
435 EXPECT_EQ(SHADER_OPCODE_TEX, instruction(block0, 1)->opcode);
436 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
437 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
438 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
439 }
440
441 TEST_F(cmod_propagation_test, intervening_flag_read_same_value)
442 {
443 const fs_builder &bld = v->bld;
444 fs_reg dest0 = v->vgrf(glsl_type::float_type);
445 fs_reg dest1 = v->vgrf(glsl_type::float_type);
446 fs_reg src0 = v->vgrf(glsl_type::float_type);
447 fs_reg src1 = v->vgrf(glsl_type::float_type);
448 fs_reg src2 = v->vgrf(glsl_type::float_type);
449 fs_reg zero(brw_imm_f(0.0f));
450 set_condmod(BRW_CONDITIONAL_GE, bld.ADD(dest0, src0, src1));
451 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
452 bld.CMP(bld.null_reg_f(), dest0, zero, BRW_CONDITIONAL_GE);
453
454 /* = Before =
455 *
456 * 0: add.ge.f0(8) dest0 src0 src1
457 * 1: (+f0) sel(8) dest1 src2 0.0f
458 * 2: cmp.ge.f0(8) null dest0 0.0f
459 *
460 * = After =
461 * 0: add.ge.f0(8) dest0 src0 src1
462 * 1: (+f0) sel(8) dest1 src2 0.0f
463 */
464
465 v->calculate_cfg();
466 bblock_t *block0 = v->cfg->blocks[0];
467
468 EXPECT_EQ(0, block0->start_ip);
469 EXPECT_EQ(2, block0->end_ip);
470
471 EXPECT_TRUE(cmod_propagation(v));
472 EXPECT_EQ(0, block0->start_ip);
473 EXPECT_EQ(1, block0->end_ip);
474 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
475 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
476 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
477 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
478 }
479
480 TEST_F(cmod_propagation_test, negate)
481 {
482 const fs_builder &bld = v->bld;
483 fs_reg dest = v->vgrf(glsl_type::float_type);
484 fs_reg src0 = v->vgrf(glsl_type::float_type);
485 fs_reg src1 = v->vgrf(glsl_type::float_type);
486 fs_reg zero(brw_imm_f(0.0f));
487 bld.ADD(dest, src0, src1);
488 dest.negate = true;
489 bld.CMP(bld.null_reg_f(), dest, zero, BRW_CONDITIONAL_GE);
490
491 /* = Before =
492 *
493 * 0: add(8) dest src0 src1
494 * 1: cmp.ge.f0(8) null -dest 0.0f
495 *
496 * = After =
497 * 0: add.le.f0(8) dest src0 src1
498 */
499
500 v->calculate_cfg();
501 bblock_t *block0 = v->cfg->blocks[0];
502
503 EXPECT_EQ(0, block0->start_ip);
504 EXPECT_EQ(1, block0->end_ip);
505
506 EXPECT_TRUE(cmod_propagation(v));
507 EXPECT_EQ(0, block0->start_ip);
508 EXPECT_EQ(0, block0->end_ip);
509 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
510 EXPECT_EQ(BRW_CONDITIONAL_LE, instruction(block0, 0)->conditional_mod);
511 }
512
513 TEST_F(cmod_propagation_test, movnz)
514 {
515 const fs_builder &bld = v->bld;
516 fs_reg dest = v->vgrf(glsl_type::float_type);
517 fs_reg src0 = v->vgrf(glsl_type::float_type);
518 fs_reg src1 = v->vgrf(glsl_type::float_type);
519 bld.CMP(dest, src0, src1, BRW_CONDITIONAL_GE);
520 set_condmod(BRW_CONDITIONAL_NZ,
521 bld.MOV(bld.null_reg_f(), dest));
522
523 /* = Before =
524 *
525 * 0: cmp.ge.f0(8) dest src0 src1
526 * 1: mov.nz.f0(8) null dest
527 *
528 * = After =
529 * 0: cmp.ge.f0(8) dest src0 src1
530 */
531
532 v->calculate_cfg();
533 bblock_t *block0 = v->cfg->blocks[0];
534
535 EXPECT_EQ(0, block0->start_ip);
536 EXPECT_EQ(1, block0->end_ip);
537
538 EXPECT_TRUE(cmod_propagation(v));
539 EXPECT_EQ(0, block0->start_ip);
540 EXPECT_EQ(0, block0->end_ip);
541 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
542 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
543 }
544
545 TEST_F(cmod_propagation_test, different_types_cmod_with_zero)
546 {
547 const fs_builder &bld = v->bld;
548 fs_reg dest = v->vgrf(glsl_type::int_type);
549 fs_reg src0 = v->vgrf(glsl_type::int_type);
550 fs_reg src1 = v->vgrf(glsl_type::int_type);
551 fs_reg zero(brw_imm_f(0.0f));
552 bld.ADD(dest, src0, src1);
553 bld.CMP(bld.null_reg_f(), retype(dest, BRW_REGISTER_TYPE_F), zero,
554 BRW_CONDITIONAL_GE);
555
556 /* = Before =
557 *
558 * 0: add(8) dest:D src0:D src1:D
559 * 1: cmp.ge.f0(8) null:F dest:F 0.0f
560 *
561 * = After =
562 * (no changes)
563 */
564
565 v->calculate_cfg();
566 bblock_t *block0 = v->cfg->blocks[0];
567
568 EXPECT_EQ(0, block0->start_ip);
569 EXPECT_EQ(1, block0->end_ip);
570
571 EXPECT_FALSE(cmod_propagation(v));
572 EXPECT_EQ(0, block0->start_ip);
573 EXPECT_EQ(1, block0->end_ip);
574 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
575 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
576 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
577 }
578
579 TEST_F(cmod_propagation_test, andnz_one)
580 {
581 const fs_builder &bld = v->bld;
582 fs_reg dest = v->vgrf(glsl_type::int_type);
583 fs_reg src0 = v->vgrf(glsl_type::float_type);
584 fs_reg zero(brw_imm_f(0.0f));
585 fs_reg one(brw_imm_d(1));
586
587 bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
588 set_condmod(BRW_CONDITIONAL_NZ,
589 bld.AND(bld.null_reg_d(), dest, one));
590
591 /* = Before =
592 * 0: cmp.l.f0(8) dest:F src0:F 0F
593 * 1: and.nz.f0(8) null:D dest:D 1D
594 *
595 * = After =
596 * 0: cmp.l.f0(8) dest:F src0:F 0F
597 */
598
599 v->calculate_cfg();
600 bblock_t *block0 = v->cfg->blocks[0];
601
602 EXPECT_EQ(0, block0->start_ip);
603 EXPECT_EQ(1, block0->end_ip);
604
605 EXPECT_TRUE(cmod_propagation(v));
606 EXPECT_EQ(0, block0->start_ip);
607 EXPECT_EQ(0, block0->end_ip);
608 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
609 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
610 EXPECT_TRUE(retype(dest, BRW_REGISTER_TYPE_F)
611 .equals(instruction(block0, 0)->dst));
612 }
613
614 TEST_F(cmod_propagation_test, andnz_non_one)
615 {
616 const fs_builder &bld = v->bld;
617 fs_reg dest = v->vgrf(glsl_type::int_type);
618 fs_reg src0 = v->vgrf(glsl_type::float_type);
619 fs_reg zero(brw_imm_f(0.0f));
620 fs_reg nonone(brw_imm_d(38));
621
622 bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
623 set_condmod(BRW_CONDITIONAL_NZ,
624 bld.AND(bld.null_reg_d(), dest, nonone));
625
626 /* = Before =
627 * 0: cmp.l.f0(8) dest:F src0:F 0F
628 * 1: and.nz.f0(8) null:D dest:D 38D
629 *
630 * = After =
631 * (no changes)
632 */
633
634 v->calculate_cfg();
635 bblock_t *block0 = v->cfg->blocks[0];
636
637 EXPECT_EQ(0, block0->start_ip);
638 EXPECT_EQ(1, block0->end_ip);
639
640 EXPECT_FALSE(cmod_propagation(v));
641 EXPECT_EQ(0, block0->start_ip);
642 EXPECT_EQ(1, block0->end_ip);
643 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
644 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
645 EXPECT_EQ(BRW_OPCODE_AND, instruction(block0, 1)->opcode);
646 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
647 }
648
649 TEST_F(cmod_propagation_test, andz_one)
650 {
651 const fs_builder &bld = v->bld;
652 fs_reg dest = v->vgrf(glsl_type::int_type);
653 fs_reg src0 = v->vgrf(glsl_type::float_type);
654 fs_reg zero(brw_imm_f(0.0f));
655 fs_reg one(brw_imm_d(1));
656
657 bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
658 set_condmod(BRW_CONDITIONAL_Z,
659 bld.AND(bld.null_reg_d(), dest, one));
660
661 /* = Before =
662 * 0: cmp.l.f0(8) dest:F src0:F 0F
663 * 1: and.z.f0(8) null:D dest:D 1D
664 *
665 * = After =
666 * (no changes)
667 */
668
669 v->calculate_cfg();
670 bblock_t *block0 = v->cfg->blocks[0];
671
672 EXPECT_EQ(0, block0->start_ip);
673 EXPECT_EQ(1, block0->end_ip);
674
675 EXPECT_FALSE(cmod_propagation(v));
676 EXPECT_EQ(0, block0->start_ip);
677 EXPECT_EQ(1, block0->end_ip);
678 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
679 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
680 EXPECT_EQ(BRW_OPCODE_AND, instruction(block0, 1)->opcode);
681 EXPECT_EQ(BRW_CONDITIONAL_EQ, instruction(block0, 1)->conditional_mod);
682 }
683
684 TEST_F(cmod_propagation_test, add_not_merge_with_compare)
685 {
686 const fs_builder &bld = v->bld;
687 fs_reg dest = v->vgrf(glsl_type::float_type);
688 fs_reg src0 = v->vgrf(glsl_type::float_type);
689 fs_reg src1 = v->vgrf(glsl_type::float_type);
690 bld.ADD(dest, src0, src1);
691 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
692
693 /* The addition and the implicit subtraction in the compare do not compute
694 * related values.
695 *
696 * = Before =
697 * 0: add(8) dest:F src0:F src1:F
698 * 1: cmp.l.f0(8) null:F src0:F src1:F
699 *
700 * = After =
701 * (no changes)
702 */
703 v->calculate_cfg();
704 bblock_t *block0 = v->cfg->blocks[0];
705
706 EXPECT_EQ(0, block0->start_ip);
707 EXPECT_EQ(1, block0->end_ip);
708
709 EXPECT_FALSE(cmod_propagation(v));
710 EXPECT_EQ(0, block0->start_ip);
711 EXPECT_EQ(1, block0->end_ip);
712 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
713 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
714 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
715 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 1)->conditional_mod);
716 }
717
718 TEST_F(cmod_propagation_test, subtract_merge_with_compare)
719 {
720 const fs_builder &bld = v->bld;
721 fs_reg dest = v->vgrf(glsl_type::float_type);
722 fs_reg src0 = v->vgrf(glsl_type::float_type);
723 fs_reg src1 = v->vgrf(glsl_type::float_type);
724 bld.ADD(dest, src0, negate(src1));
725 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
726
727 /* = Before =
728 * 0: add(8) dest:F src0:F -src1:F
729 * 1: cmp.l.f0(8) null:F src0:F src1:F
730 *
731 * = After =
732 * 0: add.l.f0(8) dest:F src0:F -src1:F
733 */
734 v->calculate_cfg();
735 bblock_t *block0 = v->cfg->blocks[0];
736
737 EXPECT_EQ(0, block0->start_ip);
738 EXPECT_EQ(1, block0->end_ip);
739
740 EXPECT_TRUE(cmod_propagation(v));
741 EXPECT_EQ(0, block0->start_ip);
742 EXPECT_EQ(0, block0->end_ip);
743 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
744 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
745 }
746
747 TEST_F(cmod_propagation_test, subtract_immediate_merge_with_compare)
748 {
749 const fs_builder &bld = v->bld;
750 fs_reg dest = v->vgrf(glsl_type::float_type);
751 fs_reg src0 = v->vgrf(glsl_type::float_type);
752 fs_reg one(brw_imm_f(1.0f));
753 fs_reg negative_one(brw_imm_f(-1.0f));
754
755 bld.ADD(dest, src0, negative_one);
756 bld.CMP(bld.null_reg_f(), src0, one, BRW_CONDITIONAL_NZ);
757
758 /* = Before =
759 * 0: add(8) dest:F src0:F -1.0f
760 * 1: cmp.nz.f0(8) null:F src0:F 1.0f
761 *
762 * = After =
763 * 0: add.nz.f0(8) dest:F src0:F -1.0f
764 */
765 v->calculate_cfg();
766 bblock_t *block0 = v->cfg->blocks[0];
767
768 EXPECT_EQ(0, block0->start_ip);
769 EXPECT_EQ(1, block0->end_ip);
770
771 EXPECT_TRUE(cmod_propagation(v));
772 EXPECT_EQ(0, block0->start_ip);
773 EXPECT_EQ(0, block0->end_ip);
774 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
775 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 0)->conditional_mod);
776 }
777
778 TEST_F(cmod_propagation_test, subtract_merge_with_compare_intervening_add)
779 {
780 const fs_builder &bld = v->bld;
781 fs_reg dest0 = v->vgrf(glsl_type::float_type);
782 fs_reg dest1 = v->vgrf(glsl_type::float_type);
783 fs_reg src0 = v->vgrf(glsl_type::float_type);
784 fs_reg src1 = v->vgrf(glsl_type::float_type);
785 bld.ADD(dest0, src0, negate(src1));
786 bld.ADD(dest1, src0, src1);
787 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
788
789 /* = Before =
790 * 0: add(8) dest0:F src0:F -src1:F
791 * 1: add(8) dest1:F src0:F src1:F
792 * 2: cmp.l.f0(8) null:F src0:F src1:F
793 *
794 * = After =
795 * 0: add.l.f0(8) dest0:F src0:F -src1:F
796 * 1: add(8) dest1:F src0:F src1:F
797 */
798 v->calculate_cfg();
799 bblock_t *block0 = v->cfg->blocks[0];
800
801 EXPECT_EQ(0, block0->start_ip);
802 EXPECT_EQ(2, block0->end_ip);
803
804 EXPECT_TRUE(cmod_propagation(v));
805 EXPECT_EQ(0, block0->start_ip);
806 EXPECT_EQ(1, block0->end_ip);
807 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
808 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
809 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 1)->opcode);
810 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 1)->conditional_mod);
811 }
812
813 TEST_F(cmod_propagation_test, subtract_not_merge_with_compare_intervening_partial_write)
814 {
815 const fs_builder &bld = v->bld;
816 fs_reg dest0 = v->vgrf(glsl_type::float_type);
817 fs_reg dest1 = v->vgrf(glsl_type::float_type);
818 fs_reg src0 = v->vgrf(glsl_type::float_type);
819 fs_reg src1 = v->vgrf(glsl_type::float_type);
820 bld.ADD(dest0, src0, negate(src1));
821 set_predicate(BRW_PREDICATE_NORMAL, bld.ADD(dest1, src0, negate(src1)));
822 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
823
824 /* = Before =
825 * 0: add(8) dest0:F src0:F -src1:F
826 * 1: (+f0) add(8) dest1:F src0:F -src1:F
827 * 2: cmp.l.f0(8) null:F src0:F src1:F
828 *
829 * = After =
830 * (no changes)
831 */
832 v->calculate_cfg();
833 bblock_t *block0 = v->cfg->blocks[0];
834
835 EXPECT_EQ(0, block0->start_ip);
836 EXPECT_EQ(2, block0->end_ip);
837
838 EXPECT_FALSE(cmod_propagation(v));
839 EXPECT_EQ(0, block0->start_ip);
840 EXPECT_EQ(2, block0->end_ip);
841 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
842 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
843 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 1)->opcode);
844 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 1)->conditional_mod);
845 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
846 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 2)->conditional_mod);
847 }
848
849 TEST_F(cmod_propagation_test, subtract_not_merge_with_compare_intervening_add)
850 {
851 const fs_builder &bld = v->bld;
852 fs_reg dest0 = v->vgrf(glsl_type::float_type);
853 fs_reg dest1 = v->vgrf(glsl_type::float_type);
854 fs_reg src0 = v->vgrf(glsl_type::float_type);
855 fs_reg src1 = v->vgrf(glsl_type::float_type);
856 bld.ADD(dest0, src0, negate(src1));
857 set_condmod(BRW_CONDITIONAL_EQ, bld.ADD(dest1, src0, src1));
858 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
859
860 /* = Before =
861 * 0: add(8) dest0:F src0:F -src1:F
862 * 1: add.z.f0(8) dest1:F src0:F src1:F
863 * 2: cmp.l.f0(8) null:F src0:F src1:F
864 *
865 * = After =
866 * (no changes)
867 */
868 v->calculate_cfg();
869 bblock_t *block0 = v->cfg->blocks[0];
870
871 EXPECT_EQ(0, block0->start_ip);
872 EXPECT_EQ(2, block0->end_ip);
873
874 EXPECT_FALSE(cmod_propagation(v));
875 EXPECT_EQ(0, block0->start_ip);
876 EXPECT_EQ(2, block0->end_ip);
877 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
878 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
879 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 1)->opcode);
880 EXPECT_EQ(BRW_CONDITIONAL_EQ, instruction(block0, 1)->conditional_mod);
881 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
882 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 2)->conditional_mod);
883 }
884
885 TEST_F(cmod_propagation_test, add_merge_with_compare)
886 {
887 const fs_builder &bld = v->bld;
888 fs_reg dest = v->vgrf(glsl_type::float_type);
889 fs_reg src0 = v->vgrf(glsl_type::float_type);
890 fs_reg src1 = v->vgrf(glsl_type::float_type);
891 bld.ADD(dest, src0, src1);
892 bld.CMP(bld.null_reg_f(), src0, negate(src1), BRW_CONDITIONAL_L);
893
894 /* = Before =
895 * 0: add(8) dest:F src0:F src1:F
896 * 1: cmp.l.f0(8) null:F src0:F -src1:F
897 *
898 * = After =
899 * 0: add.l.f0(8) dest:F src0:F src1:F
900 */
901 v->calculate_cfg();
902 bblock_t *block0 = v->cfg->blocks[0];
903
904 EXPECT_EQ(0, block0->start_ip);
905 EXPECT_EQ(1, block0->end_ip);
906
907 EXPECT_TRUE(cmod_propagation(v));
908 EXPECT_EQ(0, block0->start_ip);
909 EXPECT_EQ(0, block0->end_ip);
910 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
911 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
912 }
913
914 TEST_F(cmod_propagation_test, negative_subtract_merge_with_compare)
915 {
916 const fs_builder &bld = v->bld;
917 fs_reg dest = v->vgrf(glsl_type::float_type);
918 fs_reg src0 = v->vgrf(glsl_type::float_type);
919 fs_reg src1 = v->vgrf(glsl_type::float_type);
920 bld.ADD(dest, src1, negate(src0));
921 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
922
923 /* The result of the subtract is the negatiion of the result of the
924 * implicit subtract in the compare, so the condition must change.
925 *
926 * = Before =
927 * 0: add(8) dest:F src1:F -src0:F
928 * 1: cmp.l.f0(8) null:F src0:F src1:F
929 *
930 * = After =
931 * 0: add.g.f0(8) dest:F src0:F -src1:F
932 */
933 v->calculate_cfg();
934 bblock_t *block0 = v->cfg->blocks[0];
935
936 EXPECT_EQ(0, block0->start_ip);
937 EXPECT_EQ(1, block0->end_ip);
938
939 EXPECT_TRUE(cmod_propagation(v));
940 EXPECT_EQ(0, block0->start_ip);
941 EXPECT_EQ(0, block0->end_ip);
942 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
943 EXPECT_EQ(BRW_CONDITIONAL_G, instruction(block0, 0)->conditional_mod);
944 }
945
946 TEST_F(cmod_propagation_test, subtract_delete_compare)
947 {
948 const fs_builder &bld = v->bld;
949 fs_reg dest = v->vgrf(glsl_type::float_type);
950 fs_reg dest1 = v->vgrf(glsl_type::float_type);
951 fs_reg src0 = v->vgrf(glsl_type::float_type);
952 fs_reg src1 = v->vgrf(glsl_type::float_type);
953 fs_reg src2 = v->vgrf(glsl_type::float_type);
954
955 set_condmod(BRW_CONDITIONAL_L, bld.ADD(dest, src0, negate(src1)));
956 set_predicate(BRW_PREDICATE_NORMAL, bld.MOV(dest1, src2));
957 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
958
959 /* = Before =
960 * 0: add.l.f0(8) dest0:F src0:F -src1:F
961 * 1: (+f0) mov(0) dest1:F src2:F
962 * 2: cmp.l.f0(8) null:F src0:F src1:F
963 *
964 * = After =
965 * 0: add.l.f0(8) dest:F src0:F -src1:F
966 * 1: (+f0) mov(0) dest1:F src2:F
967 */
968 v->calculate_cfg();
969 bblock_t *block0 = v->cfg->blocks[0];
970
971 EXPECT_EQ(0, block0->start_ip);
972 EXPECT_EQ(2, block0->end_ip);
973
974 EXPECT_TRUE(cmod_propagation(v));
975 EXPECT_EQ(0, block0->start_ip);
976 EXPECT_EQ(1, block0->end_ip);
977 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
978 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
979 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
980 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
981 }
982
983 TEST_F(cmod_propagation_test, subtract_delete_compare_other_flag)
984 {
985 /* This test is the same as subtract_delete_compare but it explicitly used
986 * flag f0.1 for the subtraction and the comparison.
987 */
988 const fs_builder &bld = v->bld;
989 fs_reg dest = v->vgrf(glsl_type::float_type);
990 fs_reg dest1 = v->vgrf(glsl_type::float_type);
991 fs_reg src0 = v->vgrf(glsl_type::float_type);
992 fs_reg src1 = v->vgrf(glsl_type::float_type);
993 fs_reg src2 = v->vgrf(glsl_type::float_type);
994
995 set_condmod(BRW_CONDITIONAL_L, bld.ADD(dest, src0, negate(src1)))
996 ->flag_subreg = 1;
997 set_predicate(BRW_PREDICATE_NORMAL, bld.MOV(dest1, src2));
998 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L)
999 ->flag_subreg = 1;
1000
1001 /* = Before =
1002 * 0: add.l.f0.1(8) dest0:F src0:F -src1:F
1003 * 1: (+f0) mov(0) dest1:F src2:F
1004 * 2: cmp.l.f0.1(8) null:F src0:F src1:F
1005 *
1006 * = After =
1007 * 0: add.l.f0.1(8) dest:F src0:F -src1:F
1008 * 1: (+f0) mov(0) dest1:F src2:F
1009 */
1010 v->calculate_cfg();
1011 bblock_t *block0 = v->cfg->blocks[0];
1012
1013 EXPECT_EQ(0, block0->start_ip);
1014 EXPECT_EQ(2, block0->end_ip);
1015
1016 EXPECT_TRUE(cmod_propagation(v));
1017 EXPECT_EQ(0, block0->start_ip);
1018 EXPECT_EQ(1, block0->end_ip);
1019 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1020 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
1021 EXPECT_EQ(1, instruction(block0, 0)->flag_subreg);
1022 EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
1023 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
1024 }
1025
1026 TEST_F(cmod_propagation_test, subtract_to_mismatch_flag)
1027 {
1028 const fs_builder &bld = v->bld;
1029 fs_reg dest = v->vgrf(glsl_type::float_type);
1030 fs_reg src0 = v->vgrf(glsl_type::float_type);
1031 fs_reg src1 = v->vgrf(glsl_type::float_type);
1032
1033 set_condmod(BRW_CONDITIONAL_L, bld.ADD(dest, src0, negate(src1)));
1034 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L)
1035 ->flag_subreg = 1;
1036
1037 /* = Before =
1038 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1039 * 1: cmp.l.f0.1(8) null:F src0:F src1:F
1040 *
1041 * = After =
1042 * No changes
1043 */
1044 v->calculate_cfg();
1045 bblock_t *block0 = v->cfg->blocks[0];
1046
1047 EXPECT_EQ(0, block0->start_ip);
1048 EXPECT_EQ(1, block0->end_ip);
1049
1050 EXPECT_FALSE(cmod_propagation(v));
1051 EXPECT_EQ(0, block0->start_ip);
1052 EXPECT_EQ(1, block0->end_ip);
1053 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1054 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
1055 EXPECT_EQ(0, instruction(block0, 0)->flag_subreg);
1056 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
1057 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 1)->conditional_mod);
1058 EXPECT_EQ(1, instruction(block0, 1)->flag_subreg);
1059 }
1060
1061 TEST_F(cmod_propagation_test,
1062 subtract_merge_with_compare_intervening_mismatch_flag_write)
1063 {
1064 const fs_builder &bld = v->bld;
1065 fs_reg dest0 = v->vgrf(glsl_type::float_type);
1066 fs_reg src0 = v->vgrf(glsl_type::float_type);
1067 fs_reg src1 = v->vgrf(glsl_type::float_type);
1068
1069 bld.ADD(dest0, src0, negate(src1));
1070 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L)
1071 ->flag_subreg = 1;
1072 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
1073
1074 /* = Before =
1075 * 0: add(8) dest0:F src0:F -src1:F
1076 * 1: cmp.l.f0.1(8) null:F src0:F src1:F
1077 * 2: cmp.l.f0(8) null:F src0:F src1:F
1078 *
1079 * = After =
1080 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1081 * 1: cmp.l.f0.1(8) null:F src0:F src1:F
1082 *
1083 * NOTE: Another perfectly valid after sequence would be:
1084 *
1085 * 0: add.f0.1(8) dest0:F src0:F -src1:F
1086 * 1: cmp.l.f0(8) null:F src0:F src1:F
1087 *
1088 * However, the optimization pass starts at the end of the basic block.
1089 * Because of this, the cmp.l.f0 will always be chosen. If the pass
1090 * changes its strategy, this test will also need to change.
1091 */
1092 v->calculate_cfg();
1093 bblock_t *block0 = v->cfg->blocks[0];
1094
1095 EXPECT_EQ(0, block0->start_ip);
1096 EXPECT_EQ(2, block0->end_ip);
1097
1098 EXPECT_TRUE(cmod_propagation(v));
1099 EXPECT_EQ(0, block0->start_ip);
1100 EXPECT_EQ(1, block0->end_ip);
1101 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1102 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
1103 EXPECT_EQ(0, instruction(block0, 0)->flag_subreg);
1104 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
1105 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 1)->conditional_mod);
1106 EXPECT_EQ(1, instruction(block0, 1)->flag_subreg);
1107 }
1108
1109 TEST_F(cmod_propagation_test,
1110 subtract_merge_with_compare_intervening_mismatch_flag_read)
1111 {
1112 const fs_builder &bld = v->bld;
1113 fs_reg dest0 = v->vgrf(glsl_type::float_type);
1114 fs_reg dest1 = v->vgrf(glsl_type::float_type);
1115 fs_reg src0 = v->vgrf(glsl_type::float_type);
1116 fs_reg src1 = v->vgrf(glsl_type::float_type);
1117 fs_reg src2 = v->vgrf(glsl_type::float_type);
1118 fs_reg zero(brw_imm_f(0.0f));
1119
1120 bld.ADD(dest0, src0, negate(src1));
1121 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero))
1122 ->flag_subreg = 1;
1123 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
1124
1125 /* = Before =
1126 * 0: add(8) dest0:F src0:F -src1:F
1127 * 1: (+f0.1) sel(8) dest1 src2 0.0f
1128 * 2: cmp.l.f0(8) null:F src0:F src1:F
1129 *
1130 * = After =
1131 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1132 * 1: (+f0.1) sel(8) dest1 src2 0.0f
1133 */
1134 v->calculate_cfg();
1135 bblock_t *block0 = v->cfg->blocks[0];
1136
1137 EXPECT_EQ(0, block0->start_ip);
1138 EXPECT_EQ(2, block0->end_ip);
1139
1140 EXPECT_TRUE(cmod_propagation(v));
1141 EXPECT_EQ(0, block0->start_ip);
1142 EXPECT_EQ(1, block0->end_ip);
1143 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1144 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
1145 EXPECT_EQ(0, instruction(block0, 0)->flag_subreg);
1146 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
1147 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
1148 EXPECT_EQ(1, instruction(block0, 1)->flag_subreg);
1149 }
1150
1151 TEST_F(cmod_propagation_test, subtract_delete_compare_derp)
1152 {
1153 const fs_builder &bld = v->bld;
1154 fs_reg dest0 = v->vgrf(glsl_type::float_type);
1155 fs_reg dest1 = v->vgrf(glsl_type::float_type);
1156 fs_reg src0 = v->vgrf(glsl_type::float_type);
1157 fs_reg src1 = v->vgrf(glsl_type::float_type);
1158
1159 set_condmod(BRW_CONDITIONAL_L, bld.ADD(dest0, src0, negate(src1)));
1160 set_predicate(BRW_PREDICATE_NORMAL, bld.ADD(dest1, negate(src0), src1));
1161 bld.CMP(bld.null_reg_f(), src0, src1, BRW_CONDITIONAL_L);
1162
1163 /* = Before =
1164 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1165 * 1: (+f0) add(0) dest1:F -src0:F src1:F
1166 * 2: cmp.l.f0(8) null:F src0:F src1:F
1167 *
1168 * = After =
1169 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1170 * 1: (+f0) add(0) dest1:F -src0:F src1:F
1171 */
1172 v->calculate_cfg();
1173 bblock_t *block0 = v->cfg->blocks[0];
1174
1175 EXPECT_EQ(0, block0->start_ip);
1176 EXPECT_EQ(2, block0->end_ip);
1177
1178 EXPECT_TRUE(cmod_propagation(v));
1179 EXPECT_EQ(0, block0->start_ip);
1180 EXPECT_EQ(1, block0->end_ip);
1181 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1182 EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
1183 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 1)->opcode);
1184 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
1185 }
1186
1187 TEST_F(cmod_propagation_test, signed_unsigned_comparison_mismatch)
1188 {
1189 const fs_builder &bld = v->bld;
1190 fs_reg dest0 = v->vgrf(glsl_type::int_type);
1191 fs_reg src0 = v->vgrf(glsl_type::int_type);
1192 src0.type = BRW_REGISTER_TYPE_W;
1193
1194 bld.ASR(dest0, negate(src0), brw_imm_d(15));
1195 bld.CMP(bld.null_reg_ud(), retype(dest0, BRW_REGISTER_TYPE_UD),
1196 brw_imm_ud(0u), BRW_CONDITIONAL_LE);
1197
1198 /* = Before =
1199 * 0: asr(8) dest:D -src0:W 15D
1200 * 1: cmp.le.f0(8) null:UD dest:UD 0UD
1201 *
1202 * = After =
1203 * (no changes)
1204 */
1205 v->calculate_cfg();
1206 bblock_t *block0 = v->cfg->blocks[0];
1207
1208 EXPECT_EQ(0, block0->start_ip);
1209 EXPECT_EQ(1, block0->end_ip);
1210
1211 EXPECT_FALSE(cmod_propagation(v));
1212 EXPECT_EQ(0, block0->start_ip);
1213 EXPECT_EQ(1, block0->end_ip);
1214 EXPECT_EQ(BRW_OPCODE_ASR, instruction(block0, 0)->opcode);
1215 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
1216 EXPECT_EQ(BRW_CONDITIONAL_LE, instruction(block0, 1)->conditional_mod);
1217 }
1218
1219 void
1220 cmod_propagation_test::test_positive_float_saturate_prop(enum brw_conditional_mod before,
1221 enum brw_conditional_mod after,
1222 enum opcode op)
1223 {
1224 const fs_builder &bld = v->bld;
1225 fs_reg dest = v->vgrf(glsl_type::float_type);
1226 fs_reg src0 = v->vgrf(glsl_type::float_type);
1227 fs_reg src1 = v->vgrf(glsl_type::float_type);
1228 fs_reg zero(brw_imm_f(0.0f));
1229 bld.ADD(dest, src0, src1)->saturate = true;
1230
1231 assert(op == BRW_OPCODE_CMP || op == BRW_OPCODE_MOV);
1232 if (op == BRW_OPCODE_CMP)
1233 bld.CMP(bld.null_reg_f(), dest, zero, before);
1234 else
1235 bld.MOV(bld.null_reg_f(), dest)->conditional_mod = before;
1236
1237 v->calculate_cfg();
1238 bblock_t *block0 = v->cfg->blocks[0];
1239
1240 EXPECT_EQ(0, block0->start_ip);
1241 EXPECT_EQ(1, block0->end_ip);
1242
1243 EXPECT_TRUE(cmod_propagation(v));
1244 EXPECT_EQ(0, block0->start_ip);
1245 EXPECT_EQ(0, block0->end_ip);
1246 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1247 EXPECT_TRUE(instruction(block0, 0)->saturate);
1248 EXPECT_EQ(after, instruction(block0, 0)->conditional_mod);
1249 }
1250
1251 void
1252 cmod_propagation_test::test_negative_float_saturate_prop(enum brw_conditional_mod before,
1253 enum opcode op)
1254 {
1255 const fs_builder &bld = v->bld;
1256 fs_reg dest = v->vgrf(glsl_type::float_type);
1257 fs_reg src0 = v->vgrf(glsl_type::float_type);
1258 fs_reg src1 = v->vgrf(glsl_type::float_type);
1259 fs_reg zero(brw_imm_f(0.0f));
1260 bld.ADD(dest, src0, src1)->saturate = true;
1261
1262 assert(op == BRW_OPCODE_CMP || op == BRW_OPCODE_MOV);
1263 if (op == BRW_OPCODE_CMP)
1264 bld.CMP(bld.null_reg_f(), dest, zero, before);
1265 else
1266 bld.MOV(bld.null_reg_f(), dest)->conditional_mod = before;
1267
1268 v->calculate_cfg();
1269 bblock_t *block0 = v->cfg->blocks[0];
1270
1271 EXPECT_EQ(0, block0->start_ip);
1272 EXPECT_EQ(1, block0->end_ip);
1273
1274 EXPECT_FALSE(cmod_propagation(v));
1275 EXPECT_EQ(0, block0->start_ip);
1276 EXPECT_EQ(1, block0->end_ip);
1277 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1278 EXPECT_TRUE(instruction(block0, 0)->saturate);
1279 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
1280 EXPECT_EQ(op, instruction(block0, 1)->opcode);
1281 EXPECT_FALSE(instruction(block0, 1)->saturate);
1282 EXPECT_EQ(before, instruction(block0, 1)->conditional_mod);
1283 }
1284
1285 void
1286 cmod_propagation_test::test_negative_int_saturate_prop(enum brw_conditional_mod before,
1287 enum opcode op)
1288 {
1289 const fs_builder &bld = v->bld;
1290 fs_reg dest = v->vgrf(glsl_type::int_type);
1291 fs_reg src0 = v->vgrf(glsl_type::int_type);
1292 fs_reg src1 = v->vgrf(glsl_type::int_type);
1293 fs_reg zero(brw_imm_d(0));
1294 bld.ADD(dest, src0, src1)->saturate = true;
1295
1296 assert(op == BRW_OPCODE_CMP || op == BRW_OPCODE_MOV);
1297 if (op == BRW_OPCODE_CMP)
1298 bld.CMP(bld.null_reg_d(), dest, zero, before);
1299 else
1300 bld.MOV(bld.null_reg_d(), dest)->conditional_mod = before;
1301
1302 v->calculate_cfg();
1303 bblock_t *block0 = v->cfg->blocks[0];
1304
1305 EXPECT_EQ(0, block0->start_ip);
1306 EXPECT_EQ(1, block0->end_ip);
1307
1308 EXPECT_FALSE(cmod_propagation(v));
1309 EXPECT_EQ(0, block0->start_ip);
1310 EXPECT_EQ(1, block0->end_ip);
1311 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1312 EXPECT_TRUE(instruction(block0, 0)->saturate);
1313 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
1314 EXPECT_EQ(op, instruction(block0, 1)->opcode);
1315 EXPECT_FALSE(instruction(block0, 1)->saturate);
1316 EXPECT_EQ(before, instruction(block0, 1)->conditional_mod);
1317 }
1318
1319 TEST_F(cmod_propagation_test, float_saturate_nz_cmp)
1320 {
1321 /* With the saturate modifier, the comparison happens before clamping to
1322 * [0, 1]. (sat(x) != 0) == (x > 0).
1323 *
1324 * = Before =
1325 *
1326 * 0: add.sat(8) dest src0 src1
1327 * 1: cmp.nz.f0(8) null dest 0.0f
1328 *
1329 * = After =
1330 * 0: add.sat.g.f0(8) dest src0 src1
1331 */
1332 test_positive_float_saturate_prop(BRW_CONDITIONAL_NZ, BRW_CONDITIONAL_G,
1333 BRW_OPCODE_CMP);
1334 }
1335
1336 TEST_F(cmod_propagation_test, float_saturate_nz_mov)
1337 {
1338 /* With the saturate modifier, the comparison happens before clamping to
1339 * [0, 1]. (sat(x) != 0) == (x > 0).
1340 *
1341 * = Before =
1342 *
1343 * 0: add.sat(8) dest src0 src1
1344 * 1: mov.nz.f0(8) null dest
1345 *
1346 * = After =
1347 * 0: add.sat.g.f0(8) dest src0 src1
1348 */
1349 test_positive_float_saturate_prop(BRW_CONDITIONAL_NZ, BRW_CONDITIONAL_G,
1350 BRW_OPCODE_MOV);
1351 }
1352
1353 TEST_F(cmod_propagation_test, float_saturate_z_cmp)
1354 {
1355 /* With the saturate modifier, the comparison happens before clamping to
1356 * [0, 1]. (sat(x) == 0) == (x <= 0).
1357 *
1358 * = Before =
1359 *
1360 * 0: add.sat(8) dest src0 src1
1361 * 1: cmp.z.f0(8) null dest 0.0f
1362 *
1363 * = After =
1364 * 0: add.sat.le.f0(8) dest src0 src1
1365 */
1366 test_positive_float_saturate_prop(BRW_CONDITIONAL_Z, BRW_CONDITIONAL_LE,
1367 BRW_OPCODE_CMP);
1368 }
1369
1370 TEST_F(cmod_propagation_test, float_saturate_z_mov)
1371 {
1372 /* With the saturate modifier, the comparison happens before clamping to
1373 * [0, 1]. (sat(x) == 0) == (x <= 0).
1374 *
1375 * = Before =
1376 *
1377 * 0: add.sat(8) dest src0 src1
1378 * 1: mov.z.f0(8) null dest
1379 *
1380 * = After =
1381 * 0: add.sat.le.f0(8) dest src0 src1
1382 */
1383 #if 1
1384 /* cmod propagation bails on every MOV except MOV.NZ. */
1385 test_negative_float_saturate_prop(BRW_CONDITIONAL_Z, BRW_OPCODE_MOV);
1386 #else
1387 test_positive_float_saturate_prop(BRW_CONDITIONAL_Z, BRW_CONDITIONAL_LE,
1388 BRW_OPCODE_MOV);
1389 #endif
1390 }
1391
1392 TEST_F(cmod_propagation_test, float_saturate_g_cmp)
1393 {
1394 /* With the saturate modifier, the comparison happens before clamping to
1395 * [0, 1]. (sat(x) > 0) == (x > 0).
1396 *
1397 * = Before =
1398 *
1399 * 0: add.sat(8) dest src0 src1
1400 * 1: cmp.g.f0(8) null dest 0.0f
1401 *
1402 * = After =
1403 * 0: add.sat.g.f0(8) dest src0 src1
1404 */
1405 test_positive_float_saturate_prop(BRW_CONDITIONAL_G, BRW_CONDITIONAL_G,
1406 BRW_OPCODE_CMP);
1407 }
1408
1409 TEST_F(cmod_propagation_test, float_saturate_g_mov)
1410 {
1411 /* With the saturate modifier, the comparison happens before clamping to
1412 * [0, 1]. (sat(x) > 0) == (x > 0).
1413 *
1414 * = Before =
1415 *
1416 * 0: add.sat(8) dest src0 src1
1417 * 1: mov.g.f0(8) null dest
1418 *
1419 * = After =
1420 * 0: add.sat.g.f0(8) dest src0 src1
1421 */
1422 #if 1
1423 /* cmod propagation bails on every MOV except MOV.NZ. */
1424 test_negative_float_saturate_prop(BRW_CONDITIONAL_G, BRW_OPCODE_MOV);
1425 #else
1426 test_positive_float_saturate_prop(BRW_CONDITIONAL_G, BRW_CONDITIONAL_G,
1427 BRW_OPCODE_MOV);
1428 #endif
1429 }
1430
1431 TEST_F(cmod_propagation_test, float_saturate_le_cmp)
1432 {
1433 /* With the saturate modifier, the comparison happens before clamping to
1434 * [0, 1]. (sat(x) <= 0) == (x <= 0).
1435 *
1436 * = Before =
1437 *
1438 * 0: add.sat(8) dest src0 src1
1439 * 1: cmp.le.f0(8) null dest 0.0f
1440 *
1441 * = After =
1442 * 0: add.sat.le.f0(8) dest src0 src1
1443 */
1444 test_positive_float_saturate_prop(BRW_CONDITIONAL_LE, BRW_CONDITIONAL_LE,
1445 BRW_OPCODE_CMP);
1446 }
1447
1448 TEST_F(cmod_propagation_test, float_saturate_le_mov)
1449 {
1450 /* With the saturate modifier, the comparison happens before clamping to
1451 * [0, 1]. (sat(x) <= 0) == (x <= 0).
1452 *
1453 * = Before =
1454 *
1455 * 0: add.sat(8) dest src0 src1
1456 * 1: mov.le.f0(8) null dest
1457 *
1458 * = After =
1459 * 0: add.sat.le.f0(8) dest src0 src1
1460 */
1461 #if 1
1462 /* cmod propagation bails on every MOV except MOV.NZ. */
1463 test_negative_float_saturate_prop(BRW_CONDITIONAL_LE, BRW_OPCODE_MOV);
1464 #else
1465 test_positive_float_saturate_prop(BRW_CONDITIONAL_LE, BRW_CONDITIONAL_LE,
1466 BRW_OPCODE_MOV);
1467 #endif
1468 }
1469
1470 TEST_F(cmod_propagation_test, float_saturate_l_cmp)
1471 {
1472 /* With the saturate modifier, the comparison happens before clamping to
1473 * [0, 1]. There is no before / after equivalence for (sat(x) < 0).
1474 *
1475 * = Before =
1476 *
1477 * 0: add.sat(8) dest src0 src1
1478 * 1: cmp.l.f0(8) null dest 0.0f
1479 *
1480 * = After =
1481 * No change
1482 */
1483 test_negative_float_saturate_prop(BRW_CONDITIONAL_L, BRW_OPCODE_CMP);
1484 }
1485
1486 #if 0
1487 TEST_F(cmod_propagation_test, float_saturate_l_mov)
1488 {
1489 /* With the saturate modifier, the comparison happens before clamping to
1490 * [0, 1]. There is no before / after equivalence for (sat(x) < 0).
1491 *
1492 * = Before =
1493 *
1494 * 0: add.sat(8) dest src0 src1
1495 * 1: mov.l.f0(8) null dest 0.0f
1496 *
1497 * = After =
1498 * No change
1499 */
1500 test_negative_float_saturate_prop(BRW_CONDITIONAL_L, BRW_OPCODE_MOV);
1501 }
1502 #endif
1503
1504 TEST_F(cmod_propagation_test, float_saturate_ge_cmp)
1505 {
1506 /* With the saturate modifier, the comparison happens before clamping to
1507 * [0, 1]. There is no before / after equivalence for (sat(x) >= 0).
1508 *
1509 * = Before =
1510 *
1511 * 0: add.sat(8) dest src0 src1
1512 * 1: cmp.ge.f0(8) null dest 0.0f
1513 *
1514 * = After =
1515 * No change
1516 */
1517 test_negative_float_saturate_prop(BRW_CONDITIONAL_GE, BRW_OPCODE_CMP);
1518 }
1519
1520 TEST_F(cmod_propagation_test, float_saturate_ge_mov)
1521 {
1522 /* With the saturate modifier, the comparison happens before clamping to
1523 * [0, 1]. There is no before / after equivalence for (sat(x) >= 0).
1524 *
1525 * = Before =
1526 *
1527 * 0: add.sat(8) dest src0 src1
1528 * 1: mov.ge.f0(8) null dest 0.0f
1529 *
1530 * = After =
1531 * No change
1532 */
1533 test_negative_float_saturate_prop(BRW_CONDITIONAL_GE, BRW_OPCODE_MOV);
1534 }
1535
1536 TEST_F(cmod_propagation_test, int_saturate_nz_cmp)
1537 {
1538 /* = Before =
1539 *
1540 * 0: add.sat(8) dest src0 src1
1541 * 1: cmp.nz.f0(8) null dest 0
1542 *
1543 * = After =
1544 * No change.
1545 */
1546 test_negative_int_saturate_prop(BRW_CONDITIONAL_NZ, BRW_OPCODE_CMP);
1547 }
1548
1549 TEST_F(cmod_propagation_test, int_saturate_nz_mov)
1550 {
1551 /* = Before =
1552 *
1553 * 0: add.sat(8) dest src0 src1
1554 * 1: mov.nz.f0(8) null dest
1555 *
1556 * = After =
1557 * No change.
1558 */
1559 test_negative_int_saturate_prop(BRW_CONDITIONAL_NZ, BRW_OPCODE_MOV);
1560 }
1561
1562 TEST_F(cmod_propagation_test, int_saturate_z_cmp)
1563 {
1564 /* = Before =
1565 *
1566 * 0: add.sat(8) dest src0 src1
1567 * 1: cmp.z.f0(8) null dest 0
1568 *
1569 * = After =
1570 * No change.
1571 */
1572 test_negative_int_saturate_prop(BRW_CONDITIONAL_Z, BRW_OPCODE_CMP);
1573 }
1574
1575 TEST_F(cmod_propagation_test, int_saturate_z_mov)
1576 {
1577 /* With the saturate modifier, the comparison happens before clamping to
1578 * [0, 1]. (sat(x) == 0) == (x <= 0).
1579 *
1580 * = Before =
1581 *
1582 * 0: add.sat(8) dest src0 src1
1583 * 1: mov.z.f0(8) null dest
1584 *
1585 * = After =
1586 * No change.
1587 */
1588 test_negative_int_saturate_prop(BRW_CONDITIONAL_Z, BRW_OPCODE_MOV);
1589 }
1590
1591 TEST_F(cmod_propagation_test, int_saturate_g_cmp)
1592 {
1593 /* = Before =
1594 *
1595 * 0: add.sat(8) dest src0 src1
1596 * 1: cmp.g.f0(8) null dest 0
1597 *
1598 * = After =
1599 * No change.
1600 */
1601 test_negative_int_saturate_prop(BRW_CONDITIONAL_G, BRW_OPCODE_CMP);
1602 }
1603
1604 TEST_F(cmod_propagation_test, int_saturate_g_mov)
1605 {
1606 /* = Before =
1607 *
1608 * 0: add.sat(8) dest src0 src1
1609 * 1: mov.g.f0(8) null dest
1610 *
1611 * = After =
1612 * No change.
1613 */
1614 test_negative_int_saturate_prop(BRW_CONDITIONAL_G, BRW_OPCODE_MOV);
1615 }
1616
1617 TEST_F(cmod_propagation_test, int_saturate_le_cmp)
1618 {
1619 /* = Before =
1620 *
1621 * 0: add.sat(8) dest src0 src1
1622 * 1: cmp.le.f0(8) null dest 0
1623 *
1624 * = After =
1625 * No change.
1626 */
1627 test_negative_int_saturate_prop(BRW_CONDITIONAL_LE, BRW_OPCODE_CMP);
1628 }
1629
1630 TEST_F(cmod_propagation_test, int_saturate_le_mov)
1631 {
1632 /* = Before =
1633 *
1634 * 0: add.sat(8) dest src0 src1
1635 * 1: mov.le.f0(8) null dest
1636 *
1637 * = After =
1638 * No change.
1639 */
1640 test_negative_int_saturate_prop(BRW_CONDITIONAL_LE, BRW_OPCODE_MOV);
1641 }
1642
1643 TEST_F(cmod_propagation_test, int_saturate_l_cmp)
1644 {
1645 /* = Before =
1646 *
1647 * 0: add.sat(8) dest src0 src1
1648 * 1: cmp.l.f0(8) null dest 0
1649 *
1650 * = After =
1651 * No change
1652 */
1653 test_negative_int_saturate_prop(BRW_CONDITIONAL_L, BRW_OPCODE_CMP);
1654 }
1655
1656 TEST_F(cmod_propagation_test, int_saturate_l_mov)
1657 {
1658 /* = Before =
1659 *
1660 * 0: add.sat(8) dest src0 src1
1661 * 1: mov.l.f0(8) null dest 0
1662 *
1663 * = After =
1664 * No change
1665 */
1666 test_negative_int_saturate_prop(BRW_CONDITIONAL_L, BRW_OPCODE_MOV);
1667 }
1668
1669 TEST_F(cmod_propagation_test, int_saturate_ge_cmp)
1670 {
1671 /* = Before =
1672 *
1673 * 0: add.sat(8) dest src0 src1
1674 * 1: cmp.ge.f0(8) null dest 0
1675 *
1676 * = After =
1677 * No change
1678 */
1679 test_negative_int_saturate_prop(BRW_CONDITIONAL_GE, BRW_OPCODE_CMP);
1680 }
1681
1682 TEST_F(cmod_propagation_test, int_saturate_ge_mov)
1683 {
1684 /* = Before =
1685 *
1686 * 0: add.sat(8) dest src0 src1
1687 * 1: mov.ge.f0(8) null dest
1688 *
1689 * = After =
1690 * No change
1691 */
1692 test_negative_int_saturate_prop(BRW_CONDITIONAL_GE, BRW_OPCODE_MOV);
1693 }
1694
1695 TEST_F(cmod_propagation_test, not_to_or)
1696 {
1697 /* Exercise propagation of conditional modifier from a NOT instruction to
1698 * another ALU instruction as performed by cmod_propagate_not.
1699 */
1700 const fs_builder &bld = v->bld;
1701 fs_reg dest = v->vgrf(glsl_type::uint_type);
1702 fs_reg src0 = v->vgrf(glsl_type::uint_type);
1703 fs_reg src1 = v->vgrf(glsl_type::uint_type);
1704 bld.OR(dest, src0, src1);
1705 set_condmod(BRW_CONDITIONAL_NZ, bld.NOT(bld.null_reg_ud(), dest));
1706
1707 /* = Before =
1708 *
1709 * 0: or(8) dest src0 src1
1710 * 1: not.nz.f0(8) null dest
1711 *
1712 * = After =
1713 * 0: or.z.f0(8) dest src0 src1
1714 */
1715
1716 v->calculate_cfg();
1717 bblock_t *block0 = v->cfg->blocks[0];
1718
1719 EXPECT_EQ(0, block0->start_ip);
1720 EXPECT_EQ(1, block0->end_ip);
1721
1722 EXPECT_TRUE(cmod_propagation(v));
1723 EXPECT_EQ(0, block0->start_ip);
1724 EXPECT_EQ(0, block0->end_ip);
1725 EXPECT_EQ(BRW_OPCODE_OR, instruction(block0, 0)->opcode);
1726 EXPECT_EQ(BRW_CONDITIONAL_Z, instruction(block0, 0)->conditional_mod);
1727 }
1728
1729 TEST_F(cmod_propagation_test, not_to_and)
1730 {
1731 /* Exercise propagation of conditional modifier from a NOT instruction to
1732 * another ALU instruction as performed by cmod_propagate_not.
1733 */
1734 const fs_builder &bld = v->bld;
1735 fs_reg dest = v->vgrf(glsl_type::uint_type);
1736 fs_reg src0 = v->vgrf(glsl_type::uint_type);
1737 fs_reg src1 = v->vgrf(glsl_type::uint_type);
1738 bld.AND(dest, src0, src1);
1739 set_condmod(BRW_CONDITIONAL_NZ, bld.NOT(bld.null_reg_ud(), dest));
1740
1741 /* = Before =
1742 *
1743 * 0: and(8) dest src0 src1
1744 * 1: not.nz.f0(8) null dest
1745 *
1746 * = After =
1747 * 0: and.z.f0(8) dest src0 src1
1748 */
1749
1750 v->calculate_cfg();
1751 bblock_t *block0 = v->cfg->blocks[0];
1752
1753 EXPECT_EQ(0, block0->start_ip);
1754 EXPECT_EQ(1, block0->end_ip);
1755
1756 EXPECT_TRUE(cmod_propagation(v));
1757 EXPECT_EQ(0, block0->start_ip);
1758 EXPECT_EQ(0, block0->end_ip);
1759 EXPECT_EQ(BRW_OPCODE_AND, instruction(block0, 0)->opcode);
1760 EXPECT_EQ(BRW_CONDITIONAL_Z, instruction(block0, 0)->conditional_mod);
1761 }
1762
1763 TEST_F(cmod_propagation_test, not_to_uadd)
1764 {
1765 /* Exercise propagation of conditional modifier from a NOT instruction to
1766 * another ALU instruction as performed by cmod_propagate_not.
1767 *
1768 * The optimization pass currently restricts to just OR and AND. It's
1769 * possible that this is too restrictive, and the actual, necessary
1770 * restriction is just the the destination type of the ALU instruction is
1771 * the same as the source type of the NOT instruction.
1772 */
1773 const fs_builder &bld = v->bld;
1774 fs_reg dest = v->vgrf(glsl_type::uint_type);
1775 fs_reg src0 = v->vgrf(glsl_type::uint_type);
1776 fs_reg src1 = v->vgrf(glsl_type::uint_type);
1777 bld.ADD(dest, src0, src1);
1778 set_condmod(BRW_CONDITIONAL_NZ, bld.NOT(bld.null_reg_ud(), dest));
1779
1780 /* = Before =
1781 *
1782 * 0: add(8) dest src0 src1
1783 * 1: not.nz.f0(8) null dest
1784 *
1785 * = After =
1786 * No changes
1787 */
1788
1789 v->calculate_cfg();
1790 bblock_t *block0 = v->cfg->blocks[0];
1791
1792 EXPECT_EQ(0, block0->start_ip);
1793 EXPECT_EQ(1, block0->end_ip);
1794
1795 EXPECT_FALSE(cmod_propagation(v));
1796 EXPECT_EQ(0, block0->start_ip);
1797 EXPECT_EQ(1, block0->end_ip);
1798 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1799 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
1800 EXPECT_EQ(BRW_OPCODE_NOT, instruction(block0, 1)->opcode);
1801 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
1802 }
1803
1804 TEST_F(cmod_propagation_test, not_to_fadd_to_ud)
1805 {
1806 /* Exercise propagation of conditional modifier from a NOT instruction to
1807 * another ALU instruction as performed by cmod_propagate_not.
1808 *
1809 * The optimization pass currently restricts to just OR and AND. It's
1810 * possible that this is too restrictive, and the actual, necessary
1811 * restriction is just the the destination type of the ALU instruction is
1812 * the same as the source type of the NOT instruction.
1813 */
1814 const fs_builder &bld = v->bld;
1815 fs_reg dest = v->vgrf(glsl_type::uint_type);
1816 fs_reg src0 = v->vgrf(glsl_type::float_type);
1817 fs_reg src1 = v->vgrf(glsl_type::float_type);
1818 bld.ADD(dest, src0, src1);
1819 set_condmod(BRW_CONDITIONAL_NZ, bld.NOT(bld.null_reg_ud(), dest));
1820
1821 /* = Before =
1822 *
1823 * 0: add(8) dest.ud src0.f src1.f
1824 * 1: not.nz.f0(8) null dest.ud
1825 *
1826 * = After =
1827 * No changes
1828 */
1829
1830 v->calculate_cfg();
1831 bblock_t *block0 = v->cfg->blocks[0];
1832
1833 EXPECT_EQ(0, block0->start_ip);
1834 EXPECT_EQ(1, block0->end_ip);
1835
1836 EXPECT_FALSE(cmod_propagation(v));
1837 EXPECT_EQ(0, block0->start_ip);
1838 EXPECT_EQ(1, block0->end_ip);
1839 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1840 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
1841 EXPECT_EQ(BRW_OPCODE_NOT, instruction(block0, 1)->opcode);
1842 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
1843 }
1844
1845 TEST_F(cmod_propagation_test, not_to_fadd)
1846 {
1847 /* Exercise propagation of conditional modifier from a NOT instruction to
1848 * another ALU instruction as performed by cmod_propagate_not.
1849 *
1850 * The optimization pass currently restricts to just OR and AND. It's
1851 * possible that this is too restrictive, and the actual, necessary
1852 * restriction is just the the destination type of the ALU instruction is
1853 * the same as the source type of the NOT instruction.
1854 */
1855 const fs_builder &bld = v->bld;
1856 fs_reg dest = v->vgrf(glsl_type::float_type);
1857 fs_reg src0 = v->vgrf(glsl_type::float_type);
1858 fs_reg src1 = v->vgrf(glsl_type::float_type);
1859 bld.ADD(dest, src0, src1);
1860 set_condmod(BRW_CONDITIONAL_NZ,
1861 bld.NOT(bld.null_reg_ud(),
1862 retype(dest, BRW_REGISTER_TYPE_UD)));
1863
1864 /* = Before =
1865 *
1866 * 0: add(8) dest.f src0.f src1.f
1867 * 1: not.nz.f0(8) null dest.ud
1868 *
1869 * = After =
1870 * No changes
1871 */
1872
1873 v->calculate_cfg();
1874 bblock_t *block0 = v->cfg->blocks[0];
1875
1876 EXPECT_EQ(0, block0->start_ip);
1877 EXPECT_EQ(1, block0->end_ip);
1878
1879 EXPECT_FALSE(cmod_propagation(v));
1880 EXPECT_EQ(0, block0->start_ip);
1881 EXPECT_EQ(1, block0->end_ip);
1882 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1883 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
1884 EXPECT_EQ(BRW_OPCODE_NOT, instruction(block0, 1)->opcode);
1885 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
1886 }
1887
1888 TEST_F(cmod_propagation_test, not_to_or_intervening_flag_read_compatible_value)
1889 {
1890 /* Exercise propagation of conditional modifier from a NOT instruction to
1891 * another ALU instruction as performed by cmod_propagate_not.
1892 */
1893 const fs_builder &bld = v->bld;
1894 fs_reg dest0 = v->vgrf(glsl_type::uint_type);
1895 fs_reg dest1 = v->vgrf(glsl_type::float_type);
1896 fs_reg src0 = v->vgrf(glsl_type::uint_type);
1897 fs_reg src1 = v->vgrf(glsl_type::uint_type);
1898 fs_reg src2 = v->vgrf(glsl_type::float_type);
1899 fs_reg zero(brw_imm_f(0.0f));
1900 set_condmod(BRW_CONDITIONAL_Z, bld.OR(dest0, src0, src1));
1901 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
1902 set_condmod(BRW_CONDITIONAL_NZ, bld.NOT(bld.null_reg_ud(), dest0));
1903
1904 /* = Before =
1905 *
1906 * 0: or.z.f0(8) dest0 src0 src1
1907 * 1: (+f0) sel(8) dest1 src2 0.0f
1908 * 2: not.nz.f0(8) null dest0
1909 *
1910 * = After =
1911 * 0: or.z.f0(8) dest0 src0 src1
1912 * 1: (+f0) sel(8) dest1 src2 0.0f
1913 */
1914
1915 v->calculate_cfg();
1916 bblock_t *block0 = v->cfg->blocks[0];
1917
1918 EXPECT_EQ(0, block0->start_ip);
1919 EXPECT_EQ(2, block0->end_ip);
1920
1921 EXPECT_TRUE(cmod_propagation(v));
1922 EXPECT_EQ(0, block0->start_ip);
1923 EXPECT_EQ(1, block0->end_ip);
1924 EXPECT_EQ(BRW_OPCODE_OR, instruction(block0, 0)->opcode);
1925 EXPECT_EQ(BRW_CONDITIONAL_Z, instruction(block0, 0)->conditional_mod);
1926 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
1927 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
1928 }
1929
1930 TEST_F(cmod_propagation_test,
1931 not_to_or_intervening_flag_read_compatible_value_mismatch_flag)
1932 {
1933 /* Exercise propagation of conditional modifier from a NOT instruction to
1934 * another ALU instruction as performed by cmod_propagate_not.
1935 */
1936 const fs_builder &bld = v->bld;
1937 fs_reg dest0 = v->vgrf(glsl_type::uint_type);
1938 fs_reg dest1 = v->vgrf(glsl_type::float_type);
1939 fs_reg src0 = v->vgrf(glsl_type::uint_type);
1940 fs_reg src1 = v->vgrf(glsl_type::uint_type);
1941 fs_reg src2 = v->vgrf(glsl_type::float_type);
1942 fs_reg zero(brw_imm_f(0.0f));
1943 set_condmod(BRW_CONDITIONAL_Z, bld.OR(dest0, src0, src1))
1944 ->flag_subreg = 1;
1945 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
1946 set_condmod(BRW_CONDITIONAL_NZ, bld.NOT(bld.null_reg_ud(), dest0));
1947
1948 /* = Before =
1949 *
1950 * 0: or.z.f0.1(8) dest0 src0 src1
1951 * 1: (+f0) sel(8) dest1 src2 0.0f
1952 * 2: not.nz.f0(8) null dest0
1953 *
1954 * = After =
1955 * No changes
1956 */
1957
1958 v->calculate_cfg();
1959 bblock_t *block0 = v->cfg->blocks[0];
1960
1961 EXPECT_EQ(0, block0->start_ip);
1962 EXPECT_EQ(2, block0->end_ip);
1963
1964 EXPECT_FALSE(cmod_propagation(v));
1965 EXPECT_EQ(0, block0->start_ip);
1966 EXPECT_EQ(2, block0->end_ip);
1967 EXPECT_EQ(BRW_OPCODE_OR, instruction(block0, 0)->opcode);
1968 EXPECT_EQ(BRW_CONDITIONAL_Z, instruction(block0, 0)->conditional_mod);
1969 EXPECT_EQ(1, instruction(block0, 0)->flag_subreg);
1970 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
1971 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
1972 EXPECT_EQ(BRW_OPCODE_NOT, instruction(block0, 2)->opcode);
1973 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 2)->conditional_mod);
1974 EXPECT_EQ(0, instruction(block0, 2)->flag_subreg);
1975 }
1976
1977 TEST_F(cmod_propagation_test, not_to_or_intervening_flag_read_incompatible_value)
1978 {
1979 /* Exercise propagation of conditional modifier from a NOT instruction to
1980 * another ALU instruction as performed by cmod_propagate_not.
1981 */
1982 const fs_builder &bld = v->bld;
1983 fs_reg dest0 = v->vgrf(glsl_type::uint_type);
1984 fs_reg dest1 = v->vgrf(glsl_type::float_type);
1985 fs_reg src0 = v->vgrf(glsl_type::uint_type);
1986 fs_reg src1 = v->vgrf(glsl_type::uint_type);
1987 fs_reg src2 = v->vgrf(glsl_type::float_type);
1988 fs_reg zero(brw_imm_f(0.0f));
1989 set_condmod(BRW_CONDITIONAL_NZ, bld.OR(dest0, src0, src1));
1990 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
1991 set_condmod(BRW_CONDITIONAL_NZ, bld.NOT(bld.null_reg_ud(), dest0));
1992
1993 /* = Before =
1994 *
1995 * 0: or.nz.f0(8) dest0 src0 src1
1996 * 1: (+f0) sel(8) dest1 src2 0.0f
1997 * 2: not.nz.f0(8) null dest0
1998 *
1999 * = After =
2000 * No changes
2001 */
2002
2003 v->calculate_cfg();
2004 bblock_t *block0 = v->cfg->blocks[0];
2005
2006 EXPECT_EQ(0, block0->start_ip);
2007 EXPECT_EQ(2, block0->end_ip);
2008
2009 EXPECT_FALSE(cmod_propagation(v));
2010 EXPECT_EQ(0, block0->start_ip);
2011 EXPECT_EQ(2, block0->end_ip);
2012 EXPECT_EQ(BRW_OPCODE_OR, instruction(block0, 0)->opcode);
2013 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 0)->conditional_mod);
2014 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
2015 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
2016 EXPECT_EQ(BRW_OPCODE_NOT, instruction(block0, 2)->opcode);
2017 EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 2)->conditional_mod);
2018 }
2019
2020 TEST_F(cmod_propagation_test, not_to_or_intervening_mismatch_flag_write)
2021 {
2022 /* Exercise propagation of conditional modifier from a NOT instruction to
2023 * another ALU instruction as performed by cmod_propagate_not.
2024 */
2025 const fs_builder &bld = v->bld;
2026 fs_reg dest0 = v->vgrf(glsl_type::uint_type);
2027 fs_reg dest1 = v->vgrf(glsl_type::uint_type);
2028 fs_reg src0 = v->vgrf(glsl_type::uint_type);
2029 fs_reg src1 = v->vgrf(glsl_type::uint_type);
2030
2031 bld.OR(dest0, src0, src1);
2032 set_condmod(BRW_CONDITIONAL_Z, bld.OR(dest1, src0, src1))
2033 ->flag_subreg = 1;
2034 set_condmod(BRW_CONDITIONAL_NZ, bld.NOT(bld.null_reg_ud(), dest0));
2035
2036 /* = Before =
2037 *
2038 * 0: or(8) dest0 src0 src1
2039 * 1: or.z.f0.1(8) dest1 src0 src1
2040 * 2: not.nz.f0(8) null dest0
2041 *
2042 * = After =
2043 * 0: or.z.f0(8) dest0 src0 src1
2044 * 1: or.z.f0.1(8) dest1 src0 src1
2045 */
2046
2047 v->calculate_cfg();
2048 bblock_t *block0 = v->cfg->blocks[0];
2049
2050 EXPECT_EQ(0, block0->start_ip);
2051 EXPECT_EQ(2, block0->end_ip);
2052
2053 EXPECT_TRUE(cmod_propagation(v));
2054 EXPECT_EQ(0, block0->start_ip);
2055 EXPECT_EQ(1, block0->end_ip);
2056 EXPECT_EQ(BRW_OPCODE_OR, instruction(block0, 0)->opcode);
2057 EXPECT_EQ(BRW_CONDITIONAL_Z, instruction(block0, 0)->conditional_mod);
2058 EXPECT_EQ(0, instruction(block0, 0)->flag_subreg);
2059 EXPECT_EQ(BRW_OPCODE_OR, instruction(block0, 1)->opcode);
2060 EXPECT_EQ(BRW_CONDITIONAL_Z, instruction(block0, 1)->conditional_mod);
2061 EXPECT_EQ(1, instruction(block0, 1)->flag_subreg);
2062 }
2063
2064 TEST_F(cmod_propagation_test, not_to_or_intervening_mismatch_flag_read)
2065 {
2066 /* Exercise propagation of conditional modifier from a NOT instruction to
2067 * another ALU instruction as performed by cmod_propagate_not.
2068 */
2069 const fs_builder &bld = v->bld;
2070 fs_reg dest0 = v->vgrf(glsl_type::uint_type);
2071 fs_reg dest1 = v->vgrf(glsl_type::float_type);
2072 fs_reg src0 = v->vgrf(glsl_type::uint_type);
2073 fs_reg src1 = v->vgrf(glsl_type::uint_type);
2074 fs_reg src2 = v->vgrf(glsl_type::float_type);
2075 fs_reg zero(brw_imm_f(0.0f));
2076
2077 bld.OR(dest0, src0, src1);
2078 set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero))
2079 ->flag_subreg = 1;
2080 set_condmod(BRW_CONDITIONAL_NZ, bld.NOT(bld.null_reg_ud(), dest0));
2081
2082 /* = Before =
2083 *
2084 * 0: or(8) dest0 src0 src1
2085 * 1: (+f0.1) sel(8) dest1 src2 0.0f
2086 * 2: not.nz.f0(8) null dest0
2087 *
2088 * = After =
2089 * 0: or.z.f0(8) dest0 src0 src1
2090 * 1: (+f0.1) sel(8) dest1 src2 0.0f
2091 */
2092
2093 v->calculate_cfg();
2094 bblock_t *block0 = v->cfg->blocks[0];
2095
2096 EXPECT_EQ(0, block0->start_ip);
2097 EXPECT_EQ(2, block0->end_ip);
2098
2099 EXPECT_TRUE(cmod_propagation(v));
2100 EXPECT_EQ(0, block0->start_ip);
2101 EXPECT_EQ(1, block0->end_ip);
2102 EXPECT_EQ(BRW_OPCODE_OR, instruction(block0, 0)->opcode);
2103 EXPECT_EQ(BRW_CONDITIONAL_Z, instruction(block0, 0)->conditional_mod);
2104 EXPECT_EQ(0, instruction(block0, 0)->flag_subreg);
2105 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
2106 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
2107 EXPECT_EQ(1, instruction(block0, 1)->flag_subreg);
2108 }