1 // Copyright (c) 2022 Advanced Micro Devices, Inc.
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 "test/opt/pass_fixture.h"
16 #include "test/opt/pass_utils.h"
17 
18 namespace spvtools {
19 namespace opt {
20 namespace {
21 
22 using FixFuncCallArgumentsTest = PassTest<::testing::Test>;
TEST_F(FixFuncCallArgumentsTest, Simple)23 TEST_F(FixFuncCallArgumentsTest, Simple) {
24   const std::string text = R"(
25 ;
26 ; CHECK: [[v0:%\w+]] = OpVariable %_ptr_Function_float Function
27 ; CHECK: [[v1:%\w+]] = OpVariable %_ptr_Function_float Function
28 ; CHECK: [[v2:%\w+]] = OpVariable %_ptr_Function_T Function
29 ; CHECK: [[ac0:%\w+]] = OpAccessChain %_ptr_Function_float %t %int_0
30 ; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform_float %r1 %int_0 %uint_0
31 ; CHECK: [[ld0:%\w+]] = OpLoad %float [[ac0]]
32 ; CHECK:                OpStore [[v1]] [[ld0]]
33 ; CHECK: [[ld1:%\w+]] = OpLoad %float [[ac1]]
34 ; CHECK:                OpStore [[v0]] [[ld1]]
35 ; CHECK: [[func:%\w+]] = OpFunctionCall %void %fn [[v1]] [[v0]]
36 ; CHECK: [[ld2:%\w+]] = OpLoad %float [[v0]]
37 ; CHECK: OpStore [[ac1]] [[ld2]]
38 ; CHECK: [[ld3:%\w+]] = OpLoad %float [[v1]]
39 ; CHECK: OpStore [[ac0]] [[ld3]]
40 ;
41 OpCapability Shader
42 OpCapability Linkage
43 OpMemoryModel Logical GLSL450
44 OpSource HLSL 630
45 OpName %type_RWStructuredBuffer_float "type.RWStructuredBuffer.float"
46 OpName %r1 "r1"
47 OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
48 OpMemberName %type_ACSBuffer_counter 0 "counter"
49 OpName %counter_var_r1 "counter.var.r1"
50 OpName %main "main"
51 OpName %bb_entry "bb.entry"
52 OpName %T "T"
53 OpMemberName %T 0 "t0"
54 OpName %t "t"
55 OpName %fn "fn"
56 OpName %p0 "p0"
57 OpName %p2 "p2"
58 OpName %bb_entry_0 "bb.entry"
59 OpDecorate %main LinkageAttributes "main" Export
60 OpDecorate %r1 DescriptorSet 0
61 OpDecorate %r1 Binding 0
62 OpDecorate %counter_var_r1 DescriptorSet 0
63 OpDecorate %counter_var_r1 Binding 1
64 OpDecorate %_runtimearr_float ArrayStride 4
65 OpMemberDecorate %type_RWStructuredBuffer_float 0 Offset 0
66 OpDecorate %type_RWStructuredBuffer_float BufferBlock
67 OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
68 OpDecorate %type_ACSBuffer_counter BufferBlock
69 %int = OpTypeInt 32 1
70 %int_0 = OpConstant %int 0
71 %uint = OpTypeInt 32 0
72 %uint_0 = OpConstant %uint 0
73 %int_1 = OpConstant %int 1
74 %float = OpTypeFloat 32
75 %_runtimearr_float = OpTypeRuntimeArray %float
76 %type_RWStructuredBuffer_float = OpTypeStruct %_runtimearr_float
77 %_ptr_Uniform_type_RWStructuredBuffer_float = OpTypePointer Uniform %type_RWStructuredBuffer_float
78 %type_ACSBuffer_counter = OpTypeStruct %int
79 %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
80 %15 = OpTypeFunction %int
81 %T = OpTypeStruct %float
82 %_ptr_Function_T = OpTypePointer Function %T
83 %_ptr_Function_float = OpTypePointer Function %float
84 %_ptr_Uniform_float = OpTypePointer Uniform %float
85 %void = OpTypeVoid
86 %27 = OpTypeFunction %void %_ptr_Function_float %_ptr_Function_float
87 %r1 = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_float Uniform
88 %counter_var_r1 = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
89 %main = OpFunction %int None %15
90 %bb_entry = OpLabel
91 %t = OpVariable %_ptr_Function_T Function
92 %21 = OpAccessChain %_ptr_Function_float %t %int_0
93 %23 = OpAccessChain %_ptr_Uniform_float %r1 %int_0 %uint_0
94 %25 = OpFunctionCall %void %fn %21 %23
95 OpReturnValue %int_1
96 OpFunctionEnd
97 %fn = OpFunction %void DontInline %27
98 %p0 = OpFunctionParameter %_ptr_Function_float
99 %p2 = OpFunctionParameter %_ptr_Function_float
100 %bb_entry_0 = OpLabel
101 OpReturn
102 OpFunctionEnd
103 )";
104 
105   SinglePassRunAndMatch<FixFuncCallArgumentsPass>(text, true);
106 }
107 
TEST_F(FixFuncCallArgumentsTest, NotAccessChainInput)108 TEST_F(FixFuncCallArgumentsTest, NotAccessChainInput) {
109   const std::string text = R"(
110 ;
111 ; CHECK: [[o:%\w+]] = OpCopyObject %_ptr_Function_float %t
112 ; CHECK: [[func:%\w+]] = OpFunctionCall %void %fn [[o]]
113 ;
114 OpCapability Shader
115 OpCapability Linkage
116 OpMemoryModel Logical GLSL450
117 OpSource HLSL 630
118 OpName %main "main"
119 OpName %bb_entry "bb.entry"
120 OpName %t "t"
121 OpName %fn "fn"
122 OpName %p0 "p0"
123 OpName %bb_entry_0 "bb.entry"
124 OpDecorate %main LinkageAttributes "main" Export
125 %int = OpTypeInt 32 1
126 %int_1 = OpConstant %int 1
127 %4 = OpTypeFunction %int
128 %float = OpTypeFloat 32
129 %_ptr_Function_float = OpTypePointer Function %float
130 %void = OpTypeVoid
131 %12 = OpTypeFunction %void %_ptr_Function_float
132 %main = OpFunction %int None %4
133 %bb_entry = OpLabel
134 %t = OpVariable %_ptr_Function_float Function
135 %t1 = OpCopyObject %_ptr_Function_float %t
136 %10 = OpFunctionCall %void %fn %t1
137 OpReturnValue %int_1
138 OpFunctionEnd
139 %fn = OpFunction %void DontInline %12
140 %p0 = OpFunctionParameter %_ptr_Function_float
141 %bb_entry_0 = OpLabel
142 OpReturn
143 OpFunctionEnd
144 )";
145 
146   SinglePassRunAndMatch<FixFuncCallArgumentsPass>(text, false);
147 }
148 
149 }  // namespace
150 }  // namespace opt
151 }  // namespace spvtools