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"
29 class cmod_propagation_test
: public ::testing::Test
{
33 struct brw_context
*brw
;
34 struct brw_device_info
*devinfo
;
35 struct gl_context
*ctx
;
36 struct brw_wm_prog_data
*prog_data
;
37 struct gl_shader_program
*shader_prog
;
38 struct brw_fragment_program
*fp
;
42 class cmod_propagation_fs_visitor
: public fs_visitor
45 cmod_propagation_fs_visitor(struct brw_context
*brw
,
46 struct brw_wm_prog_data
*prog_data
,
47 struct gl_shader_program
*shader_prog
)
48 : fs_visitor(brw
, NULL
, NULL
, prog_data
, shader_prog
, NULL
, 8) {}
52 void cmod_propagation_test::SetUp()
54 brw
= (struct brw_context
*)calloc(1, sizeof(*brw
));
55 devinfo
= (struct brw_device_info
*)calloc(1, sizeof(*brw
));
56 brw
->intelScreen
= (struct intel_screen
*)calloc(1, sizeof(*brw
->intelScreen
));
57 brw
->intelScreen
->devinfo
= devinfo
;
60 fp
= ralloc(NULL
, struct brw_fragment_program
);
61 prog_data
= ralloc(NULL
, struct brw_wm_prog_data
);
62 shader_prog
= ralloc(NULL
, struct gl_shader_program
);
64 v
= new cmod_propagation_fs_visitor(brw
, prog_data
, shader_prog
);
66 _mesa_init_fragment_program(ctx
, &fp
->program
, GL_FRAGMENT_SHADER
, 0);
68 brw
->gen
= devinfo
->gen
= 4;
72 instruction(bblock_t
*block
, int num
)
74 fs_inst
*inst
= (fs_inst
*)block
->start();
75 for (int i
= 0; i
< num
; i
++) {
76 inst
= (fs_inst
*)inst
->next
;
82 cmod_propagation(fs_visitor
*v
)
84 const bool print
= false;
87 fprintf(stderr
, "= Before =\n");
91 bool ret
= v
->opt_cmod_propagation();
94 fprintf(stderr
, "\n= After =\n");
101 TEST_F(cmod_propagation_test
, basic
)
103 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
104 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
105 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
107 v
->emit(BRW_OPCODE_ADD
, dest
, src0
, src1
);
108 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_f
, dest
, zero
)
109 ->conditional_mod
= BRW_CONDITIONAL_GE
;
113 * 0: add(8) dest src0 src1
114 * 1: cmp.ge.f0(8) null dest 0.0f
117 * 0: add.ge.f0(8) dest src0 src1
121 bblock_t
*block0
= v
->cfg
->blocks
[0];
123 EXPECT_EQ(0, block0
->start_ip
);
124 EXPECT_EQ(1, block0
->end_ip
);
126 EXPECT_TRUE(cmod_propagation(v
));
127 EXPECT_EQ(0, block0
->start_ip
);
128 EXPECT_EQ(0, block0
->end_ip
);
129 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
130 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 0)->conditional_mod
);
133 TEST_F(cmod_propagation_test
, cmp_nonzero
)
135 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
136 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
137 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
138 fs_reg
nonzero(1.0f
);
139 v
->emit(BRW_OPCODE_ADD
, dest
, src0
, src1
);
140 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_f
, dest
, nonzero
)
141 ->conditional_mod
= BRW_CONDITIONAL_GE
;
145 * 0: add(8) dest src0 src1
146 * 1: cmp.ge.f0(8) null dest 1.0f
153 bblock_t
*block0
= v
->cfg
->blocks
[0];
155 EXPECT_EQ(0, block0
->start_ip
);
156 EXPECT_EQ(1, block0
->end_ip
);
158 EXPECT_FALSE(cmod_propagation(v
));
159 EXPECT_EQ(0, block0
->start_ip
);
160 EXPECT_EQ(1, block0
->end_ip
);
161 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
162 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
163 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 1)->conditional_mod
);
166 TEST_F(cmod_propagation_test
, non_cmod_instruction
)
168 fs_reg dest
= v
->vgrf(glsl_type::uint_type
);
169 fs_reg src0
= v
->vgrf(glsl_type::uint_type
);
171 v
->emit(BRW_OPCODE_FBL
, dest
, src0
);
172 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_ud
, dest
, zero
)
173 ->conditional_mod
= BRW_CONDITIONAL_GE
;
177 * 0: fbl(8) dest src0
178 * 1: cmp.ge.f0(8) null dest 0u
185 bblock_t
*block0
= v
->cfg
->blocks
[0];
187 EXPECT_EQ(0, block0
->start_ip
);
188 EXPECT_EQ(1, block0
->end_ip
);
190 EXPECT_FALSE(cmod_propagation(v
));
191 EXPECT_EQ(0, block0
->start_ip
);
192 EXPECT_EQ(1, block0
->end_ip
);
193 EXPECT_EQ(BRW_OPCODE_FBL
, instruction(block0
, 0)->opcode
);
194 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
195 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 1)->conditional_mod
);
198 TEST_F(cmod_propagation_test
, intervening_flag_write
)
200 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
201 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
202 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
203 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
205 v
->emit(BRW_OPCODE_ADD
, dest
, src0
, src1
);
206 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_f
, src2
, zero
)
207 ->conditional_mod
= BRW_CONDITIONAL_GE
;
208 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_f
, dest
, zero
)
209 ->conditional_mod
= BRW_CONDITIONAL_GE
;
213 * 0: add(8) dest src0 src1
214 * 1: cmp.ge.f0(8) null src2 0.0f
215 * 2: cmp.ge.f0(8) null dest 0.0f
222 bblock_t
*block0
= v
->cfg
->blocks
[0];
224 EXPECT_EQ(0, block0
->start_ip
);
225 EXPECT_EQ(2, block0
->end_ip
);
227 EXPECT_FALSE(cmod_propagation(v
));
228 EXPECT_EQ(0, block0
->start_ip
);
229 EXPECT_EQ(2, block0
->end_ip
);
230 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
231 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
232 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 1)->conditional_mod
);
233 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
234 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 2)->conditional_mod
);
237 TEST_F(cmod_propagation_test
, intervening_flag_read
)
239 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
240 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
241 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
242 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
243 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
245 v
->emit(BRW_OPCODE_ADD
, dest0
, src0
, src1
);
246 v
->emit(BRW_OPCODE_SEL
, dest1
, src2
, zero
)
247 ->predicate
= BRW_PREDICATE_NORMAL
;
248 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_f
, dest0
, zero
)
249 ->conditional_mod
= BRW_CONDITIONAL_GE
;
253 * 0: add(8) dest0 src0 src1
254 * 1: (+f0) sel(8) dest1 src2 0.0f
255 * 2: cmp.ge.f0(8) null dest0 0.0f
262 bblock_t
*block0
= v
->cfg
->blocks
[0];
264 EXPECT_EQ(0, block0
->start_ip
);
265 EXPECT_EQ(2, block0
->end_ip
);
267 EXPECT_FALSE(cmod_propagation(v
));
268 EXPECT_EQ(0, block0
->start_ip
);
269 EXPECT_EQ(2, block0
->end_ip
);
270 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
271 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
272 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
273 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
274 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 2)->conditional_mod
);
277 TEST_F(cmod_propagation_test
, intervening_dest_write
)
279 fs_reg dest
= v
->vgrf(glsl_type::vec4_type
);
280 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
281 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
282 fs_reg src2
= v
->vgrf(glsl_type::vec2_type
);
284 v
->emit(BRW_OPCODE_ADD
, offset(dest
, 2), src0
, src1
);
285 v
->emit(SHADER_OPCODE_TEX
, dest
, src2
)
287 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_f
, offset(dest
, 2), zero
)
288 ->conditional_mod
= BRW_CONDITIONAL_GE
;
292 * 0: add(8) dest+2 src0 src1
293 * 1: tex(8) rlen 4 dest+0 src2
294 * 2: cmp.ge.f0(8) null dest+2 0.0f
301 bblock_t
*block0
= v
->cfg
->blocks
[0];
303 EXPECT_EQ(0, block0
->start_ip
);
304 EXPECT_EQ(2, block0
->end_ip
);
306 EXPECT_FALSE(cmod_propagation(v
));
307 EXPECT_EQ(0, block0
->start_ip
);
308 EXPECT_EQ(2, block0
->end_ip
);
309 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
310 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
311 EXPECT_EQ(SHADER_OPCODE_TEX
, instruction(block0
, 1)->opcode
);
312 EXPECT_EQ(BRW_CONDITIONAL_NONE
, instruction(block0
, 0)->conditional_mod
);
313 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 2)->opcode
);
314 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 2)->conditional_mod
);
317 TEST_F(cmod_propagation_test
, intervening_flag_read_same_value
)
319 fs_reg dest0
= v
->vgrf(glsl_type::float_type
);
320 fs_reg dest1
= v
->vgrf(glsl_type::float_type
);
321 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
322 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
323 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
325 v
->emit(BRW_OPCODE_ADD
, dest0
, src0
, src1
)
326 ->conditional_mod
= BRW_CONDITIONAL_GE
;
327 v
->emit(BRW_OPCODE_SEL
, dest1
, src2
, zero
)
328 ->predicate
= BRW_PREDICATE_NORMAL
;
329 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_f
, dest0
, zero
)
330 ->conditional_mod
= BRW_CONDITIONAL_GE
;
334 * 0: add.ge.f0(8) dest0 src0 src1
335 * 1: (+f0) sel(8) dest1 src2 0.0f
336 * 2: cmp.ge.f0(8) null dest0 0.0f
339 * 0: add.ge.f0(8) dest0 src0 src1
340 * 1: (+f0) sel(8) dest1 src2 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_TRUE(cmod_propagation(v
));
350 EXPECT_EQ(0, block0
->start_ip
);
351 EXPECT_EQ(1, block0
->end_ip
);
352 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
353 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 0)->conditional_mod
);
354 EXPECT_EQ(BRW_OPCODE_SEL
, instruction(block0
, 1)->opcode
);
355 EXPECT_EQ(BRW_PREDICATE_NORMAL
, instruction(block0
, 1)->predicate
);
358 TEST_F(cmod_propagation_test
, negate
)
360 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
361 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
362 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
364 v
->emit(BRW_OPCODE_ADD
, dest
, src0
, src1
);
366 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_f
, dest
, zero
)
367 ->conditional_mod
= BRW_CONDITIONAL_GE
;
371 * 0: add(8) dest src0 src1
372 * 1: cmp.ge.f0(8) null -dest 0.0f
375 * 0: add.le.f0(8) dest src0 src1
379 bblock_t
*block0
= v
->cfg
->blocks
[0];
381 EXPECT_EQ(0, block0
->start_ip
);
382 EXPECT_EQ(1, block0
->end_ip
);
384 EXPECT_TRUE(cmod_propagation(v
));
385 EXPECT_EQ(0, block0
->start_ip
);
386 EXPECT_EQ(0, block0
->end_ip
);
387 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
388 EXPECT_EQ(BRW_CONDITIONAL_LE
, instruction(block0
, 0)->conditional_mod
);
391 TEST_F(cmod_propagation_test
, movnz
)
393 fs_reg dest
= v
->vgrf(glsl_type::float_type
);
394 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
395 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
396 v
->emit(BRW_OPCODE_CMP
, dest
, src0
, src1
)
397 ->conditional_mod
= BRW_CONDITIONAL_GE
;
398 v
->emit(BRW_OPCODE_MOV
, v
->reg_null_f
, dest
)
399 ->conditional_mod
= BRW_CONDITIONAL_NZ
;
403 * 0: cmp.ge.f0(8) dest src0 src1
404 * 1: mov.nz.f0(8) null dest
407 * 0: cmp.ge.f0(8) dest src0 src1
411 bblock_t
*block0
= v
->cfg
->blocks
[0];
413 EXPECT_EQ(0, block0
->start_ip
);
414 EXPECT_EQ(1, block0
->end_ip
);
416 EXPECT_TRUE(cmod_propagation(v
));
417 EXPECT_EQ(0, block0
->start_ip
);
418 EXPECT_EQ(0, block0
->end_ip
);
419 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 0)->opcode
);
420 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 0)->conditional_mod
);
423 TEST_F(cmod_propagation_test
, different_types_cmod_with_zero
)
425 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
426 fs_reg src0
= v
->vgrf(glsl_type::int_type
);
427 fs_reg src1
= v
->vgrf(glsl_type::int_type
);
429 v
->emit(BRW_OPCODE_ADD
, dest
, src0
, src1
);
430 v
->emit(BRW_OPCODE_CMP
, v
->reg_null_f
, retype(dest
, BRW_REGISTER_TYPE_F
),
432 ->conditional_mod
= BRW_CONDITIONAL_GE
;
436 * 0: add(8) dest:D src0:D src1:D
437 * 1: cmp.ge.f0(8) null:F dest:F 0.0f
444 bblock_t
*block0
= v
->cfg
->blocks
[0];
446 EXPECT_EQ(0, block0
->start_ip
);
447 EXPECT_EQ(1, block0
->end_ip
);
449 EXPECT_FALSE(cmod_propagation(v
));
450 EXPECT_EQ(0, block0
->start_ip
);
451 EXPECT_EQ(1, block0
->end_ip
);
452 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
453 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 1)->opcode
);
454 EXPECT_EQ(BRW_CONDITIONAL_GE
, instruction(block0
, 1)->conditional_mod
);
457 TEST_F(cmod_propagation_test
, andnz_one
)
459 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
460 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
464 v
->emit(BRW_OPCODE_CMP
, retype(dest
, BRW_REGISTER_TYPE_F
), src0
, zero
)
465 ->conditional_mod
= BRW_CONDITIONAL_L
;
466 v
->emit(BRW_OPCODE_AND
, v
->reg_null_d
, dest
, one
)
467 ->conditional_mod
= BRW_CONDITIONAL_NZ
;
470 * 0: cmp.l.f0(8) dest:F src0:F 0F
471 * 1: and.nz.f0(8) null:D dest:D 1D
474 * 0: cmp.l.f0(8) dest:F src0:F 0F
478 bblock_t
*block0
= v
->cfg
->blocks
[0];
480 EXPECT_EQ(0, block0
->start_ip
);
481 EXPECT_EQ(1, block0
->end_ip
);
483 EXPECT_TRUE(cmod_propagation(v
));
484 EXPECT_EQ(0, block0
->start_ip
);
485 EXPECT_EQ(0, block0
->end_ip
);
486 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 0)->opcode
);
487 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
488 EXPECT_TRUE(retype(dest
, BRW_REGISTER_TYPE_F
)
489 .equals(instruction(block0
, 0)->dst
));
492 TEST_F(cmod_propagation_test
, andnz_non_one
)
494 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
495 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
499 v
->emit(BRW_OPCODE_CMP
, retype(dest
, BRW_REGISTER_TYPE_F
), src0
, zero
)
500 ->conditional_mod
= BRW_CONDITIONAL_L
;
501 v
->emit(BRW_OPCODE_AND
, v
->reg_null_d
, dest
, nonone
)
502 ->conditional_mod
= BRW_CONDITIONAL_NZ
;
505 * 0: cmp.l.f0(8) dest:F src0:F 0F
506 * 1: and.nz.f0(8) null:D dest:D 38D
513 bblock_t
*block0
= v
->cfg
->blocks
[0];
515 EXPECT_EQ(0, block0
->start_ip
);
516 EXPECT_EQ(1, block0
->end_ip
);
518 EXPECT_FALSE(cmod_propagation(v
));
519 EXPECT_EQ(0, block0
->start_ip
);
520 EXPECT_EQ(1, block0
->end_ip
);
521 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 0)->opcode
);
522 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
523 EXPECT_EQ(BRW_OPCODE_AND
, instruction(block0
, 1)->opcode
);
524 EXPECT_EQ(BRW_CONDITIONAL_NZ
, instruction(block0
, 1)->conditional_mod
);
527 TEST_F(cmod_propagation_test
, andz_one
)
529 fs_reg dest
= v
->vgrf(glsl_type::int_type
);
530 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
534 v
->emit(BRW_OPCODE_CMP
, retype(dest
, BRW_REGISTER_TYPE_F
), src0
, zero
)
535 ->conditional_mod
= BRW_CONDITIONAL_L
;
536 v
->emit(BRW_OPCODE_AND
, v
->reg_null_d
, dest
, one
)
537 ->conditional_mod
= BRW_CONDITIONAL_Z
;
540 * 0: cmp.l.f0(8) dest:F src0:F 0F
541 * 1: and.z.f0(8) null:D dest:D 1D
548 bblock_t
*block0
= v
->cfg
->blocks
[0];
550 EXPECT_EQ(0, block0
->start_ip
);
551 EXPECT_EQ(1, block0
->end_ip
);
553 EXPECT_FALSE(cmod_propagation(v
));
554 EXPECT_EQ(0, block0
->start_ip
);
555 EXPECT_EQ(1, block0
->end_ip
);
556 EXPECT_EQ(BRW_OPCODE_CMP
, instruction(block0
, 0)->opcode
);
557 EXPECT_EQ(BRW_CONDITIONAL_L
, instruction(block0
, 0)->conditional_mod
);
558 EXPECT_EQ(BRW_OPCODE_AND
, instruction(block0
, 1)->opcode
);
559 EXPECT_EQ(BRW_CONDITIONAL_EQ
, instruction(block0
, 1)->conditional_mod
);