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