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