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
, (struct gl_program
*) NULL
,
55 void copy_propagation_test::SetUp()
57 ctx
= (struct gl_context
*)calloc(1, sizeof(*ctx
));
58 compiler
= (struct brw_compiler
*)calloc(1, sizeof(*compiler
));
59 devinfo
= (struct gen_device_info
*)calloc(1, sizeof(*devinfo
));
60 compiler
->devinfo
= devinfo
;
62 prog_data
= ralloc(NULL
, struct brw_wm_prog_data
);
64 nir_shader_create(NULL
, MESA_SHADER_FRAGMENT
, NULL
, NULL
);
66 v
= new copy_propagation_fs_visitor(compiler
, prog_data
, shader
);
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 copy_propagation(fs_visitor
*v
)
84 const bool print
= getenv("TEST_DEBUG");
87 fprintf(stderr
, "= Before =\n");
91 bool ret
= v
->opt_copy_propagation();
94 fprintf(stderr
, "\n= After =\n");
101 TEST_F(copy_propagation_test
, basic
)
103 const fs_builder
&bld
= v
->bld
;
104 fs_reg vgrf0
= v
->vgrf(glsl_type::float_type
);
105 fs_reg vgrf1
= v
->vgrf(glsl_type::float_type
);
106 fs_reg vgrf2
= v
->vgrf(glsl_type::float_type
);
107 fs_reg vgrf3
= v
->vgrf(glsl_type::float_type
);
108 bld
.MOV(vgrf0
, vgrf2
);
109 bld
.ADD(vgrf1
, vgrf0
, vgrf3
);
113 * 0: mov(8) vgrf0 vgrf2
114 * 1: add(8) vgrf1 vgrf0 vgrf3
117 * 0: mov(8) vgrf0 vgrf2
118 * 1: add(8) vgrf1 vgrf2 vgrf3
122 bblock_t
*block0
= v
->cfg
->blocks
[0];
124 EXPECT_EQ(0, block0
->start_ip
);
125 EXPECT_EQ(1, block0
->end_ip
);
127 EXPECT_TRUE(copy_propagation(v
));
128 EXPECT_EQ(0, block0
->start_ip
);
129 EXPECT_EQ(1, block0
->end_ip
);
131 fs_inst
*mov
= instruction(block0
, 0);
132 EXPECT_EQ(BRW_OPCODE_MOV
, mov
->opcode
);
133 EXPECT_TRUE(mov
->dst
.equals(vgrf0
));
134 EXPECT_TRUE(mov
->src
[0].equals(vgrf2
));
136 fs_inst
*add
= instruction(block0
, 1);
137 EXPECT_EQ(BRW_OPCODE_ADD
, add
->opcode
);
138 EXPECT_TRUE(add
->dst
.equals(vgrf1
));
139 EXPECT_TRUE(add
->src
[0].equals(vgrf2
));
140 EXPECT_TRUE(add
->src
[1].equals(vgrf3
));
143 TEST_F(copy_propagation_test
, maxmax_sat_imm
)
145 const fs_builder
&bld
= v
->bld
;
146 fs_reg vgrf0
= v
->vgrf(glsl_type::float_type
);
147 fs_reg vgrf1
= v
->vgrf(glsl_type::float_type
);
148 fs_reg vgrf2
= v
->vgrf(glsl_type::float_type
);
150 static const struct {
151 enum brw_conditional_mod conditional_mod
;
153 bool expected_result
;
155 /* conditional mod, imm, expected_result */
156 { BRW_CONDITIONAL_GE
, 0.1f
, true },
157 { BRW_CONDITIONAL_L
, 0.1f
, true },
158 { BRW_CONDITIONAL_GE
, 0.5f
, true },
159 { BRW_CONDITIONAL_L
, 0.5f
, true },
160 { BRW_CONDITIONAL_GE
, 0.9f
, true },
161 { BRW_CONDITIONAL_L
, 0.9f
, true },
162 { BRW_CONDITIONAL_GE
, -1.5f
, false },
163 { BRW_CONDITIONAL_L
, -1.5f
, false },
164 { BRW_CONDITIONAL_GE
, 1.5f
, false },
165 { BRW_CONDITIONAL_L
, 1.5f
, false },
167 { BRW_CONDITIONAL_NONE
, 0.5f
, false },
168 { BRW_CONDITIONAL_Z
, 0.5f
, false },
169 { BRW_CONDITIONAL_NZ
, 0.5f
, false },
170 { BRW_CONDITIONAL_G
, 0.5f
, false },
171 { BRW_CONDITIONAL_LE
, 0.5f
, false },
172 { BRW_CONDITIONAL_R
, 0.5f
, false },
173 { BRW_CONDITIONAL_O
, 0.5f
, false },
174 { BRW_CONDITIONAL_U
, 0.5f
, false },
177 for (unsigned i
= 0; i
< sizeof(test
) / sizeof(test
[0]); i
++) {
178 fs_inst
*mov
= set_saturate(true, bld
.MOV(vgrf0
, vgrf1
));
179 fs_inst
*sel
= set_condmod(test
[i
].conditional_mod
,
180 bld
.SEL(vgrf2
, vgrf0
,
181 brw_imm_f(test
[i
].immediate
)));
185 bblock_t
*block0
= v
->cfg
->blocks
[0];
187 EXPECT_EQ(0, block0
->start_ip
);
188 EXPECT_EQ(1, block0
->end_ip
);
190 EXPECT_EQ(test
[i
].expected_result
, copy_propagation(v
));
191 EXPECT_EQ(0, block0
->start_ip
);
192 EXPECT_EQ(1, block0
->end_ip
);
194 EXPECT_EQ(BRW_OPCODE_MOV
, mov
->opcode
);
195 EXPECT_TRUE(mov
->saturate
);
196 EXPECT_TRUE(mov
->dst
.equals(vgrf0
));
197 EXPECT_TRUE(mov
->src
[0].equals(vgrf1
));
199 EXPECT_EQ(BRW_OPCODE_SEL
, sel
->opcode
);
200 EXPECT_EQ(test
[i
].conditional_mod
, sel
->conditional_mod
);
201 EXPECT_EQ(test
[i
].expected_result
, sel
->saturate
);
202 EXPECT_TRUE(sel
->dst
.equals(vgrf2
));
203 if (test
[i
].expected_result
) {
204 EXPECT_TRUE(sel
->src
[0].equals(vgrf1
));
206 EXPECT_TRUE(sel
->src
[0].equals(vgrf0
));
208 EXPECT_TRUE(sel
->src
[1].equals(brw_imm_f(test
[i
].immediate
)));