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