1 // Copyright (c) 2019 Google LLC.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <vector>
16
17 #include "gmock/gmock.h"
18 #include "test/opt/pass_fixture.h"
19 #include "test/opt/pass_utils.h"
20
21 namespace spvtools {
22 namespace opt {
23 namespace {
24
25 using AmdExtToKhrTest = PassTest<::testing::Test>;
26
27 using ::testing::HasSubstr;
28
GetTest(std::string op_code,std::string new_op_code,bool is_float=false)29 std::string GetTest(std::string op_code, std::string new_op_code,
30 bool is_float = false) {
31 const std::string text = R"(
32 ; CHECK: OpCapability Shader
33 ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
34 ; CHECK: OpFunction
35 ; CHECK-NEXT: OpLabel
36 ; CHECK-NEXT: [[undef:%\w+]] = OpUndef %
37 ; CHECK-NEXT: )" + new_op_code +
38 " %" + (is_float ? "float" : "uint") +
39 R"( %uint_3 Reduce [[undef]]
40 OpCapability Shader
41 OpCapability Groups
42 OpExtension "SPV_AMD_shader_ballot"
43 OpMemoryModel Logical GLSL450
44 OpEntryPoint Fragment %1 "func"
45 OpExecutionMode %1 OriginUpperLeft
46 %void = OpTypeVoid
47 %3 = OpTypeFunction %void
48 %uint = OpTypeInt 32 0
49 %float = OpTypeFloat 32
50 %uint_3 = OpConstant %uint 3
51 %1 = OpFunction %void None %3
52 %6 = OpLabel
53 %7 = OpUndef %)" +
54 (is_float ? "float" : "uint") + R"(
55 %8 = )" + op_code +
56 " %" + (is_float ? "float" : "uint") +
57 R"( %uint_3 Reduce %7
58 OpReturn
59 OpFunctionEnd
60
61 )";
62 return text;
63 }
64
TEST_F(AmdExtToKhrTest,ReplaceGroupIAddNonUniformAMD)65 TEST_F(AmdExtToKhrTest, ReplaceGroupIAddNonUniformAMD) {
66 std::string text =
67 GetTest("OpGroupIAddNonUniformAMD", "OpGroupNonUniformIAdd");
68 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
69 }
TEST_F(AmdExtToKhrTest,ReplaceGroupFAddNonUniformAMD)70 TEST_F(AmdExtToKhrTest, ReplaceGroupFAddNonUniformAMD) {
71 std::string text =
72 GetTest("OpGroupFAddNonUniformAMD", "OpGroupNonUniformFAdd", true);
73 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
74 }
TEST_F(AmdExtToKhrTest,ReplaceGroupUMinNonUniformAMD)75 TEST_F(AmdExtToKhrTest, ReplaceGroupUMinNonUniformAMD) {
76 std::string text =
77 GetTest("OpGroupUMinNonUniformAMD", "OpGroupNonUniformUMin");
78 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
79 }
TEST_F(AmdExtToKhrTest,ReplaceGroupSMinNonUniformAMD)80 TEST_F(AmdExtToKhrTest, ReplaceGroupSMinNonUniformAMD) {
81 std::string text =
82 GetTest("OpGroupSMinNonUniformAMD", "OpGroupNonUniformSMin");
83 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
84 }
TEST_F(AmdExtToKhrTest,ReplaceGroupFMinNonUniformAMD)85 TEST_F(AmdExtToKhrTest, ReplaceGroupFMinNonUniformAMD) {
86 std::string text =
87 GetTest("OpGroupFMinNonUniformAMD", "OpGroupNonUniformFMin", true);
88 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
89 }
TEST_F(AmdExtToKhrTest,ReplaceGroupUMaxNonUniformAMD)90 TEST_F(AmdExtToKhrTest, ReplaceGroupUMaxNonUniformAMD) {
91 std::string text =
92 GetTest("OpGroupUMaxNonUniformAMD", "OpGroupNonUniformUMax");
93 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
94 }
TEST_F(AmdExtToKhrTest,ReplaceGroupSMaxNonUniformAMD)95 TEST_F(AmdExtToKhrTest, ReplaceGroupSMaxNonUniformAMD) {
96 std::string text =
97 GetTest("OpGroupSMaxNonUniformAMD", "OpGroupNonUniformSMax");
98 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
99 }
TEST_F(AmdExtToKhrTest,ReplaceGroupFMaxNonUniformAMD)100 TEST_F(AmdExtToKhrTest, ReplaceGroupFMaxNonUniformAMD) {
101 std::string text =
102 GetTest("OpGroupFMaxNonUniformAMD", "OpGroupNonUniformFMax", true);
103 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
104 }
105
TEST_F(AmdExtToKhrTest,ReplaceMbcntAMD)106 TEST_F(AmdExtToKhrTest, ReplaceMbcntAMD) {
107 const std::string text = R"(
108 ; CHECK: OpCapability Shader
109 ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
110 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_ballot"
111 ; CHECK: OpDecorate [[var:%\w+]] BuiltIn SubgroupLtMask
112 ; CHECK: [[var]] = OpVariable %_ptr_Input_v4uint Input
113 ; CHECK: OpFunction
114 ; CHECK-NEXT: OpLabel
115 ; CHECK-NEXT: [[ld:%\w+]] = OpLoad %v4uint [[var]]
116 ; CHECK-NEXT: [[shuffle:%\w+]] = OpVectorShuffle %v2uint [[ld]] [[ld]] 0 1
117 ; CHECK-NEXT: [[bitcast:%\w+]] = OpBitcast %ulong [[shuffle]]
118 ; CHECK-NEXT: [[and:%\w+]] = OpBitwiseAnd %ulong [[bitcast]] %ulong_0
119 ; CHECK-NEXT: [[result:%\w+]] = OpBitCount %uint [[and]]
120 OpCapability Shader
121 OpCapability Int64
122 OpExtension "SPV_AMD_shader_ballot"
123 %1 = OpExtInstImport "SPV_AMD_shader_ballot"
124 OpMemoryModel Logical GLSL450
125 OpEntryPoint Fragment %2 "func"
126 OpExecutionMode %2 OriginUpperLeft
127 %void = OpTypeVoid
128 %4 = OpTypeFunction %void
129 %uint = OpTypeInt 32 0
130 %ulong = OpTypeInt 64 0
131 %ulong_0 = OpConstant %ulong 0
132 %2 = OpFunction %void None %4
133 %8 = OpLabel
134 %9 = OpExtInst %uint %1 MbcntAMD %ulong_0
135 OpReturn
136 OpFunctionEnd
137 )";
138
139 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
140 }
141
TEST_F(AmdExtToKhrTest,ReplaceSwizzleInvocationsAMD)142 TEST_F(AmdExtToKhrTest, ReplaceSwizzleInvocationsAMD) {
143 const std::string text = R"(
144 ; CHECK: OpCapability Shader
145 ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
146 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_ballot"
147 ; CHECK: OpDecorate [[var:%\w+]] BuiltIn SubgroupLocalInvocationId
148 ; CHECK: [[subgroup:%\w+]] = OpConstant %uint 3
149 ; CHECK: [[offset:%\w+]] = OpConstantComposite %v4uint
150 ; CHECK: [[var]] = OpVariable %_ptr_Input_uint Input
151 ; CHECK: [[uint_max:%\w+]] = OpConstant %uint 4294967295
152 ; CHECK: [[ballot_value:%\w+]] = OpConstantComposite %v4uint [[uint_max]] [[uint_max]] [[uint_max]] [[uint_max]]
153 ; CHECK: [[null:%\w+]] = OpConstantNull [[type:%\w+]]
154 ; CHECK: OpFunction
155 ; CHECK-NEXT: OpLabel
156 ; CHECK-NEXT: [[data:%\w+]] = OpUndef [[type]]
157 ; CHECK-NEXT: [[id:%\w+]] = OpLoad %uint [[var]]
158 ; CHECK-NEXT: [[quad_idx:%\w+]] = OpBitwiseAnd %uint [[id]] %uint_3
159 ; CHECK-NEXT: [[quad_ldr:%\w+]] = OpBitwiseXor %uint [[id]] [[quad_idx]]
160 ; CHECK-NEXT: [[my_offset:%\w+]] = OpVectorExtractDynamic %uint [[offset]] [[quad_idx]]
161 ; CHECK-NEXT: [[target_inv:%\w+]] = OpIAdd %uint [[quad_ldr]] [[my_offset]]
162 ; CHECK-NEXT: [[is_active:%\w+]] = OpGroupNonUniformBallotBitExtract %bool [[subgroup]] [[ballot_value]] [[target_inv]]
163 ; CHECK-NEXT: [[shuffle:%\w+]] = OpGroupNonUniformShuffle [[type]] [[subgroup]] [[data]] [[target_inv]]
164 ; CHECK-NEXT: [[result:%\w+]] = OpSelect [[type]] [[is_active]] [[shuffle]] [[null]]
165 OpCapability Shader
166 OpExtension "SPV_AMD_shader_ballot"
167 %ext = OpExtInstImport "SPV_AMD_shader_ballot"
168 OpMemoryModel Logical GLSL450
169 OpEntryPoint Fragment %1 "func"
170 OpExecutionMode %1 OriginUpperLeft
171 %void = OpTypeVoid
172 %3 = OpTypeFunction %void
173 %uint = OpTypeInt 32 0
174 %uint_x = OpConstant %uint 1
175 %uint_y = OpConstant %uint 2
176 %uint_z = OpConstant %uint 3
177 %uint_w = OpConstant %uint 0
178 %v4uint = OpTypeVector %uint 4
179 %offset = OpConstantComposite %v4uint %uint_x %uint_y %uint_z %uint_x
180 %1 = OpFunction %void None %3
181 %6 = OpLabel
182 %data = OpUndef %uint
183 %9 = OpExtInst %uint %ext SwizzleInvocationsAMD %data %offset
184 OpReturn
185 OpFunctionEnd
186 )";
187
188 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
189 }
TEST_F(AmdExtToKhrTest,ReplaceSwizzleInvocationsMaskedAMD)190 TEST_F(AmdExtToKhrTest, ReplaceSwizzleInvocationsMaskedAMD) {
191 const std::string text = R"(
192 ; CHECK: OpCapability Shader
193 ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
194 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_ballot"
195 ; CHECK: OpDecorate [[var:%\w+]] BuiltIn SubgroupLocalInvocationId
196 ; CHECK: [[x:%\w+]] = OpConstant %uint 19
197 ; CHECK: [[y:%\w+]] = OpConstant %uint 12
198 ; CHECK: [[z:%\w+]] = OpConstant %uint 16
199 ; CHECK: [[var]] = OpVariable %_ptr_Input_uint Input
200 ; CHECK: [[mask_extend:%\w+]] = OpConstant %uint 4294967264
201 ; CHECK: [[uint_max:%\w+]] = OpConstant %uint 4294967295
202 ; CHECK: [[subgroup:%\w+]] = OpConstant %uint 3
203 ; CHECK: [[ballot_value:%\w+]] = OpConstantComposite %v4uint [[uint_max]] [[uint_max]] [[uint_max]] [[uint_max]]
204 ; CHECK: [[null:%\w+]] = OpConstantNull [[type:%\w+]]
205 ; CHECK: OpFunction
206 ; CHECK-NEXT: OpLabel
207 ; CHECK-NEXT: [[data:%\w+]] = OpUndef [[type]]
208 ; CHECK-NEXT: [[id:%\w+]] = OpLoad %uint [[var]]
209 ; CHECK-NEXT: [[and_mask:%\w+]] = OpBitwiseOr %uint [[x]] [[mask_extend]]
210 ; CHECK-NEXT: [[and:%\w+]] = OpBitwiseAnd %uint [[id]] [[and_mask]]
211 ; CHECK-NEXT: [[or:%\w+]] = OpBitwiseOr %uint [[and]] [[y]]
212 ; CHECK-NEXT: [[target_inv:%\w+]] = OpBitwiseXor %uint [[or]] [[z]]
213 ; CHECK-NEXT: [[is_active:%\w+]] = OpGroupNonUniformBallotBitExtract %bool [[subgroup]] [[ballot_value]] [[target_inv]]
214 ; CHECK-NEXT: [[shuffle:%\w+]] = OpGroupNonUniformShuffle [[type]] [[subgroup]] [[data]] [[target_inv]]
215 ; CHECK-NEXT: [[result:%\w+]] = OpSelect [[type]] [[is_active]] [[shuffle]] [[null]]
216 OpCapability Shader
217 OpExtension "SPV_AMD_shader_ballot"
218 %ext = OpExtInstImport "SPV_AMD_shader_ballot"
219 OpMemoryModel Logical GLSL450
220 OpEntryPoint Fragment %1 "func"
221 OpExecutionMode %1 OriginUpperLeft
222 %void = OpTypeVoid
223 %3 = OpTypeFunction %void
224 %uint = OpTypeInt 32 0
225 %uint_x = OpConstant %uint 19
226 %uint_y = OpConstant %uint 12
227 %uint_z = OpConstant %uint 16
228 %v3uint = OpTypeVector %uint 3
229 %mask = OpConstantComposite %v3uint %uint_x %uint_y %uint_z
230 %1 = OpFunction %void None %3
231 %6 = OpLabel
232 %data = OpUndef %uint
233 %9 = OpExtInst %uint %ext SwizzleInvocationsMaskedAMD %data %mask
234 OpReturn
235 OpFunctionEnd
236 )";
237
238 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
239 }
240
TEST_F(AmdExtToKhrTest,ReplaceWriteInvocationAMD)241 TEST_F(AmdExtToKhrTest, ReplaceWriteInvocationAMD) {
242 const std::string text = R"(
243 ; CHECK: OpCapability Shader
244 ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
245 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_ballot"
246 ; CHECK: OpDecorate [[var:%\w+]] BuiltIn SubgroupLocalInvocationId
247 ; CHECK: [[var]] = OpVariable %_ptr_Input_uint Input
248 ; CHECK: OpFunction
249 ; CHECK-NEXT: OpLabel
250 ; CHECK-NEXT: [[input_val:%\w+]] = OpUndef %uint
251 ; CHECK-NEXT: [[write_val:%\w+]] = OpUndef %uint
252 ; CHECK-NEXT: [[ld:%\w+]] = OpLoad %uint [[var]]
253 ; CHECK-NEXT: [[cmp:%\w+]] = OpIEqual %bool [[ld]] %uint_3
254 ; CHECK-NEXT: [[result:%\w+]] = OpSelect %uint [[cmp]] [[write_val]] [[input_val]]
255 OpCapability Shader
256 OpExtension "SPV_AMD_shader_ballot"
257 %ext = OpExtInstImport "SPV_AMD_shader_ballot"
258 OpMemoryModel Logical GLSL450
259 OpEntryPoint Fragment %1 "func"
260 OpExecutionMode %1 OriginUpperLeft
261 %void = OpTypeVoid
262 %3 = OpTypeFunction %void
263 %uint = OpTypeInt 32 0
264 %uint_3 = OpConstant %uint 3
265 %1 = OpFunction %void None %3
266 %6 = OpLabel
267 %7 = OpUndef %uint
268 %8 = OpUndef %uint
269 %9 = OpExtInst %uint %ext WriteInvocationAMD %7 %8 %uint_3
270 OpReturn
271 OpFunctionEnd
272 )";
273
274 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
275 }
276
TEST_F(AmdExtToKhrTest,ReplaceFMin3AMD)277 TEST_F(AmdExtToKhrTest, ReplaceFMin3AMD) {
278 const std::string text = R"(
279 ; CHECK: OpCapability Shader
280 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
281 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
282 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
283 ; CHECK: [[type:%\w+]] = OpTypeFloat 32
284 ; CHECK: OpFunction
285 ; CHECK-NEXT: OpLabel
286 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
287 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
288 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
289 ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] FMin [[x]] [[y]]
290 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] FMin [[temp]] [[z]]
291 OpCapability Shader
292 OpExtension "SPV_AMD_shader_trinary_minmax"
293 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
294 OpMemoryModel Logical GLSL450
295 OpEntryPoint Fragment %1 "func"
296 OpExecutionMode %1 OriginUpperLeft
297 %void = OpTypeVoid
298 %3 = OpTypeFunction %void
299 %uint = OpTypeInt 32 0
300 %float = OpTypeFloat 32
301 %uint_3 = OpConstant %uint 3
302 %1 = OpFunction %void None %3
303 %6 = OpLabel
304 %7 = OpUndef %float
305 %8 = OpUndef %float
306 %9 = OpUndef %float
307 %10 = OpExtInst %float %ext FMin3AMD %7 %8 %9
308 OpReturn
309 OpFunctionEnd
310 )";
311
312 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
313 }
314
TEST_F(AmdExtToKhrTest,ReplaceSMin3AMD)315 TEST_F(AmdExtToKhrTest, ReplaceSMin3AMD) {
316 const std::string text = R"(
317 ; CHECK: OpCapability Shader
318 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
319 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
320 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
321 ; CHECK: [[type:%\w+]] = OpTypeInt 32 1
322 ; CHECK: OpFunction
323 ; CHECK-NEXT: OpLabel
324 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
325 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
326 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
327 ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] SMin [[x]] [[y]]
328 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] SMin [[temp]] [[z]]
329 OpCapability Shader
330 OpExtension "SPV_AMD_shader_trinary_minmax"
331 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
332 OpMemoryModel Logical GLSL450
333 OpEntryPoint Fragment %1 "func"
334 OpExecutionMode %1 OriginUpperLeft
335 %void = OpTypeVoid
336 %3 = OpTypeFunction %void
337 %uint = OpTypeInt 32 0
338 %int = OpTypeInt 32 1
339 %float = OpTypeFloat 32
340 %uint_3 = OpConstant %uint 3
341 %1 = OpFunction %void None %3
342 %6 = OpLabel
343 %7 = OpUndef %int
344 %8 = OpUndef %int
345 %9 = OpUndef %int
346 %10 = OpExtInst %int %ext SMin3AMD %7 %8 %9
347 OpReturn
348 OpFunctionEnd
349 )";
350
351 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
352 }
353
TEST_F(AmdExtToKhrTest,ReplaceUMin3AMD)354 TEST_F(AmdExtToKhrTest, ReplaceUMin3AMD) {
355 const std::string text = R"(
356 ; CHECK: OpCapability Shader
357 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
358 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
359 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
360 ; CHECK: [[type:%\w+]] = OpTypeInt 32 0
361 ; CHECK: OpFunction
362 ; CHECK-NEXT: OpLabel
363 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
364 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
365 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
366 ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] UMin [[x]] [[y]]
367 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UMin [[temp]] [[z]]
368 OpCapability Shader
369 OpExtension "SPV_AMD_shader_trinary_minmax"
370 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
371 OpMemoryModel Logical GLSL450
372 OpEntryPoint Fragment %1 "func"
373 OpExecutionMode %1 OriginUpperLeft
374 %void = OpTypeVoid
375 %3 = OpTypeFunction %void
376 %uint = OpTypeInt 32 0
377 %int = OpTypeInt 32 1
378 %float = OpTypeFloat 32
379 %uint_3 = OpConstant %uint 3
380 %1 = OpFunction %void None %3
381 %6 = OpLabel
382 %7 = OpUndef %uint
383 %8 = OpUndef %uint
384 %9 = OpUndef %uint
385 %10 = OpExtInst %uint %ext UMin3AMD %7 %8 %9
386 OpReturn
387 OpFunctionEnd
388 )";
389
390 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
391 }
392
TEST_F(AmdExtToKhrTest,ReplaceFMax3AMD)393 TEST_F(AmdExtToKhrTest, ReplaceFMax3AMD) {
394 const std::string text = R"(
395 ; CHECK: OpCapability Shader
396 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
397 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
398 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
399 ; CHECK: [[type:%\w+]] = OpTypeFloat 32
400 ; CHECK: OpFunction
401 ; CHECK-NEXT: OpLabel
402 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
403 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
404 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
405 ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] FMax [[x]] [[y]]
406 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] FMax [[temp]] [[z]]
407 OpCapability Shader
408 OpExtension "SPV_AMD_shader_trinary_minmax"
409 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
410 OpMemoryModel Logical GLSL450
411 OpEntryPoint Fragment %1 "func"
412 OpExecutionMode %1 OriginUpperLeft
413 %void = OpTypeVoid
414 %3 = OpTypeFunction %void
415 %uint = OpTypeInt 32 0
416 %float = OpTypeFloat 32
417 %uint_3 = OpConstant %uint 3
418 %1 = OpFunction %void None %3
419 %6 = OpLabel
420 %7 = OpUndef %float
421 %8 = OpUndef %float
422 %9 = OpUndef %float
423 %10 = OpExtInst %float %ext FMax3AMD %7 %8 %9
424 OpReturn
425 OpFunctionEnd
426 )";
427
428 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
429 }
430
TEST_F(AmdExtToKhrTest,ReplaceSMax3AMD)431 TEST_F(AmdExtToKhrTest, ReplaceSMax3AMD) {
432 const std::string text = R"(
433 ; CHECK: OpCapability Shader
434 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
435 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
436 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
437 ; CHECK: [[type:%\w+]] = OpTypeInt 32 1
438 ; CHECK: OpFunction
439 ; CHECK-NEXT: OpLabel
440 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
441 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
442 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
443 ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] SMax [[x]] [[y]]
444 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] SMax [[temp]] [[z]]
445 OpCapability Shader
446 OpExtension "SPV_AMD_shader_trinary_minmax"
447 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
448 OpMemoryModel Logical GLSL450
449 OpEntryPoint Fragment %1 "func"
450 OpExecutionMode %1 OriginUpperLeft
451 %void = OpTypeVoid
452 %3 = OpTypeFunction %void
453 %uint = OpTypeInt 32 0
454 %int = OpTypeInt 32 1
455 %float = OpTypeFloat 32
456 %uint_3 = OpConstant %uint 3
457 %1 = OpFunction %void None %3
458 %6 = OpLabel
459 %7 = OpUndef %int
460 %8 = OpUndef %int
461 %9 = OpUndef %int
462 %10 = OpExtInst %int %ext SMax3AMD %7 %8 %9
463 OpReturn
464 OpFunctionEnd
465 )";
466
467 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
468 }
469
TEST_F(AmdExtToKhrTest,ReplaceUMax3AMD)470 TEST_F(AmdExtToKhrTest, ReplaceUMax3AMD) {
471 const std::string text = R"(
472 ; CHECK: OpCapability Shader
473 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
474 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
475 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
476 ; CHECK: [[type:%\w+]] = OpTypeInt 32 0
477 ; CHECK: OpFunction
478 ; CHECK-NEXT: OpLabel
479 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
480 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
481 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
482 ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[x]] [[y]]
483 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[temp]] [[z]]
484 OpCapability Shader
485 OpExtension "SPV_AMD_shader_trinary_minmax"
486 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
487 OpMemoryModel Logical GLSL450
488 OpEntryPoint Fragment %1 "func"
489 OpExecutionMode %1 OriginUpperLeft
490 %void = OpTypeVoid
491 %3 = OpTypeFunction %void
492 %uint = OpTypeInt 32 0
493 %int = OpTypeInt 32 1
494 %float = OpTypeFloat 32
495 %uint_3 = OpConstant %uint 3
496 %1 = OpFunction %void None %3
497 %6 = OpLabel
498 %7 = OpUndef %uint
499 %8 = OpUndef %uint
500 %9 = OpUndef %uint
501 %10 = OpExtInst %uint %ext UMax3AMD %7 %8 %9
502 OpReturn
503 OpFunctionEnd
504 )";
505
506 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
507 }
508
TEST_F(AmdExtToKhrTest,ReplaceVecUMax3AMD)509 TEST_F(AmdExtToKhrTest, ReplaceVecUMax3AMD) {
510 const std::string text = R"(
511 ; CHECK: OpCapability Shader
512 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
513 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
514 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
515 ; CHECK: [[type:%\w+]] = OpTypeVector
516 ; CHECK: OpFunction
517 ; CHECK-NEXT: OpLabel
518 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
519 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
520 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
521 ; CHECK-NEXT: [[temp:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[x]] [[y]]
522 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[temp]] [[z]]
523 OpCapability Shader
524 OpExtension "SPV_AMD_shader_trinary_minmax"
525 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
526 OpMemoryModel Logical GLSL450
527 OpEntryPoint Fragment %1 "func"
528 OpExecutionMode %1 OriginUpperLeft
529 %void = OpTypeVoid
530 %3 = OpTypeFunction %void
531 %uint = OpTypeInt 32 0
532 %vec = OpTypeVector %uint 4
533 %int = OpTypeInt 32 1
534 %float = OpTypeFloat 32
535 %uint_3 = OpConstant %uint 3
536 %1 = OpFunction %void None %3
537 %6 = OpLabel
538 %7 = OpUndef %vec
539 %8 = OpUndef %vec
540 %9 = OpUndef %vec
541 %10 = OpExtInst %vec %ext UMax3AMD %7 %8 %9
542 OpReturn
543 OpFunctionEnd
544 )";
545
546 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
547 }
548
TEST_F(AmdExtToKhrTest,ReplaceFMid3AMD)549 TEST_F(AmdExtToKhrTest, ReplaceFMid3AMD) {
550 const std::string text = R"(
551 ; CHECK: OpCapability Shader
552 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
553 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
554 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
555 ; CHECK: [[type:%\w+]] = OpTypeFloat 32
556 ; CHECK: OpFunction
557 ; CHECK-NEXT: OpLabel
558 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
559 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
560 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
561 ; CHECK-NEXT: [[min:%\w+]] = OpExtInst [[type]] [[ext]] FMin [[y]] [[z]]
562 ; CHECK-NEXT: [[max:%\w+]] = OpExtInst [[type]] [[ext]] FMax [[y]] [[z]]
563 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] FClamp [[x]] [[min]] [[max]]
564 OpCapability Shader
565 OpExtension "SPV_AMD_shader_trinary_minmax"
566 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
567 OpMemoryModel Logical GLSL450
568 OpEntryPoint Fragment %1 "func"
569 OpExecutionMode %1 OriginUpperLeft
570 %void = OpTypeVoid
571 %3 = OpTypeFunction %void
572 %uint = OpTypeInt 32 0
573 %float = OpTypeFloat 32
574 %uint_3 = OpConstant %uint 3
575 %1 = OpFunction %void None %3
576 %6 = OpLabel
577 %7 = OpUndef %float
578 %8 = OpUndef %float
579 %9 = OpUndef %float
580 %10 = OpExtInst %float %ext FMid3AMD %7 %8 %9
581 OpReturn
582 OpFunctionEnd
583 )";
584
585 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
586 }
587
TEST_F(AmdExtToKhrTest,ReplaceSMid3AMD)588 TEST_F(AmdExtToKhrTest, ReplaceSMid3AMD) {
589 const std::string text = R"(
590 ; CHECK: OpCapability Shader
591 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
592 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
593 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
594 ; CHECK: [[type:%\w+]] = OpTypeInt 32 1
595 ; CHECK: OpFunction
596 ; CHECK-NEXT: OpLabel
597 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
598 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
599 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
600 ; CHECK-NEXT: [[min:%\w+]] = OpExtInst [[type]] [[ext]] SMin [[y]] [[z]]
601 ; CHECK-NEXT: [[max:%\w+]] = OpExtInst [[type]] [[ext]] SMax [[y]] [[z]]
602 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] SClamp [[x]] [[min]] [[max]]
603 OpCapability Shader
604 OpExtension "SPV_AMD_shader_trinary_minmax"
605 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
606 OpMemoryModel Logical GLSL450
607 OpEntryPoint Fragment %1 "func"
608 OpExecutionMode %1 OriginUpperLeft
609 %void = OpTypeVoid
610 %3 = OpTypeFunction %void
611 %uint = OpTypeInt 32 0
612 %int = OpTypeInt 32 1
613 %float = OpTypeFloat 32
614 %uint_3 = OpConstant %uint 3
615 %1 = OpFunction %void None %3
616 %6 = OpLabel
617 %7 = OpUndef %int
618 %8 = OpUndef %int
619 %9 = OpUndef %int
620 %10 = OpExtInst %int %ext SMid3AMD %7 %8 %9
621 OpReturn
622 OpFunctionEnd
623 )";
624
625 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
626 }
627
TEST_F(AmdExtToKhrTest,ReplaceUMid3AMD)628 TEST_F(AmdExtToKhrTest, ReplaceUMid3AMD) {
629 const std::string text = R"(
630 ; CHECK: OpCapability Shader
631 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
632 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
633 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
634 ; CHECK: [[type:%\w+]] = OpTypeInt 32 0
635 ; CHECK: OpFunction
636 ; CHECK-NEXT: OpLabel
637 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
638 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
639 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
640 ; CHECK-NEXT: [[min:%\w+]] = OpExtInst [[type]] [[ext]] UMin [[y]] [[z]]
641 ; CHECK-NEXT: [[max:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[y]] [[z]]
642 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UClamp [[x]] [[min]] [[max]]
643 OpCapability Shader
644 OpExtension "SPV_AMD_shader_trinary_minmax"
645 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
646 OpMemoryModel Logical GLSL450
647 OpEntryPoint Fragment %1 "func"
648 OpExecutionMode %1 OriginUpperLeft
649 %void = OpTypeVoid
650 %3 = OpTypeFunction %void
651 %uint = OpTypeInt 32 0
652 %int = OpTypeInt 32 1
653 %float = OpTypeFloat 32
654 %uint_3 = OpConstant %uint 3
655 %1 = OpFunction %void None %3
656 %6 = OpLabel
657 %7 = OpUndef %uint
658 %8 = OpUndef %uint
659 %9 = OpUndef %uint
660 %10 = OpExtInst %uint %ext UMid3AMD %7 %8 %9
661 OpReturn
662 OpFunctionEnd
663 )";
664
665 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
666 }
667
TEST_F(AmdExtToKhrTest,ReplaceVecUMid3AMD)668 TEST_F(AmdExtToKhrTest, ReplaceVecUMid3AMD) {
669 const std::string text = R"(
670 ; CHECK: OpCapability Shader
671 ; CHECK-NOT: OpExtension "SPV_AMD_shader_trinary_minmax"
672 ; CHECK-NOT: OpExtInstImport "SPV_AMD_shader_trinary_minmax"
673 ; CHECK: [[ext:%\w+]] = OpExtInstImport "GLSL.std.450"
674 ; CHECK: [[type:%\w+]] = OpTypeVector
675 ; CHECK: OpFunction
676 ; CHECK-NEXT: OpLabel
677 ; CHECK-NEXT: [[x:%\w+]] = OpUndef [[type]]
678 ; CHECK-NEXT: [[y:%\w+]] = OpUndef [[type]]
679 ; CHECK-NEXT: [[z:%\w+]] = OpUndef [[type]]
680 ; CHECK-NEXT: [[min:%\w+]] = OpExtInst [[type]] [[ext]] UMin [[y]] [[z]]
681 ; CHECK-NEXT: [[max:%\w+]] = OpExtInst [[type]] [[ext]] UMax [[y]] [[z]]
682 ; CHECK-NEXT: [[result:%\w+]] = OpExtInst [[type]] [[ext]] UClamp [[x]] [[min]] [[max]]
683 OpCapability Shader
684 OpExtension "SPV_AMD_shader_trinary_minmax"
685 %ext = OpExtInstImport "SPV_AMD_shader_trinary_minmax"
686 OpMemoryModel Logical GLSL450
687 OpEntryPoint Fragment %1 "func"
688 OpExecutionMode %1 OriginUpperLeft
689 %void = OpTypeVoid
690 %3 = OpTypeFunction %void
691 %uint = OpTypeInt 32 0
692 %vec = OpTypeVector %uint 3
693 %int = OpTypeInt 32 1
694 %float = OpTypeFloat 32
695 %uint_3 = OpConstant %uint 3
696 %1 = OpFunction %void None %3
697 %6 = OpLabel
698 %7 = OpUndef %vec
699 %8 = OpUndef %vec
700 %9 = OpUndef %vec
701 %10 = OpExtInst %vec %ext UMid3AMD %7 %8 %9
702 OpReturn
703 OpFunctionEnd
704 )";
705
706 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
707 }
708
TEST_F(AmdExtToKhrTest,ReplaceCubeFaceCoordAMD)709 TEST_F(AmdExtToKhrTest, ReplaceCubeFaceCoordAMD) {
710 // Sorry for the Check test. The code sequence is so long, I do not think
711 // that a match test would be anymore legible. This tests the replacement of
712 // the CubeFaceCoordAMD instruction.
713 const std::string before = R"(
714 OpCapability Shader
715 OpExtension "SPV_KHR_storage_buffer_storage_class"
716 OpExtension "SPV_AMD_gcn_shader"
717 %1 = OpExtInstImport "SPV_AMD_gcn_shader"
718 OpMemoryModel Logical GLSL450
719 OpEntryPoint GLCompute %2 "main"
720 OpExecutionMode %2 LocalSize 1 1 1
721 %void = OpTypeVoid
722 %4 = OpTypeFunction %void
723 %float = OpTypeFloat 32
724 %v2float = OpTypeVector %float 2
725 %v3float = OpTypeVector %float 3
726 %2 = OpFunction %void None %4
727 %8 = OpLabel
728 %9 = OpUndef %v3float
729 %10 = OpExtInst %v2float %1 CubeFaceCoordAMD %9
730 OpReturn
731 OpFunctionEnd
732 )";
733
734 const std::string after = R"(OpCapability Shader
735 OpExtension "SPV_KHR_storage_buffer_storage_class"
736 %12 = OpExtInstImport "GLSL.std.450"
737 OpMemoryModel Logical GLSL450
738 OpEntryPoint GLCompute %2 "main"
739 OpExecutionMode %2 LocalSize 1 1 1
740 %void = OpTypeVoid
741 %4 = OpTypeFunction %void
742 %float = OpTypeFloat 32
743 %v2float = OpTypeVector %float 2
744 %v3float = OpTypeVector %float 3
745 %bool = OpTypeBool
746 %float_0 = OpConstant %float 0
747 %float_2 = OpConstant %float 2
748 %float_0_5 = OpConstant %float 0.5
749 %16 = OpConstantComposite %v2float %float_0_5 %float_0_5
750 %2 = OpFunction %void None %4
751 %8 = OpLabel
752 %9 = OpUndef %v3float
753 %17 = OpCompositeExtract %float %9 0
754 %18 = OpCompositeExtract %float %9 1
755 %19 = OpCompositeExtract %float %9 2
756 %20 = OpFNegate %float %17
757 %21 = OpFNegate %float %18
758 %22 = OpFNegate %float %19
759 %23 = OpExtInst %float %12 FAbs %17
760 %24 = OpExtInst %float %12 FAbs %18
761 %25 = OpExtInst %float %12 FAbs %19
762 %26 = OpFOrdLessThan %bool %19 %float_0
763 %27 = OpFOrdLessThan %bool %18 %float_0
764 %28 = OpFOrdLessThan %bool %17 %float_0
765 %29 = OpExtInst %float %12 FMax %23 %24
766 %30 = OpExtInst %float %12 FMax %25 %29
767 %31 = OpFMul %float %float_2 %30
768 %32 = OpFOrdGreaterThanEqual %bool %25 %29
769 %33 = OpLogicalNot %bool %32
770 %34 = OpFOrdGreaterThanEqual %bool %24 %23
771 %35 = OpLogicalAnd %bool %33 %34
772 %36 = OpSelect %float %26 %20 %17
773 %37 = OpSelect %float %28 %19 %22
774 %38 = OpSelect %float %35 %17 %37
775 %39 = OpSelect %float %32 %36 %38
776 %40 = OpSelect %float %27 %22 %19
777 %41 = OpSelect %float %35 %40 %21
778 %42 = OpCompositeConstruct %v2float %39 %41
779 %43 = OpCompositeConstruct %v2float %31 %31
780 %44 = OpFDiv %v2float %42 %43
781 %10 = OpFAdd %v2float %44 %16
782 OpReturn
783 OpFunctionEnd
784 )";
785
786 SinglePassRunAndCheck<AmdExtensionToKhrPass>(before, after, true);
787 }
788
TEST_F(AmdExtToKhrTest,ReplaceCubeFaceIndexAMD)789 TEST_F(AmdExtToKhrTest, ReplaceCubeFaceIndexAMD) {
790 // Sorry for the Check test. The code sequence is so long, I do not think
791 // that a match test would be anymore legible. This tests the replacement of
792 // the CubeFaceIndexAMD instruction.
793 const std::string before = R"(OpCapability Shader
794 OpExtension "SPV_KHR_storage_buffer_storage_class"
795 OpExtension "SPV_AMD_gcn_shader"
796 %1 = OpExtInstImport "SPV_AMD_gcn_shader"
797 OpMemoryModel Logical GLSL450
798 OpEntryPoint GLCompute %2 "main"
799 OpExecutionMode %2 LocalSize 1 1 1
800 %void = OpTypeVoid
801 %4 = OpTypeFunction %void
802 %float = OpTypeFloat 32
803 %v3float = OpTypeVector %float 3
804 %2 = OpFunction %void None %4
805 %7 = OpLabel
806 %8 = OpUndef %v3float
807 %9 = OpExtInst %float %1 CubeFaceIndexAMD %8
808 OpReturn
809 OpFunctionEnd
810 )";
811
812 const std::string after = R"(OpCapability Shader
813 OpExtension "SPV_KHR_storage_buffer_storage_class"
814 %11 = OpExtInstImport "GLSL.std.450"
815 OpMemoryModel Logical GLSL450
816 OpEntryPoint GLCompute %2 "main"
817 OpExecutionMode %2 LocalSize 1 1 1
818 %void = OpTypeVoid
819 %4 = OpTypeFunction %void
820 %float = OpTypeFloat 32
821 %v3float = OpTypeVector %float 3
822 %bool = OpTypeBool
823 %float_0 = OpConstant %float 0
824 %float_1 = OpConstant %float 1
825 %float_2 = OpConstant %float 2
826 %float_3 = OpConstant %float 3
827 %float_4 = OpConstant %float 4
828 %float_5 = OpConstant %float 5
829 %2 = OpFunction %void None %4
830 %7 = OpLabel
831 %8 = OpUndef %v3float
832 %18 = OpCompositeExtract %float %8 0
833 %19 = OpCompositeExtract %float %8 1
834 %20 = OpCompositeExtract %float %8 2
835 %21 = OpExtInst %float %11 FAbs %18
836 %22 = OpExtInst %float %11 FAbs %19
837 %23 = OpExtInst %float %11 FAbs %20
838 %24 = OpFOrdLessThan %bool %20 %float_0
839 %25 = OpFOrdLessThan %bool %19 %float_0
840 %26 = OpFOrdLessThan %bool %18 %float_0
841 %27 = OpExtInst %float %11 FMax %21 %22
842 %28 = OpFOrdGreaterThanEqual %bool %23 %27
843 %29 = OpFOrdGreaterThanEqual %bool %22 %21
844 %30 = OpSelect %float %24 %float_5 %float_4
845 %31 = OpSelect %float %25 %float_3 %float_2
846 %32 = OpSelect %float %26 %float_1 %float_0
847 %33 = OpSelect %float %29 %31 %32
848 %9 = OpSelect %float %28 %30 %33
849 OpReturn
850 OpFunctionEnd
851 )";
852
853 SinglePassRunAndCheck<AmdExtensionToKhrPass>(before, after, true);
854 }
855
TEST_F(AmdExtToKhrTest,SetVersion)856 TEST_F(AmdExtToKhrTest, SetVersion) {
857 const std::string text = R"(
858 OpCapability Shader
859 OpCapability Int64
860 OpExtension "SPV_AMD_shader_ballot"
861 %1 = OpExtInstImport "SPV_AMD_shader_ballot"
862 OpMemoryModel Logical GLSL450
863 OpEntryPoint Fragment %2 "func"
864 OpExecutionMode %2 OriginUpperLeft
865 %void = OpTypeVoid
866 %4 = OpTypeFunction %void
867 %uint = OpTypeInt 32 0
868 %ulong = OpTypeInt 64 0
869 %ulong_0 = OpConstant %ulong 0
870 %2 = OpFunction %void None %4
871 %8 = OpLabel
872 %9 = OpExtInst %uint %1 MbcntAMD %ulong_0
873 OpReturn
874 OpFunctionEnd
875 )";
876
877 // Set the version to 1.1 and make sure it is upgraded to 1.3.
878 SetTargetEnv(SPV_ENV_UNIVERSAL_1_1);
879 SetDisassembleOptions(0);
880 auto result = SinglePassRunAndDisassemble<AmdExtensionToKhrPass>(
881 text, /* skip_nop = */ true, /* skip_validation = */ false);
882
883 EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
884 const std::string& output = std::get<0>(result);
885 EXPECT_THAT(output, HasSubstr("Version: 1.3"));
886 }
887
TEST_F(AmdExtToKhrTest,SetVersion1)888 TEST_F(AmdExtToKhrTest, SetVersion1) {
889 const std::string text = R"(
890 OpCapability Shader
891 OpCapability Int64
892 OpExtension "SPV_AMD_shader_ballot"
893 %1 = OpExtInstImport "SPV_AMD_shader_ballot"
894 OpMemoryModel Logical GLSL450
895 OpEntryPoint Fragment %2 "func"
896 OpExecutionMode %2 OriginUpperLeft
897 %void = OpTypeVoid
898 %4 = OpTypeFunction %void
899 %uint = OpTypeInt 32 0
900 %ulong = OpTypeInt 64 0
901 %ulong_0 = OpConstant %ulong 0
902 %2 = OpFunction %void None %4
903 %8 = OpLabel
904 %9 = OpExtInst %uint %1 MbcntAMD %ulong_0
905 OpReturn
906 OpFunctionEnd
907 )";
908
909 // Set the version to 1.4 and make sure it is stays the same.
910 SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
911 SetDisassembleOptions(0);
912 auto result = SinglePassRunAndDisassemble<AmdExtensionToKhrPass>(
913 text, /* skip_nop = */ true, /* skip_validation = */ false);
914
915 EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
916 const std::string& output = std::get<0>(result);
917 EXPECT_THAT(output, HasSubstr("Version: 1.4"));
918 }
919
TEST_F(AmdExtToKhrTest,TimeAMD)920 TEST_F(AmdExtToKhrTest, TimeAMD) {
921 const std::string text = R"(
922 OpCapability Shader
923 OpCapability Int64
924 OpExtension "SPV_AMD_gcn_shader"
925 ; CHECK-NOT: OpExtension "SPV_AMD_gcn_shader"
926 ; CHECK: OpExtension "SPV_KHR_shader_clock"
927 %1 = OpExtInstImport "GLSL.std.450"
928 %2 = OpExtInstImport "SPV_AMD_gcn_shader"
929 ; CHECK-NOT: OpExtInstImport "SPV_AMD_gcn_shader"
930 OpMemoryModel Logical GLSL450
931 OpEntryPoint Fragment %main "main"
932 OpExecutionMode %main OriginUpperLeft
933 OpSource GLSL 450
934 OpSourceExtension "GL_AMD_gcn_shader"
935 OpSourceExtension "GL_ARB_gpu_shader_int64"
936 OpName %main "main"
937 OpName %time "time"
938 %void = OpTypeVoid
939 %6 = OpTypeFunction %void
940 %ulong = OpTypeInt 64 0
941 %_ptr_Function_ulong = OpTypePointer Function %ulong
942 %main = OpFunction %void None %6
943 %9 = OpLabel
944 %time = OpVariable %_ptr_Function_ulong Function
945 ; CHECK: [[uint:%\w+]] = OpTypeInt 32 0
946 ; CHECK: [[uint_3:%\w+]] = OpConstant [[uint]] 3
947 %10 = OpExtInst %ulong %2 TimeAMD
948 ; CHECK: %10 = OpReadClockKHR %ulong [[uint_3]]
949 OpStore %time %10
950 OpReturn
951 OpFunctionEnd
952 )";
953
954 SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
955 }
956 } // namespace
957 } // namespace opt
958 } // namespace spvtools
959