2 * Copyright © 2016 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 copy_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
;
43 class copy_propagation_fs_visitor
: public fs_visitor
46 copy_propagation_fs_visitor(struct brw_compiler
*compiler
,
47 struct brw_wm_prog_data
*prog_data
,
49 : fs_visitor(compiler
, NULL
, NULL
, NULL
,
50 &prog_data
->base
, shader
, 8, -1) {}
54 void copy_propagation_test::SetUp()
56 ctx
= (struct gl_context
*)calloc(1, sizeof(*ctx
));
57 compiler
= (struct brw_compiler
*)calloc(1, sizeof(*compiler
));
58 devinfo
= (struct gen_device_info
*)calloc(1, sizeof(*devinfo
));
59 compiler
->devinfo
= devinfo
;
61 prog_data
= ralloc(NULL
, struct brw_wm_prog_data
);
63 nir_shader_create(NULL
, MESA_SHADER_FRAGMENT
, NULL
, NULL
);
65 v
= new copy_propagation_fs_visitor(compiler
, prog_data
, shader
);
71 instruction(bblock_t
*block
, int num
)
73 fs_inst
*inst
= (fs_inst
*)block
->start();
74 for (int i
= 0; i
< num
; i
++) {
75 inst
= (fs_inst
*)inst
->next
;
81 copy_propagation(fs_visitor
*v
)
83 const bool print
= getenv("TEST_DEBUG");
86 fprintf(stderr
, "= Before =\n");
90 bool ret
= v
->opt_copy_propagation();
93 fprintf(stderr
, "\n= After =\n");
100 TEST_F(copy_propagation_test
, basic
)
102 const fs_builder
&bld
= v
->bld
;
103 fs_reg vgrf0
= v
->vgrf(glsl_type::float_type
);
104 fs_reg vgrf1
= v
->vgrf(glsl_type::float_type
);
105 fs_reg vgrf2
= v
->vgrf(glsl_type::float_type
);
106 fs_reg vgrf3
= v
->vgrf(glsl_type::float_type
);
107 bld
.MOV(vgrf0
, vgrf2
);
108 bld
.ADD(vgrf1
, vgrf0
, vgrf3
);
112 * 0: mov(8) vgrf0 vgrf2
113 * 1: add(8) vgrf1 vgrf0 vgrf3
116 * 0: mov(8) vgrf0 vgrf2
117 * 1: add(8) vgrf1 vgrf2 vgrf3
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(copy_propagation(v
));
127 EXPECT_EQ(0, block0
->start_ip
);
128 EXPECT_EQ(1, block0
->end_ip
);
130 fs_inst
*mov
= instruction(block0
, 0);
131 EXPECT_EQ(BRW_OPCODE_MOV
, mov
->opcode
);
132 EXPECT_TRUE(mov
->dst
.equals(vgrf0
));
133 EXPECT_TRUE(mov
->src
[0].equals(vgrf2
));
135 fs_inst
*add
= instruction(block0
, 1);
136 EXPECT_EQ(BRW_OPCODE_ADD
, add
->opcode
);
137 EXPECT_TRUE(add
->dst
.equals(vgrf1
));
138 EXPECT_TRUE(add
->src
[0].equals(vgrf2
));
139 EXPECT_TRUE(add
->src
[1].equals(vgrf3
));
142 TEST_F(copy_propagation_test
, maxmax_sat_imm
)
144 const fs_builder
&bld
= v
->bld
;
145 fs_reg vgrf0
= v
->vgrf(glsl_type::float_type
);
146 fs_reg vgrf1
= v
->vgrf(glsl_type::float_type
);
147 fs_reg vgrf2
= v
->vgrf(glsl_type::float_type
);
149 static const struct {
150 enum brw_conditional_mod conditional_mod
;
152 bool expected_result
;
154 /* conditional mod, imm, expected_result */
155 { BRW_CONDITIONAL_GE
, 0.1f
, true },
156 { BRW_CONDITIONAL_L
, 0.1f
, true },
157 { BRW_CONDITIONAL_GE
, 0.5f
, true },
158 { BRW_CONDITIONAL_L
, 0.5f
, true },
159 { BRW_CONDITIONAL_GE
, 0.9f
, true },
160 { BRW_CONDITIONAL_L
, 0.9f
, true },
161 { BRW_CONDITIONAL_GE
, -1.5f
, false },
162 { BRW_CONDITIONAL_L
, -1.5f
, false },
163 { BRW_CONDITIONAL_GE
, 1.5f
, false },
164 { BRW_CONDITIONAL_L
, 1.5f
, false },
166 { BRW_CONDITIONAL_NONE
, 0.5f
, false },
167 { BRW_CONDITIONAL_Z
, 0.5f
, false },
168 { BRW_CONDITIONAL_NZ
, 0.5f
, false },
169 { BRW_CONDITIONAL_G
, 0.5f
, false },
170 { BRW_CONDITIONAL_LE
, 0.5f
, false },
171 { BRW_CONDITIONAL_R
, 0.5f
, false },
172 { BRW_CONDITIONAL_O
, 0.5f
, false },
173 { BRW_CONDITIONAL_U
, 0.5f
, false },
176 for (unsigned i
= 0; i
< sizeof(test
) / sizeof(test
[0]); i
++) {
177 fs_inst
*mov
= set_saturate(true, bld
.MOV(vgrf0
, vgrf1
));
178 fs_inst
*sel
= set_condmod(test
[i
].conditional_mod
,
179 bld
.SEL(vgrf2
, vgrf0
,
180 brw_imm_f(test
[i
].immediate
)));
184 bblock_t
*block0
= v
->cfg
->blocks
[0];
186 EXPECT_EQ(0, block0
->start_ip
);
187 EXPECT_EQ(1, block0
->end_ip
);
189 EXPECT_EQ(test
[i
].expected_result
, copy_propagation(v
));
190 EXPECT_EQ(0, block0
->start_ip
);
191 EXPECT_EQ(1, block0
->end_ip
);
193 EXPECT_EQ(BRW_OPCODE_MOV
, mov
->opcode
);
194 EXPECT_TRUE(mov
->saturate
);
195 EXPECT_TRUE(mov
->dst
.equals(vgrf0
));
196 EXPECT_TRUE(mov
->src
[0].equals(vgrf1
));
198 EXPECT_EQ(BRW_OPCODE_SEL
, sel
->opcode
);
199 EXPECT_EQ(test
[i
].conditional_mod
, sel
->conditional_mod
);
200 EXPECT_EQ(test
[i
].expected_result
, sel
->saturate
);
201 EXPECT_TRUE(sel
->dst
.equals(vgrf2
));
202 if (test
[i
].expected_result
) {
203 EXPECT_TRUE(sel
->src
[0].equals(vgrf1
));
205 EXPECT_TRUE(sel
->src
[0].equals(vgrf0
));
207 EXPECT_TRUE(sel
->src
[1].equals(brw_imm_f(test
[i
].immediate
)));