1 /*
2  * Copyright © 2015 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Based on test_fs_cmod_propagation.cpp
24  */
25 
26 #include <gtest/gtest.h>
27 #include "brw_vec4.h"
28 #include "brw_vec4_builder.h"
29 #include "brw_cfg.h"
30 #include "program/program.h"
31 
32 using namespace brw;
33 
34 class cmod_propagation_test : public ::testing::Test {
35    virtual void SetUp();
36    virtual void TearDown();
37 
38 public:
39    struct brw_compiler *compiler;
40    struct intel_device_info *devinfo;
41    void *ctx;
42    struct gl_shader_program *shader_prog;
43    struct brw_vue_prog_data *prog_data;
44    vec4_visitor *v;
45 };
46 
47 class cmod_propagation_vec4_visitor : public vec4_visitor
48 {
49 public:
cmod_propagation_vec4_visitor(struct brw_compiler * compiler,void * mem_ctx,nir_shader * shader,struct brw_vue_prog_data * prog_data)50    cmod_propagation_vec4_visitor(struct brw_compiler *compiler,
51                                  void *mem_ctx,
52                                  nir_shader *shader,
53                                  struct brw_vue_prog_data *prog_data)
54       : vec4_visitor(compiler, NULL, NULL, prog_data, shader, mem_ctx,
55                      false, -1, false)
56       {
57          prog_data->dispatch_mode = DISPATCH_MODE_4X2_DUAL_OBJECT;
58       }
59 
60 protected:
61    /* Dummy implementation for pure virtual methods */
make_reg_for_system_value(int)62    virtual dst_reg *make_reg_for_system_value(int /* location */)
63    {
64       unreachable("Not reached");
65    }
66 
setup_payload()67    virtual void setup_payload()
68    {
69       unreachable("Not reached");
70    }
71 
emit_prolog()72    virtual void emit_prolog()
73    {
74       unreachable("Not reached");
75    }
76 
emit_program_code()77    virtual void emit_program_code()
78    {
79       unreachable("Not reached");
80    }
81 
emit_thread_end()82    virtual void emit_thread_end()
83    {
84       unreachable("Not reached");
85    }
86 
emit_urb_write_header(int)87    virtual void emit_urb_write_header(int /* mrf */)
88    {
89       unreachable("Not reached");
90    }
91 
emit_urb_write_opcode(bool)92    virtual vec4_instruction *emit_urb_write_opcode(bool /* complete */)
93    {
94       unreachable("Not reached");
95    }
96 };
97 
98 
SetUp()99 void cmod_propagation_test::SetUp()
100 {
101    ctx = ralloc_context(NULL);
102    compiler = rzalloc(ctx, struct brw_compiler);
103    devinfo = rzalloc(ctx, struct intel_device_info);
104    compiler->devinfo = devinfo;
105 
106    prog_data = ralloc(ctx, struct brw_vue_prog_data);
107    nir_shader *shader =
108       nir_shader_create(ctx, MESA_SHADER_VERTEX, NULL, NULL);
109 
110    v = new cmod_propagation_vec4_visitor(compiler, ctx, shader, prog_data);
111 
112    devinfo->ver = 7;
113    devinfo->verx10 = devinfo->ver * 10;
114 }
115 
TearDown()116 void cmod_propagation_test::TearDown()
117 {
118    delete v;
119    v = NULL;
120 
121    ralloc_free(ctx);
122    ctx = NULL;
123 }
124 
125 static vec4_instruction *
instruction(bblock_t * block,int num)126 instruction(bblock_t *block, int num)
127 {
128    vec4_instruction *inst = (vec4_instruction *)block->start();
129    for (int i = 0; i < num; i++) {
130       inst = (vec4_instruction *)inst->next;
131    }
132    return inst;
133 }
134 
135 static bool
cmod_propagation(vec4_visitor * v)136 cmod_propagation(vec4_visitor *v)
137 {
138    const bool print = getenv("TEST_DEBUG");
139 
140    if (print) {
141       fprintf(stderr, "= Before =\n");
142       v->dump_instructions();
143    }
144 
145    bool ret = v->opt_cmod_propagation();
146 
147    if (print) {
148       fprintf(stderr, "\n= After =\n");
149       v->dump_instructions();
150    }
151 
152    return ret;
153 }
154 
TEST_F(cmod_propagation_test,basic)155 TEST_F(cmod_propagation_test, basic)
156 {
157    const vec4_builder bld = vec4_builder(v).at_end();
158    dst_reg dest = dst_reg(v, glsl_type::float_type);
159    src_reg src0 = src_reg(v, glsl_type::float_type);
160    src_reg src1 = src_reg(v, glsl_type::float_type);
161    src_reg zero(brw_imm_f(0.0f));
162    dst_reg dest_null = bld.null_reg_f();
163    dest_null.writemask = WRITEMASK_X;
164 
165    bld.ADD(dest, src0, src1);
166    bld.CMP(dest_null, src_reg(dest), zero, BRW_CONDITIONAL_GE);
167 
168    /* = Before =
169     *
170     * 0: add        dest.x  src0.xxxx  src1.xxxx
171     * 1: cmp.ge.f0  null.x  dest.xxxx  0.0f
172     *
173     * = After =
174     * 0: add.ge.f0  dest.x  src0.xxxx  src1.xxxx
175     */
176 
177    v->calculate_cfg();
178    bblock_t *block0 = v->cfg->blocks[0];
179 
180    EXPECT_EQ(0, block0->start_ip);
181    EXPECT_EQ(1, block0->end_ip);
182 
183    EXPECT_TRUE(cmod_propagation(v));
184 
185    ASSERT_EQ(0, block0->start_ip);
186    ASSERT_EQ(0, block0->end_ip);
187    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
188    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
189 }
190 
TEST_F(cmod_propagation_test,basic_different_dst_writemask)191 TEST_F(cmod_propagation_test, basic_different_dst_writemask)
192 {
193    const vec4_builder bld = vec4_builder(v).at_end();
194    dst_reg dest = dst_reg(v, glsl_type::float_type);
195    src_reg src0 = src_reg(v, glsl_type::float_type);
196    src_reg src1 = src_reg(v, glsl_type::float_type);
197    src_reg zero(brw_imm_f(0.0f));
198    dst_reg dest_null = bld.null_reg_f();
199 
200    bld.ADD(dest, src0, src1);
201    bld.CMP(dest_null, src_reg(dest), zero, BRW_CONDITIONAL_GE);
202 
203    /* = Before =
204     *
205     * 0: add        dest.x     src0  src1
206     * 1: cmp.ge.f0  null.xyzw  dest  0.0f
207     *
208     * = After =
209     * (no changes)
210     */
211 
212    v->calculate_cfg();
213    bblock_t *block0 = v->cfg->blocks[0];
214 
215    EXPECT_EQ(0, block0->start_ip);
216    EXPECT_EQ(1, block0->end_ip);
217 
218    EXPECT_FALSE(cmod_propagation(v));
219 
220    ASSERT_EQ(0, block0->start_ip);
221    ASSERT_EQ(1, block0->end_ip);
222    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
223    EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
224    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
225    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
226 }
227 
TEST_F(cmod_propagation_test,andz_one)228 TEST_F(cmod_propagation_test, andz_one)
229 {
230    const vec4_builder bld = vec4_builder(v).at_end();
231    dst_reg dest = dst_reg(v, glsl_type::int_type);
232    src_reg src0 = src_reg(v, glsl_type::float_type);
233    src_reg zero(brw_imm_f(0.0f));
234    src_reg one(brw_imm_d(1));
235 
236    bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
237    set_condmod(BRW_CONDITIONAL_Z,
238                bld.AND(bld.null_reg_d(), src_reg(dest), one));
239 
240    /* = Before =
241     * 0: cmp.l.f0     dest:F  src0:F  0F
242     * 1: and.z.f0     null:D  dest:D  1D
243     *
244     * = After =
245     * (no changes)
246     */
247 
248    v->calculate_cfg();
249    bblock_t *block0 = v->cfg->blocks[0];
250 
251    EXPECT_EQ(0, block0->start_ip);
252    EXPECT_EQ(1, block0->end_ip);
253 
254    EXPECT_FALSE(cmod_propagation(v));
255 
256    ASSERT_EQ(0, block0->start_ip);
257    ASSERT_EQ(1, block0->end_ip);
258    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
259    EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
260    EXPECT_EQ(BRW_OPCODE_AND, instruction(block0, 1)->opcode);
261    EXPECT_EQ(BRW_CONDITIONAL_EQ, instruction(block0, 1)->conditional_mod);
262 }
263 
TEST_F(cmod_propagation_test,non_cmod_instruction)264 TEST_F(cmod_propagation_test, non_cmod_instruction)
265 {
266    const vec4_builder bld = vec4_builder(v).at_end();
267    dst_reg dest = dst_reg(v, glsl_type::uint_type);
268    src_reg src0 = src_reg(v, glsl_type::uint_type);
269    src_reg zero(brw_imm_ud(0u));
270    bld.FBL(dest, src0);
271    bld.CMP(bld.null_reg_ud(), src_reg(dest), zero, BRW_CONDITIONAL_GE);
272 
273    /* = Before =
274     *
275     * 0: fbl        dest  src0
276     * 1: cmp.ge.f0  null  dest  0u
277     *
278     * = After =
279     * (no changes)
280     */
281 
282    v->calculate_cfg();
283    bblock_t *block0 = v->cfg->blocks[0];
284 
285    EXPECT_EQ(0, block0->start_ip);
286    EXPECT_EQ(1, block0->end_ip);
287 
288    EXPECT_FALSE(cmod_propagation(v));
289 
290    ASSERT_EQ(0, block0->start_ip);
291    ASSERT_EQ(1, block0->end_ip);
292    EXPECT_EQ(BRW_OPCODE_FBL, instruction(block0, 0)->opcode);
293    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
294    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
295 }
296 
TEST_F(cmod_propagation_test,intervening_flag_write)297 TEST_F(cmod_propagation_test, intervening_flag_write)
298 {
299    const vec4_builder bld = vec4_builder(v).at_end();
300    dst_reg dest = dst_reg(v, glsl_type::float_type);
301    src_reg src0 = src_reg(v, glsl_type::float_type);
302    src_reg src1 = src_reg(v, glsl_type::float_type);
303    src_reg src2 = src_reg(v, glsl_type::float_type);
304    src_reg zero(brw_imm_f(0.0f));
305    bld.ADD(dest, src0, src1);
306    bld.CMP(bld.null_reg_f(), src2, zero, BRW_CONDITIONAL_GE);
307    bld.CMP(bld.null_reg_f(), src_reg(dest), zero, BRW_CONDITIONAL_GE);
308 
309    /* = Before =
310     *
311     * 0: add        dest  src0  src1
312     * 1: cmp.ge.f0  null  src2  0.0f
313     * 2: cmp.ge.f0  null  dest  0.0f
314     *
315     * = After =
316     * (no changes)
317     */
318 
319    v->calculate_cfg();
320    bblock_t *block0 = v->cfg->blocks[0];
321 
322    EXPECT_EQ(0, block0->start_ip);
323    EXPECT_EQ(2, block0->end_ip);
324 
325    EXPECT_FALSE(cmod_propagation(v));
326 
327    ASSERT_EQ(0, block0->start_ip);
328    ASSERT_EQ(2, block0->end_ip);
329    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
330    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
331    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
332    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
333    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
334 }
335 
TEST_F(cmod_propagation_test,intervening_flag_read)336 TEST_F(cmod_propagation_test, intervening_flag_read)
337 {
338    const vec4_builder bld = vec4_builder(v).at_end();
339    dst_reg dest0 = dst_reg(v, glsl_type::float_type);
340    dst_reg dest1 = dst_reg(v, glsl_type::float_type);
341    src_reg src0 = src_reg(v, glsl_type::float_type);
342    src_reg src1 = src_reg(v, glsl_type::float_type);
343    src_reg src2 = src_reg(v, glsl_type::float_type);
344    src_reg zero(brw_imm_f(0.0f));
345    bld.ADD(dest0, src0, src1);
346    set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
347    bld.CMP(bld.null_reg_f(), src_reg(dest0), zero, BRW_CONDITIONAL_GE);
348 
349    /* = Before =
350     *
351     * 0: add        dest0 src0  src1
352     * 1: (+f0) sel  dest1 src2  0.0f
353     * 2: cmp.ge.f0  null  dest0 0.0f
354     *
355     * = After =
356     * (no changes)
357     */
358 
359    v->calculate_cfg();
360    bblock_t *block0 = v->cfg->blocks[0];
361 
362    EXPECT_EQ(0, block0->start_ip);
363    EXPECT_EQ(2, block0->end_ip);
364 
365    EXPECT_FALSE(cmod_propagation(v));
366 
367    ASSERT_EQ(0, block0->start_ip);
368    ASSERT_EQ(2, block0->end_ip);
369    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
370    EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
371    EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
372    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
373    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
374 }
375 
TEST_F(cmod_propagation_test,intervening_dest_write)376 TEST_F(cmod_propagation_test, intervening_dest_write)
377 {
378    const vec4_builder bld = vec4_builder(v).at_end();
379    dst_reg dest = dst_reg(v, glsl_type::vec4_type);
380    src_reg src0 = src_reg(v, glsl_type::float_type);
381    src_reg src1 = src_reg(v, glsl_type::float_type);
382    src_reg src2 = src_reg(v, glsl_type::vec2_type);
383    src_reg zero(brw_imm_f(0.0f));
384    bld.ADD(offset(dest, 8, 2), src0, src1);
385    bld.emit(SHADER_OPCODE_TEX, dest, src2)
386       ->size_written = 4 * REG_SIZE;
387    bld.CMP(bld.null_reg_f(), offset(src_reg(dest), 8, 2), zero, BRW_CONDITIONAL_GE);
388 
389    /* = Before =
390     *
391     * 0: add        dest+2  src0    src1
392     * 1: tex rlen 4 dest+0  src2
393     * 2: cmp.ge.f0  null    dest+2  0.0f
394     *
395     * = After =
396     * (no changes)
397     */
398 
399    v->calculate_cfg();
400    bblock_t *block0 = v->cfg->blocks[0];
401 
402    EXPECT_EQ(0, block0->start_ip);
403    EXPECT_EQ(2, block0->end_ip);
404 
405    EXPECT_FALSE(cmod_propagation(v));
406 
407    ASSERT_EQ(0, block0->start_ip);
408    ASSERT_EQ(2, block0->end_ip);
409    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
410    EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
411    EXPECT_EQ(SHADER_OPCODE_TEX, instruction(block0, 1)->opcode);
412    EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
413    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
414    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
415 }
416 
TEST_F(cmod_propagation_test,intervening_flag_read_same_value)417 TEST_F(cmod_propagation_test, intervening_flag_read_same_value)
418 {
419    const vec4_builder bld = vec4_builder(v).at_end();
420    dst_reg dest0 = dst_reg(v, glsl_type::float_type);
421    dst_reg dest1 = dst_reg(v, glsl_type::float_type);
422    src_reg src0 = src_reg(v, glsl_type::float_type);
423    src_reg src1 = src_reg(v, glsl_type::float_type);
424    src_reg src2 = src_reg(v, glsl_type::float_type);
425    src_reg zero(brw_imm_f(0.0f));
426    dst_reg dest_null = bld.null_reg_f();
427    dest_null.writemask = WRITEMASK_X;
428 
429    set_condmod(BRW_CONDITIONAL_GE, bld.ADD(dest0, src0, src1));
430    set_predicate(BRW_PREDICATE_NORMAL, bld.SEL(dest1, src2, zero));
431    bld.CMP(dest_null, src_reg(dest0), zero, BRW_CONDITIONAL_GE);
432 
433    /* = Before =
434     *
435     * 0: add.ge.f0  dest0   src0  src1
436     * 1: (+f0) sel  dest1   src2  0.0f
437     * 2: cmp.ge.f0  null.x  dest0 0.0f
438     *
439     * = After =
440     * 0: add.ge.f0  dest0 src0  src1
441     * 1: (+f0) sel  dest1 src2  0.0f
442     */
443 
444    v->calculate_cfg();
445    bblock_t *block0 = v->cfg->blocks[0];
446 
447    EXPECT_EQ(0, block0->start_ip);
448    EXPECT_EQ(2, block0->end_ip);
449 
450    EXPECT_TRUE(cmod_propagation(v));
451    ASSERT_EQ(0, block0->start_ip);
452    ASSERT_EQ(1, block0->end_ip);
453    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
454    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
455    EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
456    EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
457 }
458 
TEST_F(cmod_propagation_test,negate)459 TEST_F(cmod_propagation_test, negate)
460 {
461    const vec4_builder bld = vec4_builder(v).at_end();
462    dst_reg dest = dst_reg(v, glsl_type::float_type);
463    src_reg src0 = src_reg(v, glsl_type::float_type);
464    src_reg src1 = src_reg(v, glsl_type::float_type);
465    src_reg zero(brw_imm_f(0.0f));
466    bld.ADD(dest, src0, src1);
467    src_reg tmp_src = src_reg(dest);
468    tmp_src.negate = true;
469    dst_reg dest_null = bld.null_reg_f();
470    dest_null.writemask = WRITEMASK_X;
471    bld.CMP(dest_null, tmp_src, zero, BRW_CONDITIONAL_GE);
472 
473    /* = Before =
474     *
475     * 0: add        dest     src0  src1
476     * 1: cmp.ge.f0  null.x  -dest 0.0f
477     *
478     * = After =
479     * 0: add.le.f0  dest     src0  src1
480     */
481 
482    v->calculate_cfg();
483    bblock_t *block0 = v->cfg->blocks[0];
484 
485    EXPECT_EQ(0, block0->start_ip);
486    EXPECT_EQ(1, block0->end_ip);
487 
488    EXPECT_TRUE(cmod_propagation(v));
489    EXPECT_EQ(0, block0->start_ip);
490    EXPECT_EQ(0, block0->end_ip);
491    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
492    EXPECT_EQ(BRW_CONDITIONAL_LE, instruction(block0, 0)->conditional_mod);
493 }
494 
TEST_F(cmod_propagation_test,movnz)495 TEST_F(cmod_propagation_test, movnz)
496 {
497    const vec4_builder bld = vec4_builder(v).at_end();
498    dst_reg dest = dst_reg(v, glsl_type::float_type);
499    src_reg src0 = src_reg(v, glsl_type::float_type);
500    src_reg src1 = src_reg(v, glsl_type::float_type);
501    dst_reg dest_null = bld.null_reg_f();
502    dest_null.writemask = WRITEMASK_X;
503 
504    bld.CMP(dest, src0, src1, BRW_CONDITIONAL_L);
505    set_condmod(BRW_CONDITIONAL_NZ,
506                bld.MOV(dest_null, src_reg(dest)));
507 
508    /* = Before =
509     *
510     * 0: cmp.l.f0  dest:F  src0:F  src1:F
511     * 1: mov.nz.f0 null.x  dest:F
512     *
513     * = After =
514     * 0: cmp.l.f0  dest  src0:F  src1:F
515     */
516 
517    v->calculate_cfg();
518    bblock_t *block0 = v->cfg->blocks[0];
519 
520    EXPECT_EQ(0, block0->start_ip);
521    EXPECT_EQ(1, block0->end_ip);
522 
523    EXPECT_TRUE(cmod_propagation(v));
524 
525    ASSERT_EQ(0, block0->start_ip);
526    ASSERT_EQ(0, block0->end_ip);
527    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
528    EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
529 }
530 
TEST_F(cmod_propagation_test,different_types_cmod_with_zero)531 TEST_F(cmod_propagation_test, different_types_cmod_with_zero)
532 {
533    const vec4_builder bld = vec4_builder(v).at_end();
534    dst_reg dest = dst_reg(v, glsl_type::int_type);
535    src_reg src0 = src_reg(v, glsl_type::int_type);
536    src_reg src1 = src_reg(v, glsl_type::int_type);
537    src_reg zero(brw_imm_f(0.0f));
538    bld.ADD(dest, src0, src1);
539    bld.CMP(bld.null_reg_f(), retype(src_reg(dest), BRW_REGISTER_TYPE_F), zero,
540            BRW_CONDITIONAL_GE);
541 
542    /* = Before =
543     *
544     * 0: add        dest:D  src0:D  src1:D
545     * 1: cmp.ge.f0  null:F  dest:F  0.0f
546     *
547     * = After =
548     * (no changes)
549     */
550 
551    v->calculate_cfg();
552    bblock_t *block0 = v->cfg->blocks[0];
553 
554    EXPECT_EQ(0, block0->start_ip);
555    EXPECT_EQ(1, block0->end_ip);
556 
557    EXPECT_FALSE(cmod_propagation(v));
558 
559    ASSERT_EQ(0, block0->start_ip);
560    ASSERT_EQ(1, block0->end_ip);
561    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
562    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
563    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
564 }
565 
TEST_F(cmod_propagation_test,andnz_non_one)566 TEST_F(cmod_propagation_test, andnz_non_one)
567 {
568    const vec4_builder bld = vec4_builder(v).at_end();
569    dst_reg dest = dst_reg(v, glsl_type::int_type);
570    src_reg src0 = src_reg(v, glsl_type::float_type);
571    src_reg zero(brw_imm_f(0.0f));
572    src_reg nonone(brw_imm_d(38));
573 
574    bld.CMP(retype(dest, BRW_REGISTER_TYPE_F), src0, zero, BRW_CONDITIONAL_L);
575    set_condmod(BRW_CONDITIONAL_NZ,
576                bld.AND(bld.null_reg_d(), src_reg(dest), nonone));
577 
578    /* = Before =
579     * 0: cmp.l.f0     dest:F  src0:F  0F
580     * 1: and.nz.f0    null:D  dest:D  38D
581     *
582     * = After =
583     * (no changes)
584     */
585 
586    v->calculate_cfg();
587    bblock_t *block0 = v->cfg->blocks[0];
588 
589    EXPECT_EQ(0, block0->start_ip);
590    EXPECT_EQ(1, block0->end_ip);
591 
592    EXPECT_FALSE(cmod_propagation(v));
593 
594    ASSERT_EQ(0, block0->start_ip);
595    ASSERT_EQ(1, block0->end_ip);
596    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
597    EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
598    EXPECT_EQ(BRW_OPCODE_AND, instruction(block0, 1)->opcode);
599    EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
600 }
601 
602 /* Note that basic is using glsl_type:float types, while this one is using
603  * glsl_type::vec4 */
TEST_F(cmod_propagation_test,basic_vec4)604 TEST_F(cmod_propagation_test, basic_vec4)
605 {
606    const vec4_builder bld = vec4_builder(v).at_end();
607    dst_reg dest = dst_reg(v, glsl_type::vec4_type);
608    src_reg src0 = src_reg(v, glsl_type::vec4_type);
609    src_reg src1 = src_reg(v, glsl_type::vec4_type);
610    src_reg zero(brw_imm_f(0.0f));
611 
612    bld.MUL(dest, src0, src1);
613    bld.CMP(bld.null_reg_f(), src_reg(dest), zero, BRW_CONDITIONAL_NZ);
614 
615    /* = Before =
616     * 0: mul         dest.xyzw  src0.xyzw  src1.xyzw
617     * 1: cmp.nz.f0.0 null.xyzw  dest.xyzw  0.0f
618     *
619     * = After =
620     * 0: mul.nz.f0.0 dest.xyzw  src0.xyzw  src1.xyzw
621     */
622 
623    v->calculate_cfg();
624    bblock_t *block0 = v->cfg->blocks[0];
625 
626    EXPECT_EQ(0, block0->start_ip);
627    EXPECT_EQ(1, block0->end_ip);
628 
629    EXPECT_TRUE(cmod_propagation(v));
630 
631    ASSERT_EQ(0, block0->start_ip);
632    ASSERT_EQ(0, block0->end_ip);
633    EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
634    EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 0)->conditional_mod);
635 }
636 
TEST_F(cmod_propagation_test,basic_vec4_different_dst_writemask)637 TEST_F(cmod_propagation_test, basic_vec4_different_dst_writemask)
638 {
639    const vec4_builder bld = vec4_builder(v).at_end();
640    dst_reg dest = dst_reg(v, glsl_type::vec4_type);
641    dest.writemask = WRITEMASK_X;
642    src_reg src0 = src_reg(v, glsl_type::vec4_type);
643    src_reg src1 = src_reg(v, glsl_type::vec4_type);
644    src_reg zero(brw_imm_f(0.0f));
645    dst_reg dest_null = bld.null_reg_f();
646 
647    bld.MUL(dest, src0, src1);
648    bld.CMP(dest_null, src_reg(dest), zero, BRW_CONDITIONAL_NZ);
649 
650    /* = Before =
651     * 0: mul         dest.x  src0  src1
652     * 1: cmp.nz.f0.0 null    dest  0.0f
653     *
654     * = After =
655     * (no changes)
656     */
657 
658    v->calculate_cfg();
659    bblock_t *block0 = v->cfg->blocks[0];
660 
661    EXPECT_EQ(0, block0->start_ip);
662    EXPECT_EQ(1, block0->end_ip);
663 
664    EXPECT_FALSE(cmod_propagation(v));
665 
666    ASSERT_EQ(0, block0->start_ip);
667    ASSERT_EQ(1, block0->end_ip);
668    EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
669    EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
670    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
671    EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
672 }
673 
TEST_F(cmod_propagation_test,mad_one_component_vec4)674 TEST_F(cmod_propagation_test, mad_one_component_vec4)
675 {
676    const vec4_builder bld = vec4_builder(v).at_end();
677    dst_reg dest = dst_reg(v, glsl_type::vec4_type);
678    dest.writemask = WRITEMASK_X;
679    src_reg src0 = src_reg(v, glsl_type::vec4_type);
680    src_reg src1 = src_reg(v, glsl_type::vec4_type);
681    src_reg src2 = src_reg(v, glsl_type::vec4_type);
682    src0.swizzle = src1.swizzle = src2.swizzle = BRW_SWIZZLE_XXXX;
683    src2.negate = true;
684    src_reg zero(brw_imm_f(0.0f));
685    src_reg tmp(dest);
686    tmp.swizzle = BRW_SWIZZLE_XXXX;
687    dst_reg dest_null = bld.null_reg_f();
688    dest_null.writemask = WRITEMASK_X;
689 
690    bld.MAD(dest, src0, src1, src2);
691    bld.CMP(dest_null, tmp, zero, BRW_CONDITIONAL_L);
692 
693    /* = Before =
694     *
695     * 0: mad         dest.x:F  src0.xxxx:F  src10.xxxx:F  -src2.xxxx:F
696     * 1: cmp.l.f0.0  null.x:F  dest.xxxx:F  0.0f
697     *
698     * = After =
699     * 0: mad.l.f0    dest.x:F  src0.xxxx:F  src10.xxxx:F  -src2.xxxx:F
700     */
701 
702    v->calculate_cfg();
703    bblock_t *block0 = v->cfg->blocks[0];
704 
705    EXPECT_EQ(0, block0->start_ip);
706    EXPECT_EQ(1, block0->end_ip);
707 
708    EXPECT_TRUE(cmod_propagation(v));
709 
710    ASSERT_EQ(0, block0->start_ip);
711    ASSERT_EQ(0, block0->end_ip);
712    EXPECT_EQ(BRW_OPCODE_MAD, instruction(block0, 0)->opcode);
713    EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 0)->conditional_mod);
714 }
715 
TEST_F(cmod_propagation_test,mad_more_one_component_vec4)716 TEST_F(cmod_propagation_test, mad_more_one_component_vec4)
717 {
718    const vec4_builder bld = vec4_builder(v).at_end();
719    dst_reg dest = dst_reg(v, glsl_type::vec4_type);
720    dest.writemask = WRITEMASK_XW;
721    src_reg src0 = src_reg(v, glsl_type::vec4_type);
722    src_reg src1 = src_reg(v, glsl_type::vec4_type);
723    src_reg src2 = src_reg(v, glsl_type::vec4_type);
724    src0.swizzle = src1.swizzle = src2.swizzle = BRW_SWIZZLE_XXXX;
725    src2.negate = true;
726    src_reg zero(brw_imm_f(0.0f));
727    src_reg tmp(dest);
728    tmp.swizzle = BRW_SWIZZLE_XXXX;
729    dst_reg dest_null = bld.null_reg_f();
730 
731    bld.MAD(dest, src0, src1, src2);
732    bld.CMP(dest_null, tmp, zero, BRW_CONDITIONAL_L);
733 
734    /* = Before =
735     *
736     * 0: mad         dest.xw:F  src0.xxxx:F  src10.xxxx:F  -src2.xxxx:F
737     * 1: cmp.l.f0.0  null:F  dest.xxxx:F  zeroF
738     *
739     * = After =
740     * (No changes)
741     */
742 
743    v->calculate_cfg();
744    bblock_t *block0 = v->cfg->blocks[0];
745 
746    EXPECT_EQ(0, block0->start_ip);
747    EXPECT_EQ(1, block0->end_ip);
748 
749    EXPECT_FALSE(cmod_propagation(v));
750 
751    ASSERT_EQ(0, block0->start_ip);
752    ASSERT_EQ(1, block0->end_ip);
753    EXPECT_EQ(BRW_OPCODE_MAD, instruction(block0, 0)->opcode);
754    EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
755    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
756    EXPECT_EQ(BRW_CONDITIONAL_L, instruction(block0, 1)->conditional_mod);
757 }
758 
TEST_F(cmod_propagation_test,cmp_mov_vec4)759 TEST_F(cmod_propagation_test, cmp_mov_vec4)
760 {
761    const vec4_builder bld = vec4_builder(v).at_end();
762    dst_reg dest = dst_reg(v, glsl_type::ivec4_type);
763    dest.writemask = WRITEMASK_X;
764    src_reg src0 = src_reg(v, glsl_type::ivec4_type);
765    src0.swizzle = BRW_SWIZZLE_XXXX;
766    src0.file = UNIFORM;
767    src_reg nonone = retype(brw_imm_d(16), BRW_REGISTER_TYPE_D);
768    src_reg mov_src = src_reg(dest);
769    mov_src.swizzle = BRW_SWIZZLE_XXXX;
770    dst_reg dest_null = bld.null_reg_d();
771    dest_null.writemask = WRITEMASK_X;
772 
773    bld.CMP(dest, src0, nonone, BRW_CONDITIONAL_GE);
774    set_condmod(BRW_CONDITIONAL_NZ,
775                bld.MOV(dest_null, mov_src));
776 
777    /* = Before =
778     *
779     * 0: cmp.ge.f0  dest.x:D  u.xxxx:D  16D
780     * 1: mov.nz.f0  null.x:D  dest.xxxx:D
781     *
782     * = After =
783     * 0: cmp.ge.f0  dest.x:D  u.xxxx:D  16D
784     */
785 
786    v->calculate_cfg();
787    bblock_t *block0 = v->cfg->blocks[0];
788 
789    EXPECT_EQ(0, block0->start_ip);
790    EXPECT_EQ(1, block0->end_ip);
791 
792    EXPECT_TRUE(cmod_propagation(v));
793 
794    ASSERT_EQ(0, block0->start_ip);
795    ASSERT_EQ(0, block0->end_ip);
796    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 0)->opcode);
797    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
798 }
799 
TEST_F(cmod_propagation_test,mul_cmp_different_channels_vec4)800 TEST_F(cmod_propagation_test, mul_cmp_different_channels_vec4)
801 {
802    const vec4_builder bld = vec4_builder(v).at_end();
803    dst_reg dest = dst_reg(v, glsl_type::vec4_type);
804    src_reg src0 = src_reg(v, glsl_type::vec4_type);
805    src_reg src1 = src_reg(v, glsl_type::vec4_type);
806    src_reg zero(brw_imm_f(0.0f));
807    src_reg cmp_src = src_reg(dest);
808    cmp_src.swizzle = BRW_SWIZZLE4(0,1,3,2);
809 
810    bld.MUL(dest, src0, src1);
811    bld.CMP(bld.null_reg_f(), cmp_src, zero, BRW_CONDITIONAL_NZ);
812 
813    /* = Before =
814     * 0: mul         dest  src0       src1
815     * 1: cmp.nz.f0.0 null  dest.xywz  0.0f
816     *
817     * = After =
818     * (No changes)
819     */
820 
821    v->calculate_cfg();
822    bblock_t *block0 = v->cfg->blocks[0];
823 
824    EXPECT_EQ(0, block0->start_ip);
825    EXPECT_EQ(1, block0->end_ip);
826 
827    EXPECT_FALSE(cmod_propagation(v));
828 
829    ASSERT_EQ(0, block0->start_ip);
830    ASSERT_EQ(1, block0->end_ip);
831    EXPECT_EQ(BRW_OPCODE_MUL, instruction(block0, 0)->opcode);
832    EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
833    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
834    EXPECT_EQ(BRW_CONDITIONAL_NZ, instruction(block0, 1)->conditional_mod);
835 }
836 
TEST_F(cmod_propagation_test,add_cmp_same_dst_writemask)837 TEST_F(cmod_propagation_test, add_cmp_same_dst_writemask)
838 {
839    const vec4_builder bld = vec4_builder(v).at_end();
840    dst_reg dest = dst_reg(v, glsl_type::vec4_type);
841    src_reg src0 = src_reg(v, glsl_type::vec4_type);
842    src_reg src1 = src_reg(v, glsl_type::vec4_type);
843    dst_reg dest_null = bld.null_reg_f();
844 
845    bld.ADD(dest, src0, src1);
846    vec4_instruction *inst = bld.CMP(dest_null, src0, src1, BRW_CONDITIONAL_GE);
847    inst->src[1].negate = true;
848 
849    /* = Before =
850     *
851     * 0: add        dest.xyzw  src0  src1
852     * 1: cmp.ge.f0  null.xyzw  src0  -src1
853     *
854     * = After =
855     * 0: add.ge.f0  dest.xyzw  src0  src1
856     */
857 
858    v->calculate_cfg();
859    bblock_t *block0 = v->cfg->blocks[0];
860 
861    EXPECT_EQ(0, block0->start_ip);
862    EXPECT_EQ(1, block0->end_ip);
863 
864    EXPECT_TRUE(cmod_propagation(v));
865 
866    ASSERT_EQ(0, block0->start_ip);
867    ASSERT_EQ(0, block0->end_ip);
868    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
869    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
870 }
871 
TEST_F(cmod_propagation_test,add_cmp_different_dst_writemask)872 TEST_F(cmod_propagation_test, add_cmp_different_dst_writemask)
873 {
874    const vec4_builder bld = vec4_builder(v).at_end();
875    dst_reg dest = dst_reg(v, glsl_type::float_type);
876    src_reg src0 = src_reg(v, glsl_type::vec4_type);
877    src_reg src1 = src_reg(v, glsl_type::vec4_type);
878    dst_reg dest_null = bld.null_reg_f();
879 
880    bld.ADD(dest, src0, src1);
881    vec4_instruction *inst = bld.CMP(dest_null, src0, src1, BRW_CONDITIONAL_GE);
882    inst->src[1].negate = true;
883 
884    /* = Before =
885     *
886     * 0: add        dest.x     src0  src1
887     * 1: cmp.ge.f0  null.xyzw  src0  -src1
888     *
889     * = After =
890     * (no changes)
891     */
892 
893    v->calculate_cfg();
894    bblock_t *block0 = v->cfg->blocks[0];
895 
896    EXPECT_EQ(0, block0->start_ip);
897    EXPECT_EQ(1, block0->end_ip);
898 
899    EXPECT_FALSE(cmod_propagation(v));
900 
901    ASSERT_EQ(0, block0->start_ip);
902    ASSERT_EQ(1, block0->end_ip);
903    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
904    EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
905    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
906    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
907 }
908 
TEST_F(cmod_propagation_test,prop_across_sel_gfx7)909 TEST_F(cmod_propagation_test, prop_across_sel_gfx7)
910 {
911    const vec4_builder bld = vec4_builder(v).at_end();
912    dst_reg dest1 = dst_reg(v, glsl_type::float_type);
913    dst_reg dest2 = dst_reg(v, glsl_type::float_type);
914    src_reg src0 = src_reg(v, glsl_type::float_type);
915    src_reg src1 = src_reg(v, glsl_type::float_type);
916    src_reg src2 = src_reg(v, glsl_type::float_type);
917    src_reg src3 = src_reg(v, glsl_type::float_type);
918    src_reg zero(brw_imm_f(0.0f));
919    dst_reg dest_null = bld.null_reg_f();
920    dest_null.writemask = WRITEMASK_X;
921 
922    bld.ADD(dest1, src0, src1);
923    bld.SEL(dest2, src2, src3)
924       ->conditional_mod = BRW_CONDITIONAL_GE;
925    bld.CMP(dest_null, src_reg(dest1), zero, BRW_CONDITIONAL_GE);
926 
927    /* = Before =
928     *
929     * 0: add        dest1.x src0.xxxx  src1.xxxx
930     * 1: sel.ge.f0  dest2.x src2.xxxx  src3.xxxx
931     * 2: cmp.ge.f0  null.x  dest.xxxx  0.0f
932     *
933     * = After =
934     * 0: add.ge.f0  dest.x  src0.xxxx  src1.xxxx
935     * 1: sel.ge.f0  dest2.x src2.xxxx  src3.xxxx
936     */
937 
938    v->calculate_cfg();
939    bblock_t *block0 = v->cfg->blocks[0];
940 
941    EXPECT_EQ(0, block0->start_ip);
942    EXPECT_EQ(2, block0->end_ip);
943 
944    EXPECT_TRUE(cmod_propagation(v));
945 
946    ASSERT_EQ(0, block0->start_ip);
947    ASSERT_EQ(1, block0->end_ip);
948    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
949    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
950    EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
951    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
952 }
953 
TEST_F(cmod_propagation_test,prop_across_sel_gfx5)954 TEST_F(cmod_propagation_test, prop_across_sel_gfx5)
955 {
956    devinfo->ver = 5;
957    devinfo->verx10 = devinfo->ver * 10;
958 
959    const vec4_builder bld = vec4_builder(v).at_end();
960    dst_reg dest1 = dst_reg(v, glsl_type::float_type);
961    dst_reg dest2 = dst_reg(v, glsl_type::float_type);
962    src_reg src0 = src_reg(v, glsl_type::float_type);
963    src_reg src1 = src_reg(v, glsl_type::float_type);
964    src_reg src2 = src_reg(v, glsl_type::float_type);
965    src_reg src3 = src_reg(v, glsl_type::float_type);
966    src_reg zero(brw_imm_f(0.0f));
967    dst_reg dest_null = bld.null_reg_f();
968    dest_null.writemask = WRITEMASK_X;
969 
970    bld.ADD(dest1, src0, src1);
971    bld.SEL(dest2, src2, src3)
972       ->conditional_mod = BRW_CONDITIONAL_GE;
973    bld.CMP(dest_null, src_reg(dest1), zero, BRW_CONDITIONAL_GE);
974 
975    /* = Before =
976     *
977     * 0: add        dest1.x src0.xxxx  src1.xxxx
978     * 1: sel.ge.f0  dest2.x src2.xxxx  src3.xxxx
979     * 2: cmp.ge.f0  null.x  dest.xxxx  0.0f
980     *
981     * = After =
982     * (no changes)
983     *
984     * On Gfx4 and Gfx5, sel.l (for min) and sel.ge (for max) are implemented
985     * using a separate cmpn and sel instruction.  This lowering occurs in
986     * fs_vistor::lower_minmax which is called a long time after the first
987     * calls to cmod_propagation.
988     */
989 
990    v->calculate_cfg();
991    bblock_t *block0 = v->cfg->blocks[0];
992 
993    EXPECT_EQ(0, block0->start_ip);
994    EXPECT_EQ(2, block0->end_ip);
995 
996    EXPECT_FALSE(cmod_propagation(v));
997 
998    ASSERT_EQ(0, block0->start_ip);
999    ASSERT_EQ(2, block0->end_ip);
1000    EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
1001    EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
1002    EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
1003    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
1004    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
1005    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
1006 }
1007 
TEST_F(cmod_propagation_test,prop_into_sel_gfx5)1008 TEST_F(cmod_propagation_test, prop_into_sel_gfx5)
1009 {
1010    devinfo->ver = 5;
1011    devinfo->verx10 = devinfo->ver * 10;
1012 
1013    const vec4_builder bld = vec4_builder(v).at_end();
1014    dst_reg dest = dst_reg(v, glsl_type::float_type);
1015    src_reg src0 = src_reg(v, glsl_type::float_type);
1016    src_reg src1 = src_reg(v, glsl_type::float_type);
1017    src_reg zero(brw_imm_f(0.0f));
1018    dst_reg dest_null = bld.null_reg_f();
1019    dest_null.writemask = WRITEMASK_X;
1020 
1021    bld.SEL(dest, src0, src1)
1022       ->conditional_mod = BRW_CONDITIONAL_GE;
1023    bld.CMP(dest_null, src_reg(dest), zero, BRW_CONDITIONAL_GE);
1024 
1025    /* = Before =
1026     *
1027     * 0: sel.ge.f0  dest.x  src2.xxxx  src3.xxxx
1028     * 1: cmp.ge.f0  null.x  dest.xxxx  0.0f
1029     *
1030     * = After =
1031     * (no changes)
1032     *
1033     * Do not copy propagate into a sel.cond instruction.  While it does modify
1034     * the flags, the flags are not based on the result compared with zero (as
1035     * with most other instructions).  The result is based on the sources
1036     * compared with each other (like cmp.cond).
1037     */
1038 
1039    v->calculate_cfg();
1040    bblock_t *block0 = v->cfg->blocks[0];
1041 
1042    EXPECT_EQ(0, block0->start_ip);
1043    EXPECT_EQ(1, block0->end_ip);
1044 
1045    EXPECT_FALSE(cmod_propagation(v));
1046 
1047    ASSERT_EQ(0, block0->start_ip);
1048    ASSERT_EQ(1, block0->end_ip);
1049    EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 0)->opcode);
1050    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
1051    EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
1052    EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
1053 }
1054