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