2 * Copyright © 2015 Intel Corporation
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:
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
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
24 #include <gtest/gtest.h>
27 #include "program/program.h"
31 class cmod_propagation_test
: public ::testing::Test
{
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
;
42 void test_positive_float_saturate_prop(enum brw_conditional_mod before
,
43 enum brw_conditional_mod after
,
46 void test_negative_float_saturate_prop(enum brw_conditional_mod before
,
49 void test_negative_int_saturate_prop(enum brw_conditional_mod before
,
53 class cmod_propagation_fs_visitor
: public fs_visitor
56 cmod_propagation_fs_visitor(struct brw_compiler
*compiler
,
57 struct brw_wm_prog_data
*prog_data
,
59 : fs_visitor(compiler
, NULL
, NULL
, NULL
,
60 &prog_data
->base
, (struct gl_program
*) NULL
,
65 void cmod_propagation_test::SetUp()
67 ctx
= (struct gl_context
*)calloc(1, sizeof(*ctx
));
68 compiler
= (struct brw_compiler
*)calloc(1, sizeof(*compiler
));
69 devinfo
= (struct gen_device_info
*)calloc(1, sizeof(*devinfo
));
70 compiler
->devinfo
= devinfo
;
72 prog_data
= ralloc(NULL
, struct brw_wm_prog_data
);
74 nir_shader_create(NULL
, MESA_SHADER_FRAGMENT
, NULL
, NULL
);
76 v
= new cmod_propagation_fs_visitor(compiler
, prog_data
, shader
);
82 instruction(bblock_t
*block
, int num
)
84 fs_inst
*inst
= (fs_inst
*)block
->start();
85 for (int i
= 0; i
< num
; i
++) {
86 inst
= (fs_inst
*)inst
->next
;
92 cmod_propagation(fs_visitor
*v
)
94 const bool print
= getenv("TEST_DEBUG");
97 fprintf(stderr
, "= Before =\n");
101 bool ret
= v
->opt_cmod_propagation();
104 fprintf(stderr
, "\n= After =\n");
111 TEST_F(cmod_propagation_test
, basic
)
113 const fs_builder
&bld
= v
->bld
;
114 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
115 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
116 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
117 fs_reg
zero(brw_imm_f(0.0f
));
118 bld
.ADD(dest
, src0
, src1
);
119 bld
.CMP(bld
.null_reg_f(), dest
, zero
, BRW_CONDITIONAL_GE
);
123 * 0: add(8) dest src0 src1
124 * 1: cmp.ge.f0(8) null dest 0.0f
127 * 0: add.ge.f0(8) dest src0 src1
131 bblock_t
*block0
= v
->cfg
->blocks
[0];
133 EXPECT_EQ(0, block0
->start_ip
);
134 EXPECT_EQ(1, block0
->end_ip
);
136 EXPECT_TRUE(cmod_propagation(v
));
137 EXPECT_EQ(0, block0
->start_ip
);
138 EXPECT_EQ(0, block0
->end_ip
);
139 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
140 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 0)->conditional_mod
);
143 TEST_F(cmod_propagation_test
, basic_other_flag
)
145 const fs_builder
&bld
= v
->bld
;
146 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
147 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
148 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
149 fs_reg
zero(brw_imm_f(0.0f
));
150 bld
.ADD(dest
, src0
, src1
);
151 bld
.CMP(bld
.null_reg_f(), dest
, zero
, BRW_CONDITIONAL_GE
)
156 * 0: add(8) dest src0 src1
157 * 1: cmp.ge.f0.1(8) null dest 0.0f
160 * 0: add.ge.f0.1(8) dest src0 src1
164 bblock_t
*block0
= v
->cfg
->blocks
[0];
166 EXPECT_EQ(0, block0
->start_ip
);
167 EXPECT_EQ(1, block0
->end_ip
);
169 EXPECT_TRUE(cmod_propagation(v
));
170 EXPECT_EQ(0, block0
->start_ip
);
171 EXPECT_EQ(0, block0
->end_ip
);
172 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
173 EXPECT_EQ(1, instruction(block0
, 0)->flag_subreg
);
174 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 0)->conditional_mod
);
177 TEST_F(cmod_propagation_test
, cmp_nonzero
)
179 const fs_builder
&bld
= v
->bld
;
180 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
181 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
182 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
183 fs_reg
nonzero(brw_imm_f(1.0f
));
184 bld
.ADD(dest
, src0
, src1
);
185 bld
.CMP(bld
.null_reg_f(), dest
, nonzero
, BRW_CONDITIONAL_GE
);
189 * 0: add(8) dest src0 src1
190 * 1: cmp.ge.f0(8) null dest 1.0f
197 bblock_t
*block0
= v
->cfg
->blocks
[0];
199 EXPECT_EQ(0, block0
->start_ip
);
200 EXPECT_EQ(1, block0
->end_ip
);
202 EXPECT_FALSE(cmod_propagation(v
));
203 EXPECT_EQ(0, block0
->start_ip
);
204 EXPECT_EQ(1, block0
->end_ip
);
205 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
206 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
207 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 1)->conditional_mod
);
210 TEST_F(cmod_propagation_test
, non_cmod_instruction
)
212 const fs_builder
&bld
= v
->bld
;
213 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
214 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
215 fs_reg
zero(brw_imm_ud(0u));
217 bld
.CMP(bld
.null_reg_ud(), dest
, zero
, BRW_CONDITIONAL_GE
);
221 * 0: fbl(8) dest src0
222 * 1: cmp.ge.f0(8) null dest 0u
229 bblock_t
*block0
= v
->cfg
->blocks
[0];
231 EXPECT_EQ(0, block0
->start_ip
);
232 EXPECT_EQ(1, block0
->end_ip
);
234 EXPECT_FALSE(cmod_propagation(v
));
235 EXPECT_EQ(0, block0
->start_ip
);
236 EXPECT_EQ(1, block0
->end_ip
);
237 EXPECT_EQ(BRW_OPCODE_FBL
, instruction(block0
, 0)->opcode
);
238 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
239 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 1)->conditional_mod
);
242 TEST_F(cmod_propagation_test
, intervening_flag_write
)
244 const fs_builder
&bld
= v
->bld
;
245 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
246 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
247 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
248 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
249 fs_reg
zero(brw_imm_f(0.0f
));
250 bld
.ADD(dest
, src0
, src1
);
251 bld
.CMP(bld
.null_reg_f(), src2
, zero
, BRW_CONDITIONAL_GE
);
252 bld
.CMP(bld
.null_reg_f(), dest
, zero
, BRW_CONDITIONAL_GE
);
256 * 0: add(8) dest src0 src1
257 * 1: cmp.ge.f0(8) null src2 0.0f
258 * 2: cmp.ge.f0(8) null dest 0.0f
265 bblock_t
*block0
= v
->cfg
->blocks
[0];
267 EXPECT_EQ(0, block0
->start_ip
);
268 EXPECT_EQ(2, block0
->end_ip
);
270 EXPECT_FALSE(cmod_propagation(v
));
271 EXPECT_EQ(0, block0
->start_ip
);
272 EXPECT_EQ(2, block0
->end_ip
);
273 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
274 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
275 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 1)->conditional_mod
);
276 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
277 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 2)->conditional_mod
);
280 TEST_F(cmod_propagation_test
, intervening_mismatch_flag_write
)
282 const fs_builder
&bld
= v
->bld
;
283 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
284 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
285 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
286 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
287 fs_reg
zero(brw_imm_f(0.0f
));
288 bld
.ADD(dest
, src0
, src1
);
289 bld
.CMP(bld
.null_reg_f(), src2
, zero
, BRW_CONDITIONAL_GE
)
291 bld
.CMP(bld
.null_reg_f(), dest
, zero
, BRW_CONDITIONAL_GE
);
295 * 0: add(8) dest src0 src1
296 * 1: cmp.ge.f0.1(8) null src2 0.0f
297 * 2: cmp.ge.f0(8) null dest 0.0f
300 * 0: add.ge.f0(8) dest src0 src1
301 * 1: cmp.ge.f0.1(8) null src2 0.0f
305 bblock_t
*block0
= v
->cfg
->blocks
[0];
307 EXPECT_EQ(0, block0
->start_ip
);
308 EXPECT_EQ(2, block0
->end_ip
);
310 EXPECT_TRUE(cmod_propagation(v
));
311 EXPECT_EQ(0, block0
->start_ip
);
312 EXPECT_EQ(1, block0
->end_ip
);
313 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
314 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 0)->conditional_mod
);
315 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
316 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
317 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 1)->conditional_mod
);
318 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
321 TEST_F(cmod_propagation_test
, intervening_flag_read
)
323 const fs_builder
&bld
= v
->bld
;
324 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
325 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
326 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
327 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
328 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
329 fs_reg
zero(brw_imm_f(0.0f
));
330 bld
.ADD(dest0
, src0
, src1
);
331 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
));
332 bld
.CMP(bld
.null_reg_f(), dest0
, zero
, BRW_CONDITIONAL_GE
);
336 * 0: add(8) dest0 src0 src1
337 * 1: (+f0) sel(8) dest1 src2 0.0f
338 * 2: cmp.ge.f0(8) null dest0 0.0f
345 bblock_t
*block0
= v
->cfg
->blocks
[0];
347 EXPECT_EQ(0, block0
->start_ip
);
348 EXPECT_EQ(2, block0
->end_ip
);
350 EXPECT_FALSE(cmod_propagation(v
));
351 EXPECT_EQ(0, block0
->start_ip
);
352 EXPECT_EQ(2, block0
->end_ip
);
353 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
354 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
355 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
356 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
357 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 2)->conditional_mod
);
360 TEST_F(cmod_propagation_test
, intervening_mismatch_flag_read
)
362 const fs_builder
&bld
= v
->bld
;
363 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
364 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
365 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
366 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
367 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
368 fs_reg
zero(brw_imm_f(0.0f
));
369 bld
.ADD(dest0
, src0
, src1
);
370 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
))
372 bld
.CMP(bld
.null_reg_f(), dest0
, zero
, BRW_CONDITIONAL_GE
);
376 * 0: add(8) dest0 src0 src1
377 * 1: (+f0.1) sel(8) dest1 src2 0.0f
378 * 2: cmp.ge.f0(8) null dest0 0.0f
381 * 0: add.ge.f0(8) dest0 src0 src1
382 * 1: (+f0.1) sel(8) dest1 src2 0.0f
386 bblock_t
*block0
= v
->cfg
->blocks
[0];
388 EXPECT_EQ(0, block0
->start_ip
);
389 EXPECT_EQ(2, block0
->end_ip
);
391 EXPECT_TRUE(cmod_propagation(v
));
392 EXPECT_EQ(0, block0
->start_ip
);
393 EXPECT_EQ(1, block0
->end_ip
);
394 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
395 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 0)->conditional_mod
);
396 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
397 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
398 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
399 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
402 TEST_F(cmod_propagation_test
, intervening_dest_write
)
404 const fs_builder
&bld
= v
->bld
;
405 fs_reg dest
= v
->vgrf(glsl_type::vec4_type
);
406 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
407 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
408 fs_reg src2
= v
->vgrf(glsl_type::vec2_type
);
409 fs_reg
zero(brw_imm_f(0.0f
));
410 bld
.ADD(offset(dest
, bld
, 2), src0
, src1
);
411 bld
.emit(SHADER_OPCODE_TEX
, dest
, src2
)
412 ->size_written
= 4 * REG_SIZE
;
413 bld
.CMP(bld
.null_reg_f(), offset(dest
, bld
, 2), zero
, BRW_CONDITIONAL_GE
);
417 * 0: add(8) dest+2 src0 src1
418 * 1: tex(8) rlen 4 dest+0 src2
419 * 2: cmp.ge.f0(8) null dest+2 0.0f
426 bblock_t
*block0
= v
->cfg
->blocks
[0];
428 EXPECT_EQ(0, block0
->start_ip
);
429 EXPECT_EQ(2, block0
->end_ip
);
431 EXPECT_FALSE(cmod_propagation(v
));
432 EXPECT_EQ(0, block0
->start_ip
);
433 EXPECT_EQ(2, block0
->end_ip
);
434 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
435 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
436 EXPECT_EQ(SHADER_OPCODE_TEX
, instruction(block0
, 1)->opcode
);
437 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
438 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
439 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 2)->conditional_mod
);
442 TEST_F(cmod_propagation_test
, intervening_flag_read_same_value
)
444 const fs_builder
&bld
= v
->bld
;
445 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
446 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
447 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
448 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
449 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
450 fs_reg
zero(brw_imm_f(0.0f
));
451 set_condmod(BRW_CONDITIONAL_GE
, bld
.ADD(dest0
, src0
, src1
));
452 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
));
453 bld
.CMP(bld
.null_reg_f(), dest0
, zero
, BRW_CONDITIONAL_GE
);
457 * 0: add.ge.f0(8) dest0 src0 src1
458 * 1: (+f0) sel(8) dest1 src2 0.0f
459 * 2: cmp.ge.f0(8) null dest0 0.0f
462 * 0: add.ge.f0(8) dest0 src0 src1
463 * 1: (+f0) sel(8) dest1 src2 0.0f
467 bblock_t
*block0
= v
->cfg
->blocks
[0];
469 EXPECT_EQ(0, block0
->start_ip
);
470 EXPECT_EQ(2, block0
->end_ip
);
472 EXPECT_TRUE(cmod_propagation(v
));
473 EXPECT_EQ(0, block0
->start_ip
);
474 EXPECT_EQ(1, block0
->end_ip
);
475 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
476 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 0)->conditional_mod
);
477 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
478 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
481 TEST_F(cmod_propagation_test
, negate
)
483 const fs_builder
&bld
= v
->bld
;
484 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
485 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
486 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
487 fs_reg
zero(brw_imm_f(0.0f
));
488 bld
.ADD(dest
, src0
, src1
);
490 bld
.CMP(bld
.null_reg_f(), dest
, zero
, BRW_CONDITIONAL_GE
);
494 * 0: add(8) dest src0 src1
495 * 1: cmp.ge.f0(8) null -dest 0.0f
498 * 0: add.le.f0(8) dest src0 src1
502 bblock_t
*block0
= v
->cfg
->blocks
[0];
504 EXPECT_EQ(0, block0
->start_ip
);
505 EXPECT_EQ(1, block0
->end_ip
);
507 EXPECT_TRUE(cmod_propagation(v
));
508 EXPECT_EQ(0, block0
->start_ip
);
509 EXPECT_EQ(0, block0
->end_ip
);
510 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
511 EXPECT_EQ(BRW_CONDITIONAL_LE
, instruction(block0
, 0)->conditional_mod
);
514 TEST_F(cmod_propagation_test
, movnz
)
516 const fs_builder
&bld
= v
->bld
;
517 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
518 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
519 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
520 bld
.CMP(dest
, src0
, src1
, BRW_CONDITIONAL_GE
);
521 set_condmod(BRW_CONDITIONAL_NZ
,
522 bld
.MOV(bld
.null_reg_f(), dest
));
526 * 0: cmp.ge.f0(8) dest src0 src1
527 * 1: mov.nz.f0(8) null dest
530 * 0: cmp.ge.f0(8) dest src0 src1
534 bblock_t
*block0
= v
->cfg
->blocks
[0];
536 EXPECT_EQ(0, block0
->start_ip
);
537 EXPECT_EQ(1, block0
->end_ip
);
539 EXPECT_TRUE(cmod_propagation(v
));
540 EXPECT_EQ(0, block0
->start_ip
);
541 EXPECT_EQ(0, block0
->end_ip
);
542 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 0)->opcode
);
543 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 0)->conditional_mod
);
546 TEST_F(cmod_propagation_test
, different_types_cmod_with_zero
)
548 const fs_builder
&bld
= v
->bld
;
549 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
550 fs_reg src0
= v
->vgrf(glsl_type::int_type
);
551 fs_reg src1
= v
->vgrf(glsl_type::int_type
);
552 fs_reg
zero(brw_imm_f(0.0f
));
553 bld
.ADD(dest
, src0
, src1
);
554 bld
.CMP(bld
.null_reg_f(), retype(dest
, BRW_REGISTER_TYPE_F
), zero
,
559 * 0: add(8) dest:D src0:D src1:D
560 * 1: cmp.ge.f0(8) null:F dest:F 0.0f
567 bblock_t
*block0
= v
->cfg
->blocks
[0];
569 EXPECT_EQ(0, block0
->start_ip
);
570 EXPECT_EQ(1, block0
->end_ip
);
572 EXPECT_FALSE(cmod_propagation(v
));
573 EXPECT_EQ(0, block0
->start_ip
);
574 EXPECT_EQ(1, block0
->end_ip
);
575 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
576 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
577 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 1)->conditional_mod
);
580 TEST_F(cmod_propagation_test
, andnz_one
)
582 const fs_builder
&bld
= v
->bld
;
583 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
584 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
585 fs_reg
zero(brw_imm_f(0.0f
));
586 fs_reg
one(brw_imm_d(1));
588 bld
.CMP(retype(dest
, BRW_REGISTER_TYPE_F
), src0
, zero
, BRW_CONDITIONAL_L
);
589 set_condmod(BRW_CONDITIONAL_NZ
,
590 bld
.AND(bld
.null_reg_d(), dest
, one
));
593 * 0: cmp.l.f0(8) dest:F src0:F 0F
594 * 1: and.nz.f0(8) null:D dest:D 1D
597 * 0: cmp.l.f0(8) dest:F src0:F 0F
601 bblock_t
*block0
= v
->cfg
->blocks
[0];
603 EXPECT_EQ(0, block0
->start_ip
);
604 EXPECT_EQ(1, block0
->end_ip
);
606 EXPECT_TRUE(cmod_propagation(v
));
607 EXPECT_EQ(0, block0
->start_ip
);
608 EXPECT_EQ(0, block0
->end_ip
);
609 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 0)->opcode
);
610 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
611 EXPECT_TRUE(retype(dest
, BRW_REGISTER_TYPE_F
)
612 .equals(instruction(block0
, 0)->dst
));
615 TEST_F(cmod_propagation_test
, andnz_non_one
)
617 const fs_builder
&bld
= v
->bld
;
618 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
619 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
620 fs_reg
zero(brw_imm_f(0.0f
));
621 fs_reg
nonone(brw_imm_d(38));
623 bld
.CMP(retype(dest
, BRW_REGISTER_TYPE_F
), src0
, zero
, BRW_CONDITIONAL_L
);
624 set_condmod(BRW_CONDITIONAL_NZ
,
625 bld
.AND(bld
.null_reg_d(), dest
, nonone
));
628 * 0: cmp.l.f0(8) dest:F src0:F 0F
629 * 1: and.nz.f0(8) null:D dest:D 38D
636 bblock_t
*block0
= v
->cfg
->blocks
[0];
638 EXPECT_EQ(0, block0
->start_ip
);
639 EXPECT_EQ(1, block0
->end_ip
);
641 EXPECT_FALSE(cmod_propagation(v
));
642 EXPECT_EQ(0, block0
->start_ip
);
643 EXPECT_EQ(1, block0
->end_ip
);
644 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 0)->opcode
);
645 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
646 EXPECT_EQ(BRW_OPCODE_AND
, instruction(block0
, 1)->opcode
);
647 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 1)->conditional_mod
);
650 TEST_F(cmod_propagation_test
, andz_one
)
652 const fs_builder
&bld
= v
->bld
;
653 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
654 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
655 fs_reg
zero(brw_imm_f(0.0f
));
656 fs_reg
one(brw_imm_d(1));
658 bld
.CMP(retype(dest
, BRW_REGISTER_TYPE_F
), src0
, zero
, BRW_CONDITIONAL_L
);
659 set_condmod(BRW_CONDITIONAL_Z
,
660 bld
.AND(bld
.null_reg_d(), dest
, one
));
663 * 0: cmp.l.f0(8) dest:F src0:F 0F
664 * 1: and.z.f0(8) null:D dest:D 1D
671 bblock_t
*block0
= v
->cfg
->blocks
[0];
673 EXPECT_EQ(0, block0
->start_ip
);
674 EXPECT_EQ(1, block0
->end_ip
);
676 EXPECT_FALSE(cmod_propagation(v
));
677 EXPECT_EQ(0, block0
->start_ip
);
678 EXPECT_EQ(1, block0
->end_ip
);
679 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 0)->opcode
);
680 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
681 EXPECT_EQ(BRW_OPCODE_AND
, instruction(block0
, 1)->opcode
);
682 EXPECT_EQ(BRW_CONDITIONAL_EQ
, instruction(block0
, 1)->conditional_mod
);
685 TEST_F(cmod_propagation_test
, add_not_merge_with_compare
)
687 const fs_builder
&bld
= v
->bld
;
688 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
689 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
690 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
691 bld
.ADD(dest
, src0
, src1
);
692 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
694 /* The addition and the implicit subtraction in the compare do not compute
698 * 0: add(8) dest:F src0:F src1:F
699 * 1: cmp.l.f0(8) null:F src0:F src1:F
705 bblock_t
*block0
= v
->cfg
->blocks
[0];
707 EXPECT_EQ(0, block0
->start_ip
);
708 EXPECT_EQ(1, block0
->end_ip
);
710 EXPECT_FALSE(cmod_propagation(v
));
711 EXPECT_EQ(0, block0
->start_ip
);
712 EXPECT_EQ(1, block0
->end_ip
);
713 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
714 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
715 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
716 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 1)->conditional_mod
);
719 TEST_F(cmod_propagation_test
, subtract_merge_with_compare
)
721 const fs_builder
&bld
= v
->bld
;
722 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
723 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
724 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
725 bld
.ADD(dest
, src0
, negate(src1
));
726 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
729 * 0: add(8) dest:F src0:F -src1:F
730 * 1: cmp.l.f0(8) null:F src0:F src1:F
733 * 0: add.l.f0(8) dest:F src0:F -src1:F
736 bblock_t
*block0
= v
->cfg
->blocks
[0];
738 EXPECT_EQ(0, block0
->start_ip
);
739 EXPECT_EQ(1, block0
->end_ip
);
741 EXPECT_TRUE(cmod_propagation(v
));
742 EXPECT_EQ(0, block0
->start_ip
);
743 EXPECT_EQ(0, block0
->end_ip
);
744 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
745 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
748 TEST_F(cmod_propagation_test
, subtract_immediate_merge_with_compare
)
750 const fs_builder
&bld
= v
->bld
;
751 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
752 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
753 fs_reg
one(brw_imm_f(1.0f
));
754 fs_reg
negative_one(brw_imm_f(-1.0f
));
756 bld
.ADD(dest
, src0
, negative_one
);
757 bld
.CMP(bld
.null_reg_f(), src0
, one
, BRW_CONDITIONAL_NZ
);
760 * 0: add(8) dest:F src0:F -1.0f
761 * 1: cmp.nz.f0(8) null:F src0:F 1.0f
764 * 0: add.nz.f0(8) dest:F src0:F -1.0f
767 bblock_t
*block0
= v
->cfg
->blocks
[0];
769 EXPECT_EQ(0, block0
->start_ip
);
770 EXPECT_EQ(1, block0
->end_ip
);
772 EXPECT_TRUE(cmod_propagation(v
));
773 EXPECT_EQ(0, block0
->start_ip
);
774 EXPECT_EQ(0, block0
->end_ip
);
775 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
776 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 0)->conditional_mod
);
779 TEST_F(cmod_propagation_test
, subtract_merge_with_compare_intervening_add
)
781 const fs_builder
&bld
= v
->bld
;
782 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
783 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
784 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
785 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
786 bld
.ADD(dest0
, src0
, negate(src1
));
787 bld
.ADD(dest1
, src0
, src1
);
788 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
791 * 0: add(8) dest0:F src0:F -src1:F
792 * 1: add(8) dest1:F src0:F src1:F
793 * 2: cmp.l.f0(8) null:F src0:F src1:F
796 * 0: add.l.f0(8) dest0:F src0:F -src1:F
797 * 1: add(8) dest1:F src0:F src1:F
800 bblock_t
*block0
= v
->cfg
->blocks
[0];
802 EXPECT_EQ(0, block0
->start_ip
);
803 EXPECT_EQ(2, block0
->end_ip
);
805 EXPECT_TRUE(cmod_propagation(v
));
806 EXPECT_EQ(0, block0
->start_ip
);
807 EXPECT_EQ(1, block0
->end_ip
);
808 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
809 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
810 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 1)->opcode
);
811 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 1)->conditional_mod
);
814 TEST_F(cmod_propagation_test
, subtract_not_merge_with_compare_intervening_partial_write
)
816 const fs_builder
&bld
= v
->bld
;
817 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
818 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
819 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
820 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
821 bld
.ADD(dest0
, src0
, negate(src1
));
822 set_predicate(BRW_PREDICATE_NORMAL
, bld
.ADD(dest1
, src0
, negate(src1
)));
823 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
826 * 0: add(8) dest0:F src0:F -src1:F
827 * 1: (+f0) add(8) dest1:F src0:F -src1:F
828 * 2: cmp.l.f0(8) null:F src0:F src1:F
834 bblock_t
*block0
= v
->cfg
->blocks
[0];
836 EXPECT_EQ(0, block0
->start_ip
);
837 EXPECT_EQ(2, block0
->end_ip
);
839 EXPECT_FALSE(cmod_propagation(v
));
840 EXPECT_EQ(0, block0
->start_ip
);
841 EXPECT_EQ(2, block0
->end_ip
);
842 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
843 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
844 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 1)->opcode
);
845 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 1)->conditional_mod
);
846 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
847 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 2)->conditional_mod
);
850 TEST_F(cmod_propagation_test
, subtract_not_merge_with_compare_intervening_add
)
852 const fs_builder
&bld
= v
->bld
;
853 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
854 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
855 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
856 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
857 bld
.ADD(dest0
, src0
, negate(src1
));
858 set_condmod(BRW_CONDITIONAL_EQ
, bld
.ADD(dest1
, src0
, src1
));
859 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
862 * 0: add(8) dest0:F src0:F -src1:F
863 * 1: add.z.f0(8) dest1:F src0:F src1:F
864 * 2: cmp.l.f0(8) null:F src0:F src1:F
870 bblock_t
*block0
= v
->cfg
->blocks
[0];
872 EXPECT_EQ(0, block0
->start_ip
);
873 EXPECT_EQ(2, block0
->end_ip
);
875 EXPECT_FALSE(cmod_propagation(v
));
876 EXPECT_EQ(0, block0
->start_ip
);
877 EXPECT_EQ(2, block0
->end_ip
);
878 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
879 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
880 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 1)->opcode
);
881 EXPECT_EQ(BRW_CONDITIONAL_EQ
, instruction(block0
, 1)->conditional_mod
);
882 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
883 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 2)->conditional_mod
);
886 TEST_F(cmod_propagation_test
, add_merge_with_compare
)
888 const fs_builder
&bld
= v
->bld
;
889 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
890 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
891 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
892 bld
.ADD(dest
, src0
, src1
);
893 bld
.CMP(bld
.null_reg_f(), src0
, negate(src1
), BRW_CONDITIONAL_L
);
896 * 0: add(8) dest:F src0:F src1:F
897 * 1: cmp.l.f0(8) null:F src0:F -src1:F
900 * 0: add.l.f0(8) dest:F src0:F src1:F
903 bblock_t
*block0
= v
->cfg
->blocks
[0];
905 EXPECT_EQ(0, block0
->start_ip
);
906 EXPECT_EQ(1, block0
->end_ip
);
908 EXPECT_TRUE(cmod_propagation(v
));
909 EXPECT_EQ(0, block0
->start_ip
);
910 EXPECT_EQ(0, block0
->end_ip
);
911 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
912 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
915 TEST_F(cmod_propagation_test
, negative_subtract_merge_with_compare
)
917 const fs_builder
&bld
= v
->bld
;
918 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
919 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
920 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
921 bld
.ADD(dest
, src1
, negate(src0
));
922 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
924 /* The result of the subtract is the negatiion of the result of the
925 * implicit subtract in the compare, so the condition must change.
928 * 0: add(8) dest:F src1:F -src0:F
929 * 1: cmp.l.f0(8) null:F src0:F src1:F
932 * 0: add.g.f0(8) dest:F src0:F -src1:F
935 bblock_t
*block0
= v
->cfg
->blocks
[0];
937 EXPECT_EQ(0, block0
->start_ip
);
938 EXPECT_EQ(1, block0
->end_ip
);
940 EXPECT_TRUE(cmod_propagation(v
));
941 EXPECT_EQ(0, block0
->start_ip
);
942 EXPECT_EQ(0, block0
->end_ip
);
943 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
944 EXPECT_EQ(BRW_CONDITIONAL_G
, instruction(block0
, 0)->conditional_mod
);
947 TEST_F(cmod_propagation_test
, subtract_delete_compare
)
949 const fs_builder
&bld
= v
->bld
;
950 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
951 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
952 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
953 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
954 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
956 set_condmod(BRW_CONDITIONAL_L
, bld
.ADD(dest
, src0
, negate(src1
)));
957 set_predicate(BRW_PREDICATE_NORMAL
, bld
.MOV(dest1
, src2
));
958 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
961 * 0: add.l.f0(8) dest0:F src0:F -src1:F
962 * 1: (+f0) mov(0) dest1:F src2:F
963 * 2: cmp.l.f0(8) null:F src0:F src1:F
966 * 0: add.l.f0(8) dest:F src0:F -src1:F
967 * 1: (+f0) mov(0) dest1:F src2:F
970 bblock_t
*block0
= v
->cfg
->blocks
[0];
972 EXPECT_EQ(0, block0
->start_ip
);
973 EXPECT_EQ(2, block0
->end_ip
);
975 EXPECT_TRUE(cmod_propagation(v
));
976 EXPECT_EQ(0, block0
->start_ip
);
977 EXPECT_EQ(1, block0
->end_ip
);
978 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
979 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
980 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
981 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
984 TEST_F(cmod_propagation_test
, subtract_delete_compare_other_flag
)
986 /* This test is the same as subtract_delete_compare but it explicitly used
987 * flag f0.1 for the subtraction and the comparison.
989 const fs_builder
&bld
= v
->bld
;
990 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
991 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
992 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
993 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
994 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
996 set_condmod(BRW_CONDITIONAL_L
, bld
.ADD(dest
, src0
, negate(src1
)))
998 set_predicate(BRW_PREDICATE_NORMAL
, bld
.MOV(dest1
, src2
));
999 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
)
1003 * 0: add.l.f0.1(8) dest0:F src0:F -src1:F
1004 * 1: (+f0) mov(0) dest1:F src2:F
1005 * 2: cmp.l.f0.1(8) null:F src0:F src1:F
1008 * 0: add.l.f0.1(8) dest:F src0:F -src1:F
1009 * 1: (+f0) mov(0) dest1:F src2:F
1012 bblock_t
*block0
= v
->cfg
->blocks
[0];
1014 EXPECT_EQ(0, block0
->start_ip
);
1015 EXPECT_EQ(2, block0
->end_ip
);
1017 EXPECT_TRUE(cmod_propagation(v
));
1018 EXPECT_EQ(0, block0
->start_ip
);
1019 EXPECT_EQ(1, block0
->end_ip
);
1020 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1021 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1022 EXPECT_EQ(1, instruction(block0
, 0)->flag_subreg
);
1023 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
1024 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1027 TEST_F(cmod_propagation_test
, subtract_to_mismatch_flag
)
1029 const fs_builder
&bld
= v
->bld
;
1030 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
1031 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1032 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1034 set_condmod(BRW_CONDITIONAL_L
, bld
.ADD(dest
, src0
, negate(src1
)));
1035 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
)
1039 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1040 * 1: cmp.l.f0.1(8) null:F src0:F src1:F
1046 bblock_t
*block0
= v
->cfg
->blocks
[0];
1048 EXPECT_EQ(0, block0
->start_ip
);
1049 EXPECT_EQ(1, block0
->end_ip
);
1051 EXPECT_FALSE(cmod_propagation(v
));
1052 EXPECT_EQ(0, block0
->start_ip
);
1053 EXPECT_EQ(1, block0
->end_ip
);
1054 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1055 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1056 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
1057 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
1058 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 1)->conditional_mod
);
1059 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
1062 TEST_F(cmod_propagation_test
,
1063 subtract_merge_with_compare_intervening_mismatch_flag_write
)
1065 const fs_builder
&bld
= v
->bld
;
1066 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
1067 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1068 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1070 bld
.ADD(dest0
, src0
, negate(src1
));
1071 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
)
1073 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
1076 * 0: add(8) dest0:F src0:F -src1:F
1077 * 1: cmp.l.f0.1(8) null:F src0:F src1:F
1078 * 2: cmp.l.f0(8) null:F src0:F src1:F
1081 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1082 * 1: cmp.l.f0.1(8) null:F src0:F src1:F
1084 * NOTE: Another perfectly valid after sequence would be:
1086 * 0: add.f0.1(8) dest0:F src0:F -src1:F
1087 * 1: cmp.l.f0(8) null:F src0:F src1:F
1089 * However, the optimization pass starts at the end of the basic block.
1090 * Because of this, the cmp.l.f0 will always be chosen. If the pass
1091 * changes its strategy, this test will also need to change.
1094 bblock_t
*block0
= v
->cfg
->blocks
[0];
1096 EXPECT_EQ(0, block0
->start_ip
);
1097 EXPECT_EQ(2, block0
->end_ip
);
1099 EXPECT_TRUE(cmod_propagation(v
));
1100 EXPECT_EQ(0, block0
->start_ip
);
1101 EXPECT_EQ(1, block0
->end_ip
);
1102 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1103 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1104 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
1105 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
1106 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 1)->conditional_mod
);
1107 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
1110 TEST_F(cmod_propagation_test
,
1111 subtract_merge_with_compare_intervening_mismatch_flag_read
)
1113 const fs_builder
&bld
= v
->bld
;
1114 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
1115 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1116 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1117 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1118 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
1119 fs_reg
zero(brw_imm_f(0.0f
));
1121 bld
.ADD(dest0
, src0
, negate(src1
));
1122 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
))
1124 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
1127 * 0: add(8) dest0:F src0:F -src1:F
1128 * 1: (+f0.1) sel(8) dest1 src2 0.0f
1129 * 2: cmp.l.f0(8) null:F src0:F src1:F
1132 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1133 * 1: (+f0.1) sel(8) dest1 src2 0.0f
1136 bblock_t
*block0
= v
->cfg
->blocks
[0];
1138 EXPECT_EQ(0, block0
->start_ip
);
1139 EXPECT_EQ(2, block0
->end_ip
);
1141 EXPECT_TRUE(cmod_propagation(v
));
1142 EXPECT_EQ(0, block0
->start_ip
);
1143 EXPECT_EQ(1, block0
->end_ip
);
1144 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1145 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1146 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
1147 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
1148 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1149 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
1152 TEST_F(cmod_propagation_test
, subtract_delete_compare_derp
)
1154 const fs_builder
&bld
= v
->bld
;
1155 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
1156 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1157 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1158 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1160 set_condmod(BRW_CONDITIONAL_L
, bld
.ADD(dest0
, src0
, negate(src1
)));
1161 set_predicate(BRW_PREDICATE_NORMAL
, bld
.ADD(dest1
, negate(src0
), src1
));
1162 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
1165 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1166 * 1: (+f0) add(0) dest1:F -src0:F src1:F
1167 * 2: cmp.l.f0(8) null:F src0:F src1:F
1170 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1171 * 1: (+f0) add(0) dest1:F -src0:F src1:F
1174 bblock_t
*block0
= v
->cfg
->blocks
[0];
1176 EXPECT_EQ(0, block0
->start_ip
);
1177 EXPECT_EQ(2, block0
->end_ip
);
1179 EXPECT_TRUE(cmod_propagation(v
));
1180 EXPECT_EQ(0, block0
->start_ip
);
1181 EXPECT_EQ(1, block0
->end_ip
);
1182 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1183 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1184 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 1)->opcode
);
1185 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1188 TEST_F(cmod_propagation_test
, signed_unsigned_comparison_mismatch
)
1190 const fs_builder
&bld
= v
->bld
;
1191 fs_reg dest0
= v
->vgrf(glsl_type::int_type
);
1192 fs_reg src0
= v
->vgrf(glsl_type::int_type
);
1193 src0
.type
= BRW_REGISTER_TYPE_W
;
1195 bld
.ASR(dest0
, negate(src0
), brw_imm_d(15));
1196 bld
.CMP(bld
.null_reg_ud(), retype(dest0
, BRW_REGISTER_TYPE_UD
),
1197 brw_imm_ud(0u), BRW_CONDITIONAL_LE
);
1200 * 0: asr(8) dest:D -src0:W 15D
1201 * 1: cmp.le.f0(8) null:UD dest:UD 0UD
1207 bblock_t
*block0
= v
->cfg
->blocks
[0];
1209 EXPECT_EQ(0, block0
->start_ip
);
1210 EXPECT_EQ(1, block0
->end_ip
);
1212 EXPECT_FALSE(cmod_propagation(v
));
1213 EXPECT_EQ(0, block0
->start_ip
);
1214 EXPECT_EQ(1, block0
->end_ip
);
1215 EXPECT_EQ(BRW_OPCODE_ASR
, instruction(block0
, 0)->opcode
);
1216 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
1217 EXPECT_EQ(BRW_CONDITIONAL_LE
, instruction(block0
, 1)->conditional_mod
);
1221 cmod_propagation_test::test_positive_float_saturate_prop(enum brw_conditional_mod before
,
1222 enum brw_conditional_mod after
,
1225 const fs_builder
&bld
= v
->bld
;
1226 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
1227 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1228 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1229 fs_reg
zero(brw_imm_f(0.0f
));
1230 bld
.ADD(dest
, src0
, src1
)->saturate
= true;
1232 assert(op
== BRW_OPCODE_CMP
|| op
== BRW_OPCODE_MOV
);
1233 if (op
== BRW_OPCODE_CMP
)
1234 bld
.CMP(bld
.null_reg_f(), dest
, zero
, before
);
1236 bld
.MOV(bld
.null_reg_f(), dest
)->conditional_mod
= before
;
1239 bblock_t
*block0
= v
->cfg
->blocks
[0];
1241 EXPECT_EQ(0, block0
->start_ip
);
1242 EXPECT_EQ(1, block0
->end_ip
);
1244 EXPECT_TRUE(cmod_propagation(v
));
1245 EXPECT_EQ(0, block0
->start_ip
);
1246 EXPECT_EQ(0, block0
->end_ip
);
1247 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1248 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
1249 EXPECT_EQ(after
, instruction(block0
, 0)->conditional_mod
);
1253 cmod_propagation_test::test_negative_float_saturate_prop(enum brw_conditional_mod before
,
1256 const fs_builder
&bld
= v
->bld
;
1257 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
1258 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1259 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1260 fs_reg
zero(brw_imm_f(0.0f
));
1261 bld
.ADD(dest
, src0
, src1
)->saturate
= true;
1263 assert(op
== BRW_OPCODE_CMP
|| op
== BRW_OPCODE_MOV
);
1264 if (op
== BRW_OPCODE_CMP
)
1265 bld
.CMP(bld
.null_reg_f(), dest
, zero
, before
);
1267 bld
.MOV(bld
.null_reg_f(), dest
)->conditional_mod
= before
;
1270 bblock_t
*block0
= v
->cfg
->blocks
[0];
1272 EXPECT_EQ(0, block0
->start_ip
);
1273 EXPECT_EQ(1, block0
->end_ip
);
1275 EXPECT_FALSE(cmod_propagation(v
));
1276 EXPECT_EQ(0, block0
->start_ip
);
1277 EXPECT_EQ(1, block0
->end_ip
);
1278 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1279 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
1280 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1281 EXPECT_EQ(op
, instruction(block0
, 1)->opcode
);
1282 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
1283 EXPECT_EQ(before
, instruction(block0
, 1)->conditional_mod
);
1287 cmod_propagation_test::test_negative_int_saturate_prop(enum brw_conditional_mod before
,
1290 const fs_builder
&bld
= v
->bld
;
1291 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
1292 fs_reg src0
= v
->vgrf(glsl_type::int_type
);
1293 fs_reg src1
= v
->vgrf(glsl_type::int_type
);
1294 fs_reg
zero(brw_imm_d(0));
1295 bld
.ADD(dest
, src0
, src1
)->saturate
= true;
1297 assert(op
== BRW_OPCODE_CMP
|| op
== BRW_OPCODE_MOV
);
1298 if (op
== BRW_OPCODE_CMP
)
1299 bld
.CMP(bld
.null_reg_d(), dest
, zero
, before
);
1301 bld
.MOV(bld
.null_reg_d(), dest
)->conditional_mod
= before
;
1304 bblock_t
*block0
= v
->cfg
->blocks
[0];
1306 EXPECT_EQ(0, block0
->start_ip
);
1307 EXPECT_EQ(1, block0
->end_ip
);
1309 EXPECT_FALSE(cmod_propagation(v
));
1310 EXPECT_EQ(0, block0
->start_ip
);
1311 EXPECT_EQ(1, block0
->end_ip
);
1312 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1313 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
1314 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1315 EXPECT_EQ(op
, instruction(block0
, 1)->opcode
);
1316 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
1317 EXPECT_EQ(before
, instruction(block0
, 1)->conditional_mod
);
1320 TEST_F(cmod_propagation_test
, float_saturate_nz_cmp
)
1322 /* With the saturate modifier, the comparison happens before clamping to
1323 * [0, 1]. (sat(x) != 0) == (x > 0).
1327 * 0: add.sat(8) dest src0 src1
1328 * 1: cmp.nz.f0(8) null dest 0.0f
1331 * 0: add.sat.g.f0(8) dest src0 src1
1333 test_positive_float_saturate_prop(BRW_CONDITIONAL_NZ
, BRW_CONDITIONAL_G
,
1337 TEST_F(cmod_propagation_test
, float_saturate_nz_mov
)
1339 /* With the saturate modifier, the comparison happens before clamping to
1340 * [0, 1]. (sat(x) != 0) == (x > 0).
1344 * 0: add.sat(8) dest src0 src1
1345 * 1: mov.nz.f0(8) null dest
1348 * 0: add.sat.g.f0(8) dest src0 src1
1350 test_positive_float_saturate_prop(BRW_CONDITIONAL_NZ
, BRW_CONDITIONAL_G
,
1354 TEST_F(cmod_propagation_test
, float_saturate_z_cmp
)
1356 /* With the saturate modifier, the comparison happens before clamping to
1357 * [0, 1]. (sat(x) == 0) == (x <= 0).
1361 * 0: add.sat(8) dest src0 src1
1362 * 1: cmp.z.f0(8) null dest 0.0f
1365 * 0: add.sat.le.f0(8) dest src0 src1
1367 test_positive_float_saturate_prop(BRW_CONDITIONAL_Z
, BRW_CONDITIONAL_LE
,
1371 TEST_F(cmod_propagation_test
, float_saturate_z_mov
)
1373 /* With the saturate modifier, the comparison happens before clamping to
1374 * [0, 1]. (sat(x) == 0) == (x <= 0).
1378 * 0: add.sat(8) dest src0 src1
1379 * 1: mov.z.f0(8) null dest
1382 * 0: add.sat.le.f0(8) dest src0 src1
1385 /* cmod propagation bails on every MOV except MOV.NZ. */
1386 test_negative_float_saturate_prop(BRW_CONDITIONAL_Z
, BRW_OPCODE_MOV
);
1388 test_positive_float_saturate_prop(BRW_CONDITIONAL_Z
, BRW_CONDITIONAL_LE
,
1393 TEST_F(cmod_propagation_test
, float_saturate_g_cmp
)
1395 /* With the saturate modifier, the comparison happens before clamping to
1396 * [0, 1]. (sat(x) > 0) == (x > 0).
1400 * 0: add.sat(8) dest src0 src1
1401 * 1: cmp.g.f0(8) null dest 0.0f
1404 * 0: add.sat.g.f0(8) dest src0 src1
1406 test_positive_float_saturate_prop(BRW_CONDITIONAL_G
, BRW_CONDITIONAL_G
,
1410 TEST_F(cmod_propagation_test
, float_saturate_g_mov
)
1412 /* With the saturate modifier, the comparison happens before clamping to
1413 * [0, 1]. (sat(x) > 0) == (x > 0).
1417 * 0: add.sat(8) dest src0 src1
1418 * 1: mov.g.f0(8) null dest
1421 * 0: add.sat.g.f0(8) dest src0 src1
1424 /* cmod propagation bails on every MOV except MOV.NZ. */
1425 test_negative_float_saturate_prop(BRW_CONDITIONAL_G
, BRW_OPCODE_MOV
);
1427 test_positive_float_saturate_prop(BRW_CONDITIONAL_G
, BRW_CONDITIONAL_G
,
1432 TEST_F(cmod_propagation_test
, float_saturate_le_cmp
)
1434 /* With the saturate modifier, the comparison happens before clamping to
1435 * [0, 1]. (sat(x) <= 0) == (x <= 0).
1439 * 0: add.sat(8) dest src0 src1
1440 * 1: cmp.le.f0(8) null dest 0.0f
1443 * 0: add.sat.le.f0(8) dest src0 src1
1445 test_positive_float_saturate_prop(BRW_CONDITIONAL_LE
, BRW_CONDITIONAL_LE
,
1449 TEST_F(cmod_propagation_test
, float_saturate_le_mov
)
1451 /* With the saturate modifier, the comparison happens before clamping to
1452 * [0, 1]. (sat(x) <= 0) == (x <= 0).
1456 * 0: add.sat(8) dest src0 src1
1457 * 1: mov.le.f0(8) null dest
1460 * 0: add.sat.le.f0(8) dest src0 src1
1463 /* cmod propagation bails on every MOV except MOV.NZ. */
1464 test_negative_float_saturate_prop(BRW_CONDITIONAL_LE
, BRW_OPCODE_MOV
);
1466 test_positive_float_saturate_prop(BRW_CONDITIONAL_LE
, BRW_CONDITIONAL_LE
,
1471 TEST_F(cmod_propagation_test
, float_saturate_l_cmp
)
1473 /* With the saturate modifier, the comparison happens before clamping to
1474 * [0, 1]. There is no before / after equivalence for (sat(x) < 0).
1478 * 0: add.sat(8) dest src0 src1
1479 * 1: cmp.l.f0(8) null dest 0.0f
1484 test_negative_float_saturate_prop(BRW_CONDITIONAL_L
, BRW_OPCODE_CMP
);
1488 TEST_F(cmod_propagation_test
, float_saturate_l_mov
)
1490 /* With the saturate modifier, the comparison happens before clamping to
1491 * [0, 1]. There is no before / after equivalence for (sat(x) < 0).
1495 * 0: add.sat(8) dest src0 src1
1496 * 1: mov.l.f0(8) null dest 0.0f
1501 test_negative_float_saturate_prop(BRW_CONDITIONAL_L
, BRW_OPCODE_MOV
);
1505 TEST_F(cmod_propagation_test
, float_saturate_ge_cmp
)
1507 /* With the saturate modifier, the comparison happens before clamping to
1508 * [0, 1]. There is no before / after equivalence for (sat(x) >= 0).
1512 * 0: add.sat(8) dest src0 src1
1513 * 1: cmp.ge.f0(8) null dest 0.0f
1518 test_negative_float_saturate_prop(BRW_CONDITIONAL_GE
, BRW_OPCODE_CMP
);
1521 TEST_F(cmod_propagation_test
, float_saturate_ge_mov
)
1523 /* With the saturate modifier, the comparison happens before clamping to
1524 * [0, 1]. There is no before / after equivalence for (sat(x) >= 0).
1528 * 0: add.sat(8) dest src0 src1
1529 * 1: mov.ge.f0(8) null dest 0.0f
1534 test_negative_float_saturate_prop(BRW_CONDITIONAL_GE
, BRW_OPCODE_MOV
);
1537 TEST_F(cmod_propagation_test
, int_saturate_nz_cmp
)
1541 * 0: add.sat(8) dest src0 src1
1542 * 1: cmp.nz.f0(8) null dest 0
1547 test_negative_int_saturate_prop(BRW_CONDITIONAL_NZ
, BRW_OPCODE_CMP
);
1550 TEST_F(cmod_propagation_test
, int_saturate_nz_mov
)
1554 * 0: add.sat(8) dest src0 src1
1555 * 1: mov.nz.f0(8) null dest
1560 test_negative_int_saturate_prop(BRW_CONDITIONAL_NZ
, BRW_OPCODE_MOV
);
1563 TEST_F(cmod_propagation_test
, int_saturate_z_cmp
)
1567 * 0: add.sat(8) dest src0 src1
1568 * 1: cmp.z.f0(8) null dest 0
1573 test_negative_int_saturate_prop(BRW_CONDITIONAL_Z
, BRW_OPCODE_CMP
);
1576 TEST_F(cmod_propagation_test
, int_saturate_z_mov
)
1578 /* With the saturate modifier, the comparison happens before clamping to
1579 * [0, 1]. (sat(x) == 0) == (x <= 0).
1583 * 0: add.sat(8) dest src0 src1
1584 * 1: mov.z.f0(8) null dest
1589 test_negative_int_saturate_prop(BRW_CONDITIONAL_Z
, BRW_OPCODE_MOV
);
1592 TEST_F(cmod_propagation_test
, int_saturate_g_cmp
)
1596 * 0: add.sat(8) dest src0 src1
1597 * 1: cmp.g.f0(8) null dest 0
1602 test_negative_int_saturate_prop(BRW_CONDITIONAL_G
, BRW_OPCODE_CMP
);
1605 TEST_F(cmod_propagation_test
, int_saturate_g_mov
)
1609 * 0: add.sat(8) dest src0 src1
1610 * 1: mov.g.f0(8) null dest
1615 test_negative_int_saturate_prop(BRW_CONDITIONAL_G
, BRW_OPCODE_MOV
);
1618 TEST_F(cmod_propagation_test
, int_saturate_le_cmp
)
1622 * 0: add.sat(8) dest src0 src1
1623 * 1: cmp.le.f0(8) null dest 0
1628 test_negative_int_saturate_prop(BRW_CONDITIONAL_LE
, BRW_OPCODE_CMP
);
1631 TEST_F(cmod_propagation_test
, int_saturate_le_mov
)
1635 * 0: add.sat(8) dest src0 src1
1636 * 1: mov.le.f0(8) null dest
1641 test_negative_int_saturate_prop(BRW_CONDITIONAL_LE
, BRW_OPCODE_MOV
);
1644 TEST_F(cmod_propagation_test
, int_saturate_l_cmp
)
1648 * 0: add.sat(8) dest src0 src1
1649 * 1: cmp.l.f0(8) null dest 0
1654 test_negative_int_saturate_prop(BRW_CONDITIONAL_L
, BRW_OPCODE_CMP
);
1657 TEST_F(cmod_propagation_test
, int_saturate_l_mov
)
1661 * 0: add.sat(8) dest src0 src1
1662 * 1: mov.l.f0(8) null dest 0
1667 test_negative_int_saturate_prop(BRW_CONDITIONAL_L
, BRW_OPCODE_MOV
);
1670 TEST_F(cmod_propagation_test
, int_saturate_ge_cmp
)
1674 * 0: add.sat(8) dest src0 src1
1675 * 1: cmp.ge.f0(8) null dest 0
1680 test_negative_int_saturate_prop(BRW_CONDITIONAL_GE
, BRW_OPCODE_CMP
);
1683 TEST_F(cmod_propagation_test
, int_saturate_ge_mov
)
1687 * 0: add.sat(8) dest src0 src1
1688 * 1: mov.ge.f0(8) null dest
1693 test_negative_int_saturate_prop(BRW_CONDITIONAL_GE
, BRW_OPCODE_MOV
);
1696 TEST_F(cmod_propagation_test
, not_to_or
)
1698 /* Exercise propagation of conditional modifier from a NOT instruction to
1699 * another ALU instruction as performed by cmod_propagate_not.
1701 const fs_builder
&bld
= v
->bld
;
1702 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
1703 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1704 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1705 bld
.OR(dest
, src0
, src1
);
1706 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest
));
1710 * 0: or(8) dest src0 src1
1711 * 1: not.nz.f0(8) null dest
1714 * 0: or.z.f0(8) dest src0 src1
1718 bblock_t
*block0
= v
->cfg
->blocks
[0];
1720 EXPECT_EQ(0, block0
->start_ip
);
1721 EXPECT_EQ(1, block0
->end_ip
);
1723 EXPECT_TRUE(cmod_propagation(v
));
1724 EXPECT_EQ(0, block0
->start_ip
);
1725 EXPECT_EQ(0, block0
->end_ip
);
1726 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
1727 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
1730 TEST_F(cmod_propagation_test
, not_to_and
)
1732 /* Exercise propagation of conditional modifier from a NOT instruction to
1733 * another ALU instruction as performed by cmod_propagate_not.
1735 const fs_builder
&bld
= v
->bld
;
1736 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
1737 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1738 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1739 bld
.AND(dest
, src0
, src1
);
1740 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest
));
1744 * 0: and(8) dest src0 src1
1745 * 1: not.nz.f0(8) null dest
1748 * 0: and.z.f0(8) dest src0 src1
1752 bblock_t
*block0
= v
->cfg
->blocks
[0];
1754 EXPECT_EQ(0, block0
->start_ip
);
1755 EXPECT_EQ(1, block0
->end_ip
);
1757 EXPECT_TRUE(cmod_propagation(v
));
1758 EXPECT_EQ(0, block0
->start_ip
);
1759 EXPECT_EQ(0, block0
->end_ip
);
1760 EXPECT_EQ(BRW_OPCODE_AND
, instruction(block0
, 0)->opcode
);
1761 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
1764 TEST_F(cmod_propagation_test
, not_to_uadd
)
1766 /* Exercise propagation of conditional modifier from a NOT instruction to
1767 * another ALU instruction as performed by cmod_propagate_not.
1769 * The optimization pass currently restricts to just OR and AND. It's
1770 * possible that this is too restrictive, and the actual, necessary
1771 * restriction is just the the destination type of the ALU instruction is
1772 * the same as the source type of the NOT instruction.
1774 const fs_builder
&bld
= v
->bld
;
1775 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
1776 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1777 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1778 bld
.ADD(dest
, src0
, src1
);
1779 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest
));
1783 * 0: add(8) dest src0 src1
1784 * 1: not.nz.f0(8) null dest
1791 bblock_t
*block0
= v
->cfg
->blocks
[0];
1793 EXPECT_EQ(0, block0
->start_ip
);
1794 EXPECT_EQ(1, block0
->end_ip
);
1796 EXPECT_FALSE(cmod_propagation(v
));
1797 EXPECT_EQ(0, block0
->start_ip
);
1798 EXPECT_EQ(1, block0
->end_ip
);
1799 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1800 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1801 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 1)->opcode
);
1802 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 1)->conditional_mod
);
1805 TEST_F(cmod_propagation_test
, not_to_fadd_to_ud
)
1807 /* Exercise propagation of conditional modifier from a NOT instruction to
1808 * another ALU instruction as performed by cmod_propagate_not.
1810 * The optimization pass currently restricts to just OR and AND. It's
1811 * possible that this is too restrictive, and the actual, necessary
1812 * restriction is just the the destination type of the ALU instruction is
1813 * the same as the source type of the NOT instruction.
1815 const fs_builder
&bld
= v
->bld
;
1816 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
1817 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1818 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1819 bld
.ADD(dest
, src0
, src1
);
1820 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest
));
1824 * 0: add(8) dest.ud src0.f src1.f
1825 * 1: not.nz.f0(8) null dest.ud
1832 bblock_t
*block0
= v
->cfg
->blocks
[0];
1834 EXPECT_EQ(0, block0
->start_ip
);
1835 EXPECT_EQ(1, block0
->end_ip
);
1837 EXPECT_FALSE(cmod_propagation(v
));
1838 EXPECT_EQ(0, block0
->start_ip
);
1839 EXPECT_EQ(1, block0
->end_ip
);
1840 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1841 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1842 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 1)->opcode
);
1843 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 1)->conditional_mod
);
1846 TEST_F(cmod_propagation_test
, not_to_fadd
)
1848 /* Exercise propagation of conditional modifier from a NOT instruction to
1849 * another ALU instruction as performed by cmod_propagate_not.
1851 * The optimization pass currently restricts to just OR and AND. It's
1852 * possible that this is too restrictive, and the actual, necessary
1853 * restriction is just the the destination type of the ALU instruction is
1854 * the same as the source type of the NOT instruction.
1856 const fs_builder
&bld
= v
->bld
;
1857 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
1858 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1859 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1860 bld
.ADD(dest
, src0
, src1
);
1861 set_condmod(BRW_CONDITIONAL_NZ
,
1862 bld
.NOT(bld
.null_reg_ud(),
1863 retype(dest
, BRW_REGISTER_TYPE_UD
)));
1867 * 0: add(8) dest.f src0.f src1.f
1868 * 1: not.nz.f0(8) null dest.ud
1875 bblock_t
*block0
= v
->cfg
->blocks
[0];
1877 EXPECT_EQ(0, block0
->start_ip
);
1878 EXPECT_EQ(1, block0
->end_ip
);
1880 EXPECT_FALSE(cmod_propagation(v
));
1881 EXPECT_EQ(0, block0
->start_ip
);
1882 EXPECT_EQ(1, block0
->end_ip
);
1883 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1884 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1885 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 1)->opcode
);
1886 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 1)->conditional_mod
);
1889 TEST_F(cmod_propagation_test
, not_to_or_intervening_flag_read_compatible_value
)
1891 /* Exercise propagation of conditional modifier from a NOT instruction to
1892 * another ALU instruction as performed by cmod_propagate_not.
1894 const fs_builder
&bld
= v
->bld
;
1895 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
1896 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1897 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1898 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1899 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
1900 fs_reg
zero(brw_imm_f(0.0f
));
1901 set_condmod(BRW_CONDITIONAL_Z
, bld
.OR(dest0
, src0
, src1
));
1902 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
));
1903 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
1907 * 0: or.z.f0(8) dest0 src0 src1
1908 * 1: (+f0) sel(8) dest1 src2 0.0f
1909 * 2: not.nz.f0(8) null dest0
1912 * 0: or.z.f0(8) dest0 src0 src1
1913 * 1: (+f0) sel(8) dest1 src2 0.0f
1917 bblock_t
*block0
= v
->cfg
->blocks
[0];
1919 EXPECT_EQ(0, block0
->start_ip
);
1920 EXPECT_EQ(2, block0
->end_ip
);
1922 EXPECT_TRUE(cmod_propagation(v
));
1923 EXPECT_EQ(0, block0
->start_ip
);
1924 EXPECT_EQ(1, block0
->end_ip
);
1925 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
1926 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
1927 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
1928 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1931 TEST_F(cmod_propagation_test
,
1932 not_to_or_intervening_flag_read_compatible_value_mismatch_flag
)
1934 /* Exercise propagation of conditional modifier from a NOT instruction to
1935 * another ALU instruction as performed by cmod_propagate_not.
1937 const fs_builder
&bld
= v
->bld
;
1938 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
1939 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1940 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1941 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1942 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
1943 fs_reg
zero(brw_imm_f(0.0f
));
1944 set_condmod(BRW_CONDITIONAL_Z
, bld
.OR(dest0
, src0
, src1
))
1946 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
));
1947 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
1951 * 0: or.z.f0.1(8) dest0 src0 src1
1952 * 1: (+f0) sel(8) dest1 src2 0.0f
1953 * 2: not.nz.f0(8) null dest0
1960 bblock_t
*block0
= v
->cfg
->blocks
[0];
1962 EXPECT_EQ(0, block0
->start_ip
);
1963 EXPECT_EQ(2, block0
->end_ip
);
1965 EXPECT_FALSE(cmod_propagation(v
));
1966 EXPECT_EQ(0, block0
->start_ip
);
1967 EXPECT_EQ(2, block0
->end_ip
);
1968 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
1969 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
1970 EXPECT_EQ(1, instruction(block0
, 0)->flag_subreg
);
1971 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
1972 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1973 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 2)->opcode
);
1974 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 2)->conditional_mod
);
1975 EXPECT_EQ(0, instruction(block0
, 2)->flag_subreg
);
1978 TEST_F(cmod_propagation_test
, not_to_or_intervening_flag_read_incompatible_value
)
1980 /* Exercise propagation of conditional modifier from a NOT instruction to
1981 * another ALU instruction as performed by cmod_propagate_not.
1983 const fs_builder
&bld
= v
->bld
;
1984 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
1985 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1986 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1987 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1988 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
1989 fs_reg
zero(brw_imm_f(0.0f
));
1990 set_condmod(BRW_CONDITIONAL_NZ
, bld
.OR(dest0
, src0
, src1
));
1991 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
));
1992 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
1996 * 0: or.nz.f0(8) dest0 src0 src1
1997 * 1: (+f0) sel(8) dest1 src2 0.0f
1998 * 2: not.nz.f0(8) null dest0
2005 bblock_t
*block0
= v
->cfg
->blocks
[0];
2007 EXPECT_EQ(0, block0
->start_ip
);
2008 EXPECT_EQ(2, block0
->end_ip
);
2010 EXPECT_FALSE(cmod_propagation(v
));
2011 EXPECT_EQ(0, block0
->start_ip
);
2012 EXPECT_EQ(2, block0
->end_ip
);
2013 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
2014 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 0)->conditional_mod
);
2015 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
2016 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
2017 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 2)->opcode
);
2018 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 2)->conditional_mod
);
2021 TEST_F(cmod_propagation_test
, not_to_or_intervening_mismatch_flag_write
)
2023 /* Exercise propagation of conditional modifier from a NOT instruction to
2024 * another ALU instruction as performed by cmod_propagate_not.
2026 const fs_builder
&bld
= v
->bld
;
2027 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
2028 fs_reg dest1
= v
->vgrf(glsl_type::uint_type
);
2029 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
2030 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
2032 bld
.OR(dest0
, src0
, src1
);
2033 set_condmod(BRW_CONDITIONAL_Z
, bld
.OR(dest1
, src0
, src1
))
2035 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
2039 * 0: or(8) dest0 src0 src1
2040 * 1: or.z.f0.1(8) dest1 src0 src1
2041 * 2: not.nz.f0(8) null dest0
2044 * 0: or.z.f0(8) dest0 src0 src1
2045 * 1: or.z.f0.1(8) dest1 src0 src1
2049 bblock_t
*block0
= v
->cfg
->blocks
[0];
2051 EXPECT_EQ(0, block0
->start_ip
);
2052 EXPECT_EQ(2, block0
->end_ip
);
2054 EXPECT_TRUE(cmod_propagation(v
));
2055 EXPECT_EQ(0, block0
->start_ip
);
2056 EXPECT_EQ(1, block0
->end_ip
);
2057 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
2058 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
2059 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
2060 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 1)->opcode
);
2061 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 1)->conditional_mod
);
2062 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
2065 TEST_F(cmod_propagation_test
, not_to_or_intervening_mismatch_flag_read
)
2067 /* Exercise propagation of conditional modifier from a NOT instruction to
2068 * another ALU instruction as performed by cmod_propagate_not.
2070 const fs_builder
&bld
= v
->bld
;
2071 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
2072 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
2073 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
2074 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
2075 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
2076 fs_reg
zero(brw_imm_f(0.0f
));
2078 bld
.OR(dest0
, src0
, src1
);
2079 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
))
2081 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
2085 * 0: or(8) dest0 src0 src1
2086 * 1: (+f0.1) sel(8) dest1 src2 0.0f
2087 * 2: not.nz.f0(8) null dest0
2090 * 0: or.z.f0(8) dest0 src0 src1
2091 * 1: (+f0.1) sel(8) dest1 src2 0.0f
2095 bblock_t
*block0
= v
->cfg
->blocks
[0];
2097 EXPECT_EQ(0, block0
->start_ip
);
2098 EXPECT_EQ(2, block0
->end_ip
);
2100 EXPECT_TRUE(cmod_propagation(v
));
2101 EXPECT_EQ(0, block0
->start_ip
);
2102 EXPECT_EQ(1, block0
->end_ip
);
2103 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
2104 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
2105 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
2106 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
2107 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
2108 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);