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
, shader
, 8, -1) {}
64 void cmod_propagation_test::SetUp()
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
;
71 prog_data
= ralloc(NULL
, struct brw_wm_prog_data
);
73 nir_shader_create(NULL
, MESA_SHADER_FRAGMENT
, NULL
, NULL
);
75 v
= new cmod_propagation_fs_visitor(compiler
, prog_data
, shader
);
81 instruction(bblock_t
*block
, int num
)
83 fs_inst
*inst
= (fs_inst
*)block
->start();
84 for (int i
= 0; i
< num
; i
++) {
85 inst
= (fs_inst
*)inst
->next
;
91 cmod_propagation(fs_visitor
*v
)
93 const bool print
= getenv("TEST_DEBUG");
96 fprintf(stderr
, "= Before =\n");
100 bool ret
= v
->opt_cmod_propagation();
103 fprintf(stderr
, "\n= After =\n");
110 TEST_F(cmod_propagation_test
, basic
)
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
);
122 * 0: add(8) dest src0 src1
123 * 1: cmp.ge.f0(8) null dest 0.0f
126 * 0: add.ge.f0(8) dest src0 src1
130 bblock_t
*block0
= v
->cfg
->blocks
[0];
132 EXPECT_EQ(0, block0
->start_ip
);
133 EXPECT_EQ(1, block0
->end_ip
);
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
);
142 TEST_F(cmod_propagation_test
, basic_other_flag
)
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
)
155 * 0: add(8) dest src0 src1
156 * 1: cmp.ge.f0.1(8) null dest 0.0f
159 * 0: add.ge.f0.1(8) dest src0 src1
163 bblock_t
*block0
= v
->cfg
->blocks
[0];
165 EXPECT_EQ(0, block0
->start_ip
);
166 EXPECT_EQ(1, block0
->end_ip
);
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
);
176 TEST_F(cmod_propagation_test
, cmp_nonzero
)
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
);
188 * 0: add(8) dest src0 src1
189 * 1: cmp.ge.f0(8) null dest 1.0f
196 bblock_t
*block0
= v
->cfg
->blocks
[0];
198 EXPECT_EQ(0, block0
->start_ip
);
199 EXPECT_EQ(1, block0
->end_ip
);
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
);
209 TEST_F(cmod_propagation_test
, non_cmod_instruction
)
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));
216 bld
.CMP(bld
.null_reg_ud(), dest
, zero
, BRW_CONDITIONAL_GE
);
220 * 0: fbl(8) dest src0
221 * 1: cmp.ge.f0(8) null dest 0u
228 bblock_t
*block0
= v
->cfg
->blocks
[0];
230 EXPECT_EQ(0, block0
->start_ip
);
231 EXPECT_EQ(1, block0
->end_ip
);
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
);
241 TEST_F(cmod_propagation_test
, intervening_flag_write
)
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
);
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
264 bblock_t
*block0
= v
->cfg
->blocks
[0];
266 EXPECT_EQ(0, block0
->start_ip
);
267 EXPECT_EQ(2, block0
->end_ip
);
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
);
279 TEST_F(cmod_propagation_test
, intervening_mismatch_flag_write
)
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
)
290 bld
.CMP(bld
.null_reg_f(), dest
, zero
, BRW_CONDITIONAL_GE
);
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
299 * 0: add.ge.f0(8) dest src0 src1
300 * 1: cmp.ge.f0.1(8) null src2 0.0f
304 bblock_t
*block0
= v
->cfg
->blocks
[0];
306 EXPECT_EQ(0, block0
->start_ip
);
307 EXPECT_EQ(2, block0
->end_ip
);
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
);
320 TEST_F(cmod_propagation_test
, intervening_flag_read
)
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
);
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
344 bblock_t
*block0
= v
->cfg
->blocks
[0];
346 EXPECT_EQ(0, block0
->start_ip
);
347 EXPECT_EQ(2, block0
->end_ip
);
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
);
359 TEST_F(cmod_propagation_test
, intervening_mismatch_flag_read
)
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
))
371 bld
.CMP(bld
.null_reg_f(), dest0
, zero
, BRW_CONDITIONAL_GE
);
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
380 * 0: add.ge.f0(8) dest0 src0 src1
381 * 1: (+f0.1) sel(8) dest1 src2 0.0f
385 bblock_t
*block0
= v
->cfg
->blocks
[0];
387 EXPECT_EQ(0, block0
->start_ip
);
388 EXPECT_EQ(2, block0
->end_ip
);
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
);
401 TEST_F(cmod_propagation_test
, intervening_dest_write
)
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
);
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
425 bblock_t
*block0
= v
->cfg
->blocks
[0];
427 EXPECT_EQ(0, block0
->start_ip
);
428 EXPECT_EQ(2, block0
->end_ip
);
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
);
441 TEST_F(cmod_propagation_test
, intervening_flag_read_same_value
)
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
);
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
461 * 0: add.ge.f0(8) dest0 src0 src1
462 * 1: (+f0) sel(8) dest1 src2 0.0f
466 bblock_t
*block0
= v
->cfg
->blocks
[0];
468 EXPECT_EQ(0, block0
->start_ip
);
469 EXPECT_EQ(2, block0
->end_ip
);
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
);
480 TEST_F(cmod_propagation_test
, negate
)
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
);
489 bld
.CMP(bld
.null_reg_f(), dest
, zero
, BRW_CONDITIONAL_GE
);
493 * 0: add(8) dest src0 src1
494 * 1: cmp.ge.f0(8) null -dest 0.0f
497 * 0: add.le.f0(8) dest src0 src1
501 bblock_t
*block0
= v
->cfg
->blocks
[0];
503 EXPECT_EQ(0, block0
->start_ip
);
504 EXPECT_EQ(1, block0
->end_ip
);
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
);
513 TEST_F(cmod_propagation_test
, movnz
)
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
));
525 * 0: cmp.ge.f0(8) dest src0 src1
526 * 1: mov.nz.f0(8) null dest
529 * 0: cmp.ge.f0(8) dest src0 src1
533 bblock_t
*block0
= v
->cfg
->blocks
[0];
535 EXPECT_EQ(0, block0
->start_ip
);
536 EXPECT_EQ(1, block0
->end_ip
);
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
);
545 TEST_F(cmod_propagation_test
, different_types_cmod_with_zero
)
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
,
558 * 0: add(8) dest:D src0:D src1:D
559 * 1: cmp.ge.f0(8) null:F dest:F 0.0f
566 bblock_t
*block0
= v
->cfg
->blocks
[0];
568 EXPECT_EQ(0, block0
->start_ip
);
569 EXPECT_EQ(1, block0
->end_ip
);
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
);
579 TEST_F(cmod_propagation_test
, andnz_one
)
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));
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
));
592 * 0: cmp.l.f0(8) dest:F src0:F 0F
593 * 1: and.nz.f0(8) null:D dest:D 1D
596 * 0: cmp.l.f0(8) dest:F src0:F 0F
600 bblock_t
*block0
= v
->cfg
->blocks
[0];
602 EXPECT_EQ(0, block0
->start_ip
);
603 EXPECT_EQ(1, block0
->end_ip
);
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
));
614 TEST_F(cmod_propagation_test
, andnz_non_one
)
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));
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
));
627 * 0: cmp.l.f0(8) dest:F src0:F 0F
628 * 1: and.nz.f0(8) null:D dest:D 38D
635 bblock_t
*block0
= v
->cfg
->blocks
[0];
637 EXPECT_EQ(0, block0
->start_ip
);
638 EXPECT_EQ(1, block0
->end_ip
);
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
);
649 TEST_F(cmod_propagation_test
, andz_one
)
651 const fs_builder
&bld
= v
->bld
;
652 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
653 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
654 fs_reg
zero(brw_imm_f(0.0f
));
655 fs_reg
one(brw_imm_d(1));
657 bld
.CMP(retype(dest
, BRW_REGISTER_TYPE_F
), src0
, zero
, BRW_CONDITIONAL_L
);
658 set_condmod(BRW_CONDITIONAL_Z
,
659 bld
.AND(bld
.null_reg_d(), dest
, one
));
662 * 0: cmp.l.f0(8) dest:F src0:F 0F
663 * 1: and.z.f0(8) null:D dest:D 1D
670 bblock_t
*block0
= v
->cfg
->blocks
[0];
672 EXPECT_EQ(0, block0
->start_ip
);
673 EXPECT_EQ(1, block0
->end_ip
);
675 EXPECT_FALSE(cmod_propagation(v
));
676 EXPECT_EQ(0, block0
->start_ip
);
677 EXPECT_EQ(1, block0
->end_ip
);
678 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 0)->opcode
);
679 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
680 EXPECT_EQ(BRW_OPCODE_AND
, instruction(block0
, 1)->opcode
);
681 EXPECT_EQ(BRW_CONDITIONAL_EQ
, instruction(block0
, 1)->conditional_mod
);
684 TEST_F(cmod_propagation_test
, add_not_merge_with_compare
)
686 const fs_builder
&bld
= v
->bld
;
687 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
688 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
689 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
690 bld
.ADD(dest
, src0
, src1
);
691 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
693 /* The addition and the implicit subtraction in the compare do not compute
697 * 0: add(8) dest:F src0:F src1:F
698 * 1: cmp.l.f0(8) null:F src0:F src1:F
704 bblock_t
*block0
= v
->cfg
->blocks
[0];
706 EXPECT_EQ(0, block0
->start_ip
);
707 EXPECT_EQ(1, block0
->end_ip
);
709 EXPECT_FALSE(cmod_propagation(v
));
710 EXPECT_EQ(0, block0
->start_ip
);
711 EXPECT_EQ(1, block0
->end_ip
);
712 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
713 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
714 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
715 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 1)->conditional_mod
);
718 TEST_F(cmod_propagation_test
, subtract_merge_with_compare
)
720 const fs_builder
&bld
= v
->bld
;
721 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
722 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
723 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
724 bld
.ADD(dest
, src0
, negate(src1
));
725 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
728 * 0: add(8) dest:F src0:F -src1:F
729 * 1: cmp.l.f0(8) null:F src0:F src1:F
732 * 0: add.l.f0(8) dest:F src0:F -src1:F
735 bblock_t
*block0
= v
->cfg
->blocks
[0];
737 EXPECT_EQ(0, block0
->start_ip
);
738 EXPECT_EQ(1, block0
->end_ip
);
740 EXPECT_TRUE(cmod_propagation(v
));
741 EXPECT_EQ(0, block0
->start_ip
);
742 EXPECT_EQ(0, block0
->end_ip
);
743 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
744 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
747 TEST_F(cmod_propagation_test
, subtract_immediate_merge_with_compare
)
749 const fs_builder
&bld
= v
->bld
;
750 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
751 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
752 fs_reg
one(brw_imm_f(1.0f
));
753 fs_reg
negative_one(brw_imm_f(-1.0f
));
755 bld
.ADD(dest
, src0
, negative_one
);
756 bld
.CMP(bld
.null_reg_f(), src0
, one
, BRW_CONDITIONAL_NZ
);
759 * 0: add(8) dest:F src0:F -1.0f
760 * 1: cmp.nz.f0(8) null:F src0:F 1.0f
763 * 0: add.nz.f0(8) dest:F src0:F -1.0f
766 bblock_t
*block0
= v
->cfg
->blocks
[0];
768 EXPECT_EQ(0, block0
->start_ip
);
769 EXPECT_EQ(1, block0
->end_ip
);
771 EXPECT_TRUE(cmod_propagation(v
));
772 EXPECT_EQ(0, block0
->start_ip
);
773 EXPECT_EQ(0, block0
->end_ip
);
774 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
775 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 0)->conditional_mod
);
778 TEST_F(cmod_propagation_test
, subtract_merge_with_compare_intervening_add
)
780 const fs_builder
&bld
= v
->bld
;
781 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
782 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
783 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
784 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
785 bld
.ADD(dest0
, src0
, negate(src1
));
786 bld
.ADD(dest1
, src0
, src1
);
787 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
790 * 0: add(8) dest0:F src0:F -src1:F
791 * 1: add(8) dest1:F src0:F src1:F
792 * 2: cmp.l.f0(8) null:F src0:F src1:F
795 * 0: add.l.f0(8) dest0:F src0:F -src1:F
796 * 1: add(8) dest1:F src0:F src1:F
799 bblock_t
*block0
= v
->cfg
->blocks
[0];
801 EXPECT_EQ(0, block0
->start_ip
);
802 EXPECT_EQ(2, block0
->end_ip
);
804 EXPECT_TRUE(cmod_propagation(v
));
805 EXPECT_EQ(0, block0
->start_ip
);
806 EXPECT_EQ(1, block0
->end_ip
);
807 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
808 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
809 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 1)->opcode
);
810 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 1)->conditional_mod
);
813 TEST_F(cmod_propagation_test
, subtract_not_merge_with_compare_intervening_partial_write
)
815 const fs_builder
&bld
= v
->bld
;
816 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
817 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
818 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
819 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
820 bld
.ADD(dest0
, src0
, negate(src1
));
821 set_predicate(BRW_PREDICATE_NORMAL
, bld
.ADD(dest1
, src0
, negate(src1
)));
822 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
825 * 0: add(8) dest0:F src0:F -src1:F
826 * 1: (+f0) add(8) dest1:F src0:F -src1:F
827 * 2: cmp.l.f0(8) null:F src0:F src1:F
833 bblock_t
*block0
= v
->cfg
->blocks
[0];
835 EXPECT_EQ(0, block0
->start_ip
);
836 EXPECT_EQ(2, block0
->end_ip
);
838 EXPECT_FALSE(cmod_propagation(v
));
839 EXPECT_EQ(0, block0
->start_ip
);
840 EXPECT_EQ(2, block0
->end_ip
);
841 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
842 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
843 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 1)->opcode
);
844 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 1)->conditional_mod
);
845 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
846 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 2)->conditional_mod
);
849 TEST_F(cmod_propagation_test
, subtract_not_merge_with_compare_intervening_add
)
851 const fs_builder
&bld
= v
->bld
;
852 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
853 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
854 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
855 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
856 bld
.ADD(dest0
, src0
, negate(src1
));
857 set_condmod(BRW_CONDITIONAL_EQ
, bld
.ADD(dest1
, src0
, src1
));
858 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
861 * 0: add(8) dest0:F src0:F -src1:F
862 * 1: add.z.f0(8) dest1:F src0:F src1:F
863 * 2: cmp.l.f0(8) null:F src0:F src1:F
869 bblock_t
*block0
= v
->cfg
->blocks
[0];
871 EXPECT_EQ(0, block0
->start_ip
);
872 EXPECT_EQ(2, block0
->end_ip
);
874 EXPECT_FALSE(cmod_propagation(v
));
875 EXPECT_EQ(0, block0
->start_ip
);
876 EXPECT_EQ(2, block0
->end_ip
);
877 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
878 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
879 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 1)->opcode
);
880 EXPECT_EQ(BRW_CONDITIONAL_EQ
, instruction(block0
, 1)->conditional_mod
);
881 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
882 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 2)->conditional_mod
);
885 TEST_F(cmod_propagation_test
, add_merge_with_compare
)
887 const fs_builder
&bld
= v
->bld
;
888 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
889 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
890 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
891 bld
.ADD(dest
, src0
, src1
);
892 bld
.CMP(bld
.null_reg_f(), src0
, negate(src1
), BRW_CONDITIONAL_L
);
895 * 0: add(8) dest:F src0:F src1:F
896 * 1: cmp.l.f0(8) null:F src0:F -src1:F
899 * 0: add.l.f0(8) dest:F src0:F src1:F
902 bblock_t
*block0
= v
->cfg
->blocks
[0];
904 EXPECT_EQ(0, block0
->start_ip
);
905 EXPECT_EQ(1, block0
->end_ip
);
907 EXPECT_TRUE(cmod_propagation(v
));
908 EXPECT_EQ(0, block0
->start_ip
);
909 EXPECT_EQ(0, block0
->end_ip
);
910 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
911 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
914 TEST_F(cmod_propagation_test
, negative_subtract_merge_with_compare
)
916 const fs_builder
&bld
= v
->bld
;
917 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
918 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
919 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
920 bld
.ADD(dest
, src1
, negate(src0
));
921 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
923 /* The result of the subtract is the negatiion of the result of the
924 * implicit subtract in the compare, so the condition must change.
927 * 0: add(8) dest:F src1:F -src0:F
928 * 1: cmp.l.f0(8) null:F src0:F src1:F
931 * 0: add.g.f0(8) dest:F src0:F -src1:F
934 bblock_t
*block0
= v
->cfg
->blocks
[0];
936 EXPECT_EQ(0, block0
->start_ip
);
937 EXPECT_EQ(1, block0
->end_ip
);
939 EXPECT_TRUE(cmod_propagation(v
));
940 EXPECT_EQ(0, block0
->start_ip
);
941 EXPECT_EQ(0, block0
->end_ip
);
942 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
943 EXPECT_EQ(BRW_CONDITIONAL_G
, instruction(block0
, 0)->conditional_mod
);
946 TEST_F(cmod_propagation_test
, subtract_delete_compare
)
948 const fs_builder
&bld
= v
->bld
;
949 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
950 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
951 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
952 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
953 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
955 set_condmod(BRW_CONDITIONAL_L
, bld
.ADD(dest
, src0
, negate(src1
)));
956 set_predicate(BRW_PREDICATE_NORMAL
, bld
.MOV(dest1
, src2
));
957 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
960 * 0: add.l.f0(8) dest0:F src0:F -src1:F
961 * 1: (+f0) mov(0) dest1:F src2:F
962 * 2: cmp.l.f0(8) null:F src0:F src1:F
965 * 0: add.l.f0(8) dest:F src0:F -src1:F
966 * 1: (+f0) mov(0) dest1:F src2:F
969 bblock_t
*block0
= v
->cfg
->blocks
[0];
971 EXPECT_EQ(0, block0
->start_ip
);
972 EXPECT_EQ(2, block0
->end_ip
);
974 EXPECT_TRUE(cmod_propagation(v
));
975 EXPECT_EQ(0, block0
->start_ip
);
976 EXPECT_EQ(1, block0
->end_ip
);
977 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
978 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
979 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
980 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
983 TEST_F(cmod_propagation_test
, subtract_delete_compare_other_flag
)
985 /* This test is the same as subtract_delete_compare but it explicitly used
986 * flag f0.1 for the subtraction and the comparison.
988 const fs_builder
&bld
= v
->bld
;
989 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
990 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
991 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
992 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
993 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
995 set_condmod(BRW_CONDITIONAL_L
, bld
.ADD(dest
, src0
, negate(src1
)))
997 set_predicate(BRW_PREDICATE_NORMAL
, bld
.MOV(dest1
, src2
));
998 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
)
1002 * 0: add.l.f0.1(8) dest0:F src0:F -src1:F
1003 * 1: (+f0) mov(0) dest1:F src2:F
1004 * 2: cmp.l.f0.1(8) null:F src0:F src1:F
1007 * 0: add.l.f0.1(8) dest:F src0:F -src1:F
1008 * 1: (+f0) mov(0) dest1:F src2:F
1011 bblock_t
*block0
= v
->cfg
->blocks
[0];
1013 EXPECT_EQ(0, block0
->start_ip
);
1014 EXPECT_EQ(2, block0
->end_ip
);
1016 EXPECT_TRUE(cmod_propagation(v
));
1017 EXPECT_EQ(0, block0
->start_ip
);
1018 EXPECT_EQ(1, block0
->end_ip
);
1019 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1020 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1021 EXPECT_EQ(1, instruction(block0
, 0)->flag_subreg
);
1022 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
1023 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1026 TEST_F(cmod_propagation_test
, subtract_to_mismatch_flag
)
1028 const fs_builder
&bld
= v
->bld
;
1029 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
1030 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1031 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1033 set_condmod(BRW_CONDITIONAL_L
, bld
.ADD(dest
, src0
, negate(src1
)));
1034 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
)
1038 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1039 * 1: cmp.l.f0.1(8) null:F src0:F src1:F
1045 bblock_t
*block0
= v
->cfg
->blocks
[0];
1047 EXPECT_EQ(0, block0
->start_ip
);
1048 EXPECT_EQ(1, block0
->end_ip
);
1050 EXPECT_FALSE(cmod_propagation(v
));
1051 EXPECT_EQ(0, block0
->start_ip
);
1052 EXPECT_EQ(1, block0
->end_ip
);
1053 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1054 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1055 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
1056 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
1057 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 1)->conditional_mod
);
1058 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
1061 TEST_F(cmod_propagation_test
,
1062 subtract_merge_with_compare_intervening_mismatch_flag_write
)
1064 const fs_builder
&bld
= v
->bld
;
1065 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
1066 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1067 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1069 bld
.ADD(dest0
, src0
, negate(src1
));
1070 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
)
1072 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
1075 * 0: add(8) dest0:F src0:F -src1:F
1076 * 1: cmp.l.f0.1(8) null:F src0:F src1:F
1077 * 2: cmp.l.f0(8) null:F src0:F src1:F
1080 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1081 * 1: cmp.l.f0.1(8) null:F src0:F src1:F
1083 * NOTE: Another perfectly valid after sequence would be:
1085 * 0: add.f0.1(8) dest0:F src0:F -src1:F
1086 * 1: cmp.l.f0(8) null:F src0:F src1:F
1088 * However, the optimization pass starts at the end of the basic block.
1089 * Because of this, the cmp.l.f0 will always be chosen. If the pass
1090 * changes its strategy, this test will also need to change.
1093 bblock_t
*block0
= v
->cfg
->blocks
[0];
1095 EXPECT_EQ(0, block0
->start_ip
);
1096 EXPECT_EQ(2, block0
->end_ip
);
1098 EXPECT_TRUE(cmod_propagation(v
));
1099 EXPECT_EQ(0, block0
->start_ip
);
1100 EXPECT_EQ(1, block0
->end_ip
);
1101 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1102 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1103 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
1104 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
1105 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 1)->conditional_mod
);
1106 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
1109 TEST_F(cmod_propagation_test
,
1110 subtract_merge_with_compare_intervening_mismatch_flag_read
)
1112 const fs_builder
&bld
= v
->bld
;
1113 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
1114 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1115 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1116 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1117 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
1118 fs_reg
zero(brw_imm_f(0.0f
));
1120 bld
.ADD(dest0
, src0
, negate(src1
));
1121 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
))
1123 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
1126 * 0: add(8) dest0:F src0:F -src1:F
1127 * 1: (+f0.1) sel(8) dest1 src2 0.0f
1128 * 2: cmp.l.f0(8) null:F src0:F src1:F
1131 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1132 * 1: (+f0.1) sel(8) dest1 src2 0.0f
1135 bblock_t
*block0
= v
->cfg
->blocks
[0];
1137 EXPECT_EQ(0, block0
->start_ip
);
1138 EXPECT_EQ(2, block0
->end_ip
);
1140 EXPECT_TRUE(cmod_propagation(v
));
1141 EXPECT_EQ(0, block0
->start_ip
);
1142 EXPECT_EQ(1, block0
->end_ip
);
1143 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1144 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1145 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
1146 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
1147 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1148 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
1151 TEST_F(cmod_propagation_test
, subtract_delete_compare_derp
)
1153 const fs_builder
&bld
= v
->bld
;
1154 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
1155 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1156 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1157 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1159 set_condmod(BRW_CONDITIONAL_L
, bld
.ADD(dest0
, src0
, negate(src1
)));
1160 set_predicate(BRW_PREDICATE_NORMAL
, bld
.ADD(dest1
, negate(src0
), src1
));
1161 bld
.CMP(bld
.null_reg_f(), src0
, src1
, BRW_CONDITIONAL_L
);
1164 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1165 * 1: (+f0) add(0) dest1:F -src0:F src1:F
1166 * 2: cmp.l.f0(8) null:F src0:F src1:F
1169 * 0: add.l.f0(8) dest0:F src0:F -src1:F
1170 * 1: (+f0) add(0) dest1:F -src0:F src1:F
1173 bblock_t
*block0
= v
->cfg
->blocks
[0];
1175 EXPECT_EQ(0, block0
->start_ip
);
1176 EXPECT_EQ(2, block0
->end_ip
);
1178 EXPECT_TRUE(cmod_propagation(v
));
1179 EXPECT_EQ(0, block0
->start_ip
);
1180 EXPECT_EQ(1, block0
->end_ip
);
1181 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1182 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
1183 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 1)->opcode
);
1184 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1187 TEST_F(cmod_propagation_test
, signed_unsigned_comparison_mismatch
)
1189 const fs_builder
&bld
= v
->bld
;
1190 fs_reg dest0
= v
->vgrf(glsl_type::int_type
);
1191 fs_reg src0
= v
->vgrf(glsl_type::int_type
);
1192 src0
.type
= BRW_REGISTER_TYPE_W
;
1194 bld
.ASR(dest0
, negate(src0
), brw_imm_d(15));
1195 bld
.CMP(bld
.null_reg_ud(), retype(dest0
, BRW_REGISTER_TYPE_UD
),
1196 brw_imm_ud(0u), BRW_CONDITIONAL_LE
);
1199 * 0: asr(8) dest:D -src0:W 15D
1200 * 1: cmp.le.f0(8) null:UD dest:UD 0UD
1206 bblock_t
*block0
= v
->cfg
->blocks
[0];
1208 EXPECT_EQ(0, block0
->start_ip
);
1209 EXPECT_EQ(1, block0
->end_ip
);
1211 EXPECT_FALSE(cmod_propagation(v
));
1212 EXPECT_EQ(0, block0
->start_ip
);
1213 EXPECT_EQ(1, block0
->end_ip
);
1214 EXPECT_EQ(BRW_OPCODE_ASR
, instruction(block0
, 0)->opcode
);
1215 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
1216 EXPECT_EQ(BRW_CONDITIONAL_LE
, instruction(block0
, 1)->conditional_mod
);
1220 cmod_propagation_test::test_positive_float_saturate_prop(enum brw_conditional_mod before
,
1221 enum brw_conditional_mod after
,
1224 const fs_builder
&bld
= v
->bld
;
1225 fs_reg dest
= 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
zero(brw_imm_f(0.0f
));
1229 bld
.ADD(dest
, src0
, src1
)->saturate
= true;
1231 assert(op
== BRW_OPCODE_CMP
|| op
== BRW_OPCODE_MOV
);
1232 if (op
== BRW_OPCODE_CMP
)
1233 bld
.CMP(bld
.null_reg_f(), dest
, zero
, before
);
1235 bld
.MOV(bld
.null_reg_f(), dest
)->conditional_mod
= before
;
1238 bblock_t
*block0
= v
->cfg
->blocks
[0];
1240 EXPECT_EQ(0, block0
->start_ip
);
1241 EXPECT_EQ(1, block0
->end_ip
);
1243 EXPECT_TRUE(cmod_propagation(v
));
1244 EXPECT_EQ(0, block0
->start_ip
);
1245 EXPECT_EQ(0, block0
->end_ip
);
1246 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1247 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
1248 EXPECT_EQ(after
, instruction(block0
, 0)->conditional_mod
);
1252 cmod_propagation_test::test_negative_float_saturate_prop(enum brw_conditional_mod before
,
1255 const fs_builder
&bld
= v
->bld
;
1256 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
1257 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1258 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1259 fs_reg
zero(brw_imm_f(0.0f
));
1260 bld
.ADD(dest
, src0
, src1
)->saturate
= true;
1262 assert(op
== BRW_OPCODE_CMP
|| op
== BRW_OPCODE_MOV
);
1263 if (op
== BRW_OPCODE_CMP
)
1264 bld
.CMP(bld
.null_reg_f(), dest
, zero
, before
);
1266 bld
.MOV(bld
.null_reg_f(), dest
)->conditional_mod
= before
;
1269 bblock_t
*block0
= v
->cfg
->blocks
[0];
1271 EXPECT_EQ(0, block0
->start_ip
);
1272 EXPECT_EQ(1, block0
->end_ip
);
1274 EXPECT_FALSE(cmod_propagation(v
));
1275 EXPECT_EQ(0, block0
->start_ip
);
1276 EXPECT_EQ(1, block0
->end_ip
);
1277 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1278 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
1279 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1280 EXPECT_EQ(op
, instruction(block0
, 1)->opcode
);
1281 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
1282 EXPECT_EQ(before
, instruction(block0
, 1)->conditional_mod
);
1286 cmod_propagation_test::test_negative_int_saturate_prop(enum brw_conditional_mod before
,
1289 const fs_builder
&bld
= v
->bld
;
1290 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
1291 fs_reg src0
= v
->vgrf(glsl_type::int_type
);
1292 fs_reg src1
= v
->vgrf(glsl_type::int_type
);
1293 fs_reg
zero(brw_imm_d(0));
1294 bld
.ADD(dest
, src0
, src1
)->saturate
= true;
1296 assert(op
== BRW_OPCODE_CMP
|| op
== BRW_OPCODE_MOV
);
1297 if (op
== BRW_OPCODE_CMP
)
1298 bld
.CMP(bld
.null_reg_d(), dest
, zero
, before
);
1300 bld
.MOV(bld
.null_reg_d(), dest
)->conditional_mod
= before
;
1303 bblock_t
*block0
= v
->cfg
->blocks
[0];
1305 EXPECT_EQ(0, block0
->start_ip
);
1306 EXPECT_EQ(1, block0
->end_ip
);
1308 EXPECT_FALSE(cmod_propagation(v
));
1309 EXPECT_EQ(0, block0
->start_ip
);
1310 EXPECT_EQ(1, block0
->end_ip
);
1311 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1312 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
1313 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1314 EXPECT_EQ(op
, instruction(block0
, 1)->opcode
);
1315 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
1316 EXPECT_EQ(before
, instruction(block0
, 1)->conditional_mod
);
1319 TEST_F(cmod_propagation_test
, float_saturate_nz_cmp
)
1321 /* With the saturate modifier, the comparison happens before clamping to
1322 * [0, 1]. (sat(x) != 0) == (x > 0).
1326 * 0: add.sat(8) dest src0 src1
1327 * 1: cmp.nz.f0(8) null dest 0.0f
1330 * 0: add.sat.g.f0(8) dest src0 src1
1332 test_positive_float_saturate_prop(BRW_CONDITIONAL_NZ
, BRW_CONDITIONAL_G
,
1336 TEST_F(cmod_propagation_test
, float_saturate_nz_mov
)
1338 /* With the saturate modifier, the comparison happens before clamping to
1339 * [0, 1]. (sat(x) != 0) == (x > 0).
1343 * 0: add.sat(8) dest src0 src1
1344 * 1: mov.nz.f0(8) null dest
1347 * 0: add.sat.g.f0(8) dest src0 src1
1349 test_positive_float_saturate_prop(BRW_CONDITIONAL_NZ
, BRW_CONDITIONAL_G
,
1353 TEST_F(cmod_propagation_test
, float_saturate_z_cmp
)
1355 /* With the saturate modifier, the comparison happens before clamping to
1356 * [0, 1]. (sat(x) == 0) == (x <= 0).
1360 * 0: add.sat(8) dest src0 src1
1361 * 1: cmp.z.f0(8) null dest 0.0f
1364 * 0: add.sat.le.f0(8) dest src0 src1
1366 test_positive_float_saturate_prop(BRW_CONDITIONAL_Z
, BRW_CONDITIONAL_LE
,
1370 TEST_F(cmod_propagation_test
, float_saturate_z_mov
)
1372 /* With the saturate modifier, the comparison happens before clamping to
1373 * [0, 1]. (sat(x) == 0) == (x <= 0).
1377 * 0: add.sat(8) dest src0 src1
1378 * 1: mov.z.f0(8) null dest
1381 * 0: add.sat.le.f0(8) dest src0 src1
1384 /* cmod propagation bails on every MOV except MOV.NZ. */
1385 test_negative_float_saturate_prop(BRW_CONDITIONAL_Z
, BRW_OPCODE_MOV
);
1387 test_positive_float_saturate_prop(BRW_CONDITIONAL_Z
, BRW_CONDITIONAL_LE
,
1392 TEST_F(cmod_propagation_test
, float_saturate_g_cmp
)
1394 /* With the saturate modifier, the comparison happens before clamping to
1395 * [0, 1]. (sat(x) > 0) == (x > 0).
1399 * 0: add.sat(8) dest src0 src1
1400 * 1: cmp.g.f0(8) null dest 0.0f
1403 * 0: add.sat.g.f0(8) dest src0 src1
1405 test_positive_float_saturate_prop(BRW_CONDITIONAL_G
, BRW_CONDITIONAL_G
,
1409 TEST_F(cmod_propagation_test
, float_saturate_g_mov
)
1411 /* With the saturate modifier, the comparison happens before clamping to
1412 * [0, 1]. (sat(x) > 0) == (x > 0).
1416 * 0: add.sat(8) dest src0 src1
1417 * 1: mov.g.f0(8) null dest
1420 * 0: add.sat.g.f0(8) dest src0 src1
1423 /* cmod propagation bails on every MOV except MOV.NZ. */
1424 test_negative_float_saturate_prop(BRW_CONDITIONAL_G
, BRW_OPCODE_MOV
);
1426 test_positive_float_saturate_prop(BRW_CONDITIONAL_G
, BRW_CONDITIONAL_G
,
1431 TEST_F(cmod_propagation_test
, float_saturate_le_cmp
)
1433 /* With the saturate modifier, the comparison happens before clamping to
1434 * [0, 1]. (sat(x) <= 0) == (x <= 0).
1438 * 0: add.sat(8) dest src0 src1
1439 * 1: cmp.le.f0(8) null dest 0.0f
1442 * 0: add.sat.le.f0(8) dest src0 src1
1444 test_positive_float_saturate_prop(BRW_CONDITIONAL_LE
, BRW_CONDITIONAL_LE
,
1448 TEST_F(cmod_propagation_test
, float_saturate_le_mov
)
1450 /* With the saturate modifier, the comparison happens before clamping to
1451 * [0, 1]. (sat(x) <= 0) == (x <= 0).
1455 * 0: add.sat(8) dest src0 src1
1456 * 1: mov.le.f0(8) null dest
1459 * 0: add.sat.le.f0(8) dest src0 src1
1462 /* cmod propagation bails on every MOV except MOV.NZ. */
1463 test_negative_float_saturate_prop(BRW_CONDITIONAL_LE
, BRW_OPCODE_MOV
);
1465 test_positive_float_saturate_prop(BRW_CONDITIONAL_LE
, BRW_CONDITIONAL_LE
,
1470 TEST_F(cmod_propagation_test
, float_saturate_l_cmp
)
1472 /* With the saturate modifier, the comparison happens before clamping to
1473 * [0, 1]. There is no before / after equivalence for (sat(x) < 0).
1477 * 0: add.sat(8) dest src0 src1
1478 * 1: cmp.l.f0(8) null dest 0.0f
1483 test_negative_float_saturate_prop(BRW_CONDITIONAL_L
, BRW_OPCODE_CMP
);
1487 TEST_F(cmod_propagation_test
, float_saturate_l_mov
)
1489 /* With the saturate modifier, the comparison happens before clamping to
1490 * [0, 1]. There is no before / after equivalence for (sat(x) < 0).
1494 * 0: add.sat(8) dest src0 src1
1495 * 1: mov.l.f0(8) null dest 0.0f
1500 test_negative_float_saturate_prop(BRW_CONDITIONAL_L
, BRW_OPCODE_MOV
);
1504 TEST_F(cmod_propagation_test
, float_saturate_ge_cmp
)
1506 /* With the saturate modifier, the comparison happens before clamping to
1507 * [0, 1]. There is no before / after equivalence for (sat(x) >= 0).
1511 * 0: add.sat(8) dest src0 src1
1512 * 1: cmp.ge.f0(8) null dest 0.0f
1517 test_negative_float_saturate_prop(BRW_CONDITIONAL_GE
, BRW_OPCODE_CMP
);
1520 TEST_F(cmod_propagation_test
, float_saturate_ge_mov
)
1522 /* With the saturate modifier, the comparison happens before clamping to
1523 * [0, 1]. There is no before / after equivalence for (sat(x) >= 0).
1527 * 0: add.sat(8) dest src0 src1
1528 * 1: mov.ge.f0(8) null dest 0.0f
1533 test_negative_float_saturate_prop(BRW_CONDITIONAL_GE
, BRW_OPCODE_MOV
);
1536 TEST_F(cmod_propagation_test
, int_saturate_nz_cmp
)
1540 * 0: add.sat(8) dest src0 src1
1541 * 1: cmp.nz.f0(8) null dest 0
1546 test_negative_int_saturate_prop(BRW_CONDITIONAL_NZ
, BRW_OPCODE_CMP
);
1549 TEST_F(cmod_propagation_test
, int_saturate_nz_mov
)
1553 * 0: add.sat(8) dest src0 src1
1554 * 1: mov.nz.f0(8) null dest
1559 test_negative_int_saturate_prop(BRW_CONDITIONAL_NZ
, BRW_OPCODE_MOV
);
1562 TEST_F(cmod_propagation_test
, int_saturate_z_cmp
)
1566 * 0: add.sat(8) dest src0 src1
1567 * 1: cmp.z.f0(8) null dest 0
1572 test_negative_int_saturate_prop(BRW_CONDITIONAL_Z
, BRW_OPCODE_CMP
);
1575 TEST_F(cmod_propagation_test
, int_saturate_z_mov
)
1577 /* With the saturate modifier, the comparison happens before clamping to
1578 * [0, 1]. (sat(x) == 0) == (x <= 0).
1582 * 0: add.sat(8) dest src0 src1
1583 * 1: mov.z.f0(8) null dest
1588 test_negative_int_saturate_prop(BRW_CONDITIONAL_Z
, BRW_OPCODE_MOV
);
1591 TEST_F(cmod_propagation_test
, int_saturate_g_cmp
)
1595 * 0: add.sat(8) dest src0 src1
1596 * 1: cmp.g.f0(8) null dest 0
1601 test_negative_int_saturate_prop(BRW_CONDITIONAL_G
, BRW_OPCODE_CMP
);
1604 TEST_F(cmod_propagation_test
, int_saturate_g_mov
)
1608 * 0: add.sat(8) dest src0 src1
1609 * 1: mov.g.f0(8) null dest
1614 test_negative_int_saturate_prop(BRW_CONDITIONAL_G
, BRW_OPCODE_MOV
);
1617 TEST_F(cmod_propagation_test
, int_saturate_le_cmp
)
1621 * 0: add.sat(8) dest src0 src1
1622 * 1: cmp.le.f0(8) null dest 0
1627 test_negative_int_saturate_prop(BRW_CONDITIONAL_LE
, BRW_OPCODE_CMP
);
1630 TEST_F(cmod_propagation_test
, int_saturate_le_mov
)
1634 * 0: add.sat(8) dest src0 src1
1635 * 1: mov.le.f0(8) null dest
1640 test_negative_int_saturate_prop(BRW_CONDITIONAL_LE
, BRW_OPCODE_MOV
);
1643 TEST_F(cmod_propagation_test
, int_saturate_l_cmp
)
1647 * 0: add.sat(8) dest src0 src1
1648 * 1: cmp.l.f0(8) null dest 0
1653 test_negative_int_saturate_prop(BRW_CONDITIONAL_L
, BRW_OPCODE_CMP
);
1656 TEST_F(cmod_propagation_test
, int_saturate_l_mov
)
1660 * 0: add.sat(8) dest src0 src1
1661 * 1: mov.l.f0(8) null dest 0
1666 test_negative_int_saturate_prop(BRW_CONDITIONAL_L
, BRW_OPCODE_MOV
);
1669 TEST_F(cmod_propagation_test
, int_saturate_ge_cmp
)
1673 * 0: add.sat(8) dest src0 src1
1674 * 1: cmp.ge.f0(8) null dest 0
1679 test_negative_int_saturate_prop(BRW_CONDITIONAL_GE
, BRW_OPCODE_CMP
);
1682 TEST_F(cmod_propagation_test
, int_saturate_ge_mov
)
1686 * 0: add.sat(8) dest src0 src1
1687 * 1: mov.ge.f0(8) null dest
1692 test_negative_int_saturate_prop(BRW_CONDITIONAL_GE
, BRW_OPCODE_MOV
);
1695 TEST_F(cmod_propagation_test
, not_to_or
)
1697 /* Exercise propagation of conditional modifier from a NOT instruction to
1698 * another ALU instruction as performed by cmod_propagate_not.
1700 const fs_builder
&bld
= v
->bld
;
1701 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
1702 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1703 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1704 bld
.OR(dest
, src0
, src1
);
1705 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest
));
1709 * 0: or(8) dest src0 src1
1710 * 1: not.nz.f0(8) null dest
1713 * 0: or.z.f0(8) dest src0 src1
1717 bblock_t
*block0
= v
->cfg
->blocks
[0];
1719 EXPECT_EQ(0, block0
->start_ip
);
1720 EXPECT_EQ(1, block0
->end_ip
);
1722 EXPECT_TRUE(cmod_propagation(v
));
1723 EXPECT_EQ(0, block0
->start_ip
);
1724 EXPECT_EQ(0, block0
->end_ip
);
1725 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
1726 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
1729 TEST_F(cmod_propagation_test
, not_to_and
)
1731 /* Exercise propagation of conditional modifier from a NOT instruction to
1732 * another ALU instruction as performed by cmod_propagate_not.
1734 const fs_builder
&bld
= v
->bld
;
1735 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
1736 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1737 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1738 bld
.AND(dest
, src0
, src1
);
1739 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest
));
1743 * 0: and(8) dest src0 src1
1744 * 1: not.nz.f0(8) null dest
1747 * 0: and.z.f0(8) dest src0 src1
1751 bblock_t
*block0
= v
->cfg
->blocks
[0];
1753 EXPECT_EQ(0, block0
->start_ip
);
1754 EXPECT_EQ(1, block0
->end_ip
);
1756 EXPECT_TRUE(cmod_propagation(v
));
1757 EXPECT_EQ(0, block0
->start_ip
);
1758 EXPECT_EQ(0, block0
->end_ip
);
1759 EXPECT_EQ(BRW_OPCODE_AND
, instruction(block0
, 0)->opcode
);
1760 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
1763 TEST_F(cmod_propagation_test
, not_to_uadd
)
1765 /* Exercise propagation of conditional modifier from a NOT instruction to
1766 * another ALU instruction as performed by cmod_propagate_not.
1768 * The optimization pass currently restricts to just OR and AND. It's
1769 * possible that this is too restrictive, and the actual, necessary
1770 * restriction is just the the destination type of the ALU instruction is
1771 * the same as the source type of the NOT instruction.
1773 const fs_builder
&bld
= v
->bld
;
1774 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
1775 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1776 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1777 bld
.ADD(dest
, src0
, src1
);
1778 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest
));
1782 * 0: add(8) dest src0 src1
1783 * 1: not.nz.f0(8) null dest
1790 bblock_t
*block0
= v
->cfg
->blocks
[0];
1792 EXPECT_EQ(0, block0
->start_ip
);
1793 EXPECT_EQ(1, block0
->end_ip
);
1795 EXPECT_FALSE(cmod_propagation(v
));
1796 EXPECT_EQ(0, block0
->start_ip
);
1797 EXPECT_EQ(1, block0
->end_ip
);
1798 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1799 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1800 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 1)->opcode
);
1801 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 1)->conditional_mod
);
1804 TEST_F(cmod_propagation_test
, not_to_fadd_to_ud
)
1806 /* Exercise propagation of conditional modifier from a NOT instruction to
1807 * another ALU instruction as performed by cmod_propagate_not.
1809 * The optimization pass currently restricts to just OR and AND. It's
1810 * possible that this is too restrictive, and the actual, necessary
1811 * restriction is just the the destination type of the ALU instruction is
1812 * the same as the source type of the NOT instruction.
1814 const fs_builder
&bld
= v
->bld
;
1815 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
1816 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1817 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1818 bld
.ADD(dest
, src0
, src1
);
1819 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest
));
1823 * 0: add(8) dest.ud src0.f src1.f
1824 * 1: not.nz.f0(8) null dest.ud
1831 bblock_t
*block0
= v
->cfg
->blocks
[0];
1833 EXPECT_EQ(0, block0
->start_ip
);
1834 EXPECT_EQ(1, block0
->end_ip
);
1836 EXPECT_FALSE(cmod_propagation(v
));
1837 EXPECT_EQ(0, block0
->start_ip
);
1838 EXPECT_EQ(1, block0
->end_ip
);
1839 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1840 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1841 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 1)->opcode
);
1842 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 1)->conditional_mod
);
1845 TEST_F(cmod_propagation_test
, not_to_fadd
)
1847 /* Exercise propagation of conditional modifier from a NOT instruction to
1848 * another ALU instruction as performed by cmod_propagate_not.
1850 * The optimization pass currently restricts to just OR and AND. It's
1851 * possible that this is too restrictive, and the actual, necessary
1852 * restriction is just the the destination type of the ALU instruction is
1853 * the same as the source type of the NOT instruction.
1855 const fs_builder
&bld
= v
->bld
;
1856 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
1857 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
1858 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
1859 bld
.ADD(dest
, src0
, src1
);
1860 set_condmod(BRW_CONDITIONAL_NZ
,
1861 bld
.NOT(bld
.null_reg_ud(),
1862 retype(dest
, BRW_REGISTER_TYPE_UD
)));
1866 * 0: add(8) dest.f src0.f src1.f
1867 * 1: not.nz.f0(8) null dest.ud
1874 bblock_t
*block0
= v
->cfg
->blocks
[0];
1876 EXPECT_EQ(0, block0
->start_ip
);
1877 EXPECT_EQ(1, block0
->end_ip
);
1879 EXPECT_FALSE(cmod_propagation(v
));
1880 EXPECT_EQ(0, block0
->start_ip
);
1881 EXPECT_EQ(1, block0
->end_ip
);
1882 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
1883 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
1884 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 1)->opcode
);
1885 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 1)->conditional_mod
);
1888 TEST_F(cmod_propagation_test
, not_to_or_intervening_flag_read_compatible_value
)
1890 /* Exercise propagation of conditional modifier from a NOT instruction to
1891 * another ALU instruction as performed by cmod_propagate_not.
1893 const fs_builder
&bld
= v
->bld
;
1894 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
1895 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1896 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1897 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1898 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
1899 fs_reg
zero(brw_imm_f(0.0f
));
1900 set_condmod(BRW_CONDITIONAL_Z
, bld
.OR(dest0
, src0
, src1
));
1901 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
));
1902 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
1906 * 0: or.z.f0(8) dest0 src0 src1
1907 * 1: (+f0) sel(8) dest1 src2 0.0f
1908 * 2: not.nz.f0(8) null dest0
1911 * 0: or.z.f0(8) dest0 src0 src1
1912 * 1: (+f0) sel(8) dest1 src2 0.0f
1916 bblock_t
*block0
= v
->cfg
->blocks
[0];
1918 EXPECT_EQ(0, block0
->start_ip
);
1919 EXPECT_EQ(2, block0
->end_ip
);
1921 EXPECT_TRUE(cmod_propagation(v
));
1922 EXPECT_EQ(0, block0
->start_ip
);
1923 EXPECT_EQ(1, block0
->end_ip
);
1924 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
1925 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
1926 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
1927 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1930 TEST_F(cmod_propagation_test
,
1931 not_to_or_intervening_flag_read_compatible_value_mismatch_flag
)
1933 /* Exercise propagation of conditional modifier from a NOT instruction to
1934 * another ALU instruction as performed by cmod_propagate_not.
1936 const fs_builder
&bld
= v
->bld
;
1937 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
1938 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1939 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1940 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1941 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
1942 fs_reg
zero(brw_imm_f(0.0f
));
1943 set_condmod(BRW_CONDITIONAL_Z
, bld
.OR(dest0
, src0
, src1
))
1945 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
));
1946 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
1950 * 0: or.z.f0.1(8) dest0 src0 src1
1951 * 1: (+f0) sel(8) dest1 src2 0.0f
1952 * 2: not.nz.f0(8) null dest0
1959 bblock_t
*block0
= v
->cfg
->blocks
[0];
1961 EXPECT_EQ(0, block0
->start_ip
);
1962 EXPECT_EQ(2, block0
->end_ip
);
1964 EXPECT_FALSE(cmod_propagation(v
));
1965 EXPECT_EQ(0, block0
->start_ip
);
1966 EXPECT_EQ(2, block0
->end_ip
);
1967 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
1968 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
1969 EXPECT_EQ(1, instruction(block0
, 0)->flag_subreg
);
1970 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
1971 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
1972 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 2)->opcode
);
1973 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 2)->conditional_mod
);
1974 EXPECT_EQ(0, instruction(block0
, 2)->flag_subreg
);
1977 TEST_F(cmod_propagation_test
, not_to_or_intervening_flag_read_incompatible_value
)
1979 /* Exercise propagation of conditional modifier from a NOT instruction to
1980 * another ALU instruction as performed by cmod_propagate_not.
1982 const fs_builder
&bld
= v
->bld
;
1983 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
1984 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
1985 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
1986 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
1987 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
1988 fs_reg
zero(brw_imm_f(0.0f
));
1989 set_condmod(BRW_CONDITIONAL_NZ
, bld
.OR(dest0
, src0
, src1
));
1990 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
));
1991 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
1995 * 0: or.nz.f0(8) dest0 src0 src1
1996 * 1: (+f0) sel(8) dest1 src2 0.0f
1997 * 2: not.nz.f0(8) null dest0
2004 bblock_t
*block0
= v
->cfg
->blocks
[0];
2006 EXPECT_EQ(0, block0
->start_ip
);
2007 EXPECT_EQ(2, block0
->end_ip
);
2009 EXPECT_FALSE(cmod_propagation(v
));
2010 EXPECT_EQ(0, block0
->start_ip
);
2011 EXPECT_EQ(2, block0
->end_ip
);
2012 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
2013 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 0)->conditional_mod
);
2014 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
2015 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
2016 EXPECT_EQ(BRW_OPCODE_NOT
, instruction(block0
, 2)->opcode
);
2017 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 2)->conditional_mod
);
2020 TEST_F(cmod_propagation_test
, not_to_or_intervening_mismatch_flag_write
)
2022 /* Exercise propagation of conditional modifier from a NOT instruction to
2023 * another ALU instruction as performed by cmod_propagate_not.
2025 const fs_builder
&bld
= v
->bld
;
2026 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
2027 fs_reg dest1
= v
->vgrf(glsl_type::uint_type
);
2028 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
2029 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
2031 bld
.OR(dest0
, src0
, src1
);
2032 set_condmod(BRW_CONDITIONAL_Z
, bld
.OR(dest1
, src0
, src1
))
2034 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
2038 * 0: or(8) dest0 src0 src1
2039 * 1: or.z.f0.1(8) dest1 src0 src1
2040 * 2: not.nz.f0(8) null dest0
2043 * 0: or.z.f0(8) dest0 src0 src1
2044 * 1: or.z.f0.1(8) dest1 src0 src1
2048 bblock_t
*block0
= v
->cfg
->blocks
[0];
2050 EXPECT_EQ(0, block0
->start_ip
);
2051 EXPECT_EQ(2, block0
->end_ip
);
2053 EXPECT_TRUE(cmod_propagation(v
));
2054 EXPECT_EQ(0, block0
->start_ip
);
2055 EXPECT_EQ(1, block0
->end_ip
);
2056 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
2057 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
2058 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
2059 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 1)->opcode
);
2060 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 1)->conditional_mod
);
2061 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);
2064 TEST_F(cmod_propagation_test
, not_to_or_intervening_mismatch_flag_read
)
2066 /* Exercise propagation of conditional modifier from a NOT instruction to
2067 * another ALU instruction as performed by cmod_propagate_not.
2069 const fs_builder
&bld
= v
->bld
;
2070 fs_reg dest0
= v
->vgrf(glsl_type::uint_type
);
2071 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
2072 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
2073 fs_reg src1
= v
->vgrf(glsl_type::uint_type
);
2074 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
2075 fs_reg
zero(brw_imm_f(0.0f
));
2077 bld
.OR(dest0
, src0
, src1
);
2078 set_predicate(BRW_PREDICATE_NORMAL
, bld
.SEL(dest1
, src2
, zero
))
2080 set_condmod(BRW_CONDITIONAL_NZ
, bld
.NOT(bld
.null_reg_ud(), dest0
));
2084 * 0: or(8) dest0 src0 src1
2085 * 1: (+f0.1) sel(8) dest1 src2 0.0f
2086 * 2: not.nz.f0(8) null dest0
2089 * 0: or.z.f0(8) dest0 src0 src1
2090 * 1: (+f0.1) sel(8) dest1 src2 0.0f
2094 bblock_t
*block0
= v
->cfg
->blocks
[0];
2096 EXPECT_EQ(0, block0
->start_ip
);
2097 EXPECT_EQ(2, block0
->end_ip
);
2099 EXPECT_TRUE(cmod_propagation(v
));
2100 EXPECT_EQ(0, block0
->start_ip
);
2101 EXPECT_EQ(1, block0
->end_ip
);
2102 EXPECT_EQ(BRW_OPCODE_OR
, instruction(block0
, 0)->opcode
);
2103 EXPECT_EQ(BRW_CONDITIONAL_Z
, instruction(block0
, 0)->conditional_mod
);
2104 EXPECT_EQ(0, instruction(block0
, 0)->flag_subreg
);
2105 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
2106 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
2107 EXPECT_EQ(1, instruction(block0
, 1)->flag_subreg
);