xref: /aosp_15_r20/external/mesa3d/src/compiler/spirv/tests/control_flow_tests.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2023 Intel Corporation
3  *
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:
10  *
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
13  * Software.
14  *
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
21  * IN THE SOFTWARE.
22  */
23 
24 #include <gtest/gtest.h>
25 
26 #include "helpers.h"
27 
28 class ControlFlow : public spirv_test {};
29 
TEST_F(ControlFlow,Basic)30 TEST_F(ControlFlow, Basic)
31 {
32    /*
33     ; Extra arguments for spirv-as --target-env spv1.3
34 
35                OpCapability Shader
36           %1 = OpExtInstImport "GLSL.std.450"
37                OpMemoryModel Logical GLSL450
38                OpEntryPoint GLCompute %4 "main"
39                OpExecutionMode %4 LocalSize 1 1 1
40                OpMemberDecorate %_struct_7 0 Offset 0
41                OpDecorate %_struct_7 BufferBlock
42                OpDecorate %9 DescriptorSet 0
43                OpDecorate %9 Binding 0
44        %void = OpTypeVoid
45           %3 = OpTypeFunction %void
46        %uint = OpTypeInt 32 0
47   %_struct_7 = OpTypeStruct %uint
48 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
49           %9 = OpVariable %_ptr_Uniform__struct_7 Uniform
50         %int = OpTypeInt 32 1
51       %int_0 = OpConstant %int 0
52 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
53           %4 = OpFunction %void None %3
54           %5 = OpLabel
55          %13 = OpAccessChain %_ptr_Uniform_uint %9 %int_0
56          %14 = OpLoad %uint %13 Volatile
57                OpStore %13 %14
58                OpReturn
59                OpFunctionEnd
60     */
61    static const uint32_t words[] = {
62       0x07230203, 0x00010300, 0x00070000, 0x0000000f, 0x00000000, 0x00020011,
63       0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e,
64       0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0005000f, 0x00000005,
65       0x00000002, 0x6e69616d, 0x00000000, 0x00060010, 0x00000002, 0x00000011,
66       0x00000001, 0x00000001, 0x00000001, 0x00050048, 0x00000003, 0x00000000,
67       0x00000023, 0x00000000, 0x00030047, 0x00000003, 0x00000003, 0x00040047,
68       0x00000004, 0x00000022, 0x00000000, 0x00040047, 0x00000004, 0x00000021,
69       0x00000000, 0x00020013, 0x00000005, 0x00030021, 0x00000006, 0x00000005,
70       0x00040015, 0x00000007, 0x00000020, 0x00000000, 0x0003001e, 0x00000003,
71       0x00000007, 0x00040020, 0x00000008, 0x00000002, 0x00000003, 0x0004003b,
72       0x00000008, 0x00000004, 0x00000002, 0x00040015, 0x00000009, 0x00000020,
73       0x00000001, 0x0004002b, 0x00000009, 0x0000000a, 0x00000000, 0x00040020,
74       0x0000000b, 0x00000002, 0x00000007, 0x00050036, 0x00000005, 0x00000002,
75       0x00000000, 0x00000006, 0x000200f8, 0x0000000c, 0x00050041, 0x0000000b,
76       0x0000000d, 0x00000004, 0x0000000a, 0x0005003d, 0x00000007, 0x0000000e,
77       0x0000000d, 0x00000001, 0x0003003e, 0x0000000d, 0x0000000e, 0x000100fd,
78       0x00010038,
79    };
80    get_nir(sizeof(words) / sizeof(words[0]), words);
81    ASSERT_TRUE(shader);
82 }
83 
TEST_F(ControlFlow,BreakIfConditionWithLoop)84 TEST_F(ControlFlow, BreakIfConditionWithLoop)
85 {
86    // From https://gitlab.khronos.org/spirv/SPIR-V/-/issues/659.
87 
88    /*
89     ; Extra arguments for spirv-as --target-env spv1.5
90 
91 OpCapability Shader
92 OpMemoryModel Logical Simple
93 OpEntryPoint GLCompute %100 "main"
94 OpExecutionMode %100 LocalSize 1 1 1
95 %void = OpTypeVoid
96 %8 = OpTypeFunction %void
97 %bool = OpTypeBool
98 %cond = OpConstantNull %bool ;  a boring "false".
99 
100 %100 = OpFunction %void None %8
101 %10 = OpLabel
102 OpBranch %20
103 
104 %20 = OpLabel
105 OpLoopMerge %90 %80 None
106 OpBranch %30
107 
108    %30 = OpLabel
109    OpSelectionMerge %50 None
110    OpBranchConditional %cond %90 %50
111 
112    %50 = OpLabel
113    OpBranch %80
114 
115    %80 = OpLabel ; continue target for loop
116    OpBranch %20
117 
118 %90 = OpLabel ; merge for loop
119 OpReturn
120 OpFunctionEnd
121  */
122    static const uint32_t words[] = {
123       0x07230203, 0x00010500, 0x00070000, 0x0000000c, 0x00000000, 0x00020011,
124       0x00000001, 0x0003000e, 0x00000000, 0x00000000, 0x0005000f, 0x00000005,
125       0x00000001, 0x6e69616d, 0x00000000, 0x00060010, 0x00000001, 0x00000011,
126       0x00000001, 0x00000001, 0x00000001, 0x00020013, 0x00000002, 0x00030021,
127       0x00000003, 0x00000002, 0x00020014, 0x00000004, 0x0003002e, 0x00000004,
128       0x00000005, 0x00050036, 0x00000002, 0x00000001, 0x00000000, 0x00000003,
129       0x000200f8, 0x00000006, 0x000200f9, 0x00000007, 0x000200f8, 0x00000007,
130       0x000400f6, 0x00000008, 0x00000009, 0x00000000, 0x000200f9, 0x0000000a,
131       0x000200f8, 0x0000000a, 0x000300f7, 0x0000000b, 0x00000000, 0x000400fa,
132       0x00000005, 0x00000008, 0x0000000b, 0x000200f8, 0x0000000b, 0x000200f9,
133       0x00000009, 0x000200f8, 0x00000009, 0x000200f9, 0x00000007, 0x000200f8,
134       0x00000008, 0x000100fd, 0x00010038,
135    };
136    get_nir(sizeof(words) / sizeof(words[0]), words);
137    ASSERT_TRUE(shader);
138 }
139 
TEST_F(ControlFlow,EarlyMerge)140 TEST_F(ControlFlow, EarlyMerge)
141 {
142    // From https://gitlab.khronos.org/spirv/SPIR-V/-/issues/640.
143 
144    /*
145     ; Extra arguments for spirv-as --target-env spv1.0
146 
147                OpCapability Shader
148           %1 = OpExtInstImport "GLSL.std.450"
149                OpMemoryModel Logical GLSL450
150                OpEntryPoint Fragment %main "main" %colour
151                OpExecutionMode %main OriginUpperLeft
152                OpSource GLSL 460
153                OpName %main "main"
154                OpName %colour "colour"
155                OpDecorate %colour Location 0
156        %void = OpTypeVoid
157           %3 = OpTypeFunction %void
158        %bool = OpTypeBool
159       %false = OpConstantFalse %bool
160        %true = OpConstantTrue %bool
161       %float = OpTypeFloat 32
162        %vec4 = OpTypeVector %float 4
163       %pvec4 = OpTypePointer Output %vec4
164      %colour = OpVariable %pvec4 Output
165          %f0 = OpConstant %float 0.0
166          %f1 = OpConstant %float 1.0
167          %13 = OpConstantComposite %vec4 %f0 %f1 %f0 %f1
168        %main = OpFunction %void None %3
169          %B5 = OpLabel
170                OpSelectionMerge %B8 None
171                OpBranchConditional %true %B6 %B7
172          %B6 = OpLabel
173                OpBranch %B7
174          %B7 = OpLabel
175                OpBranch %B8
176          %B8 = OpLabel
177                OpStore %colour %13
178                OpReturn
179                OpFunctionEnd
180     */
181    static const uint32_t words[] = {
182       0x07230203, 0x00010000, 0x00070000, 0x00000013, 0x00000000, 0x00020011,
183       0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e,
184       0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0006000f, 0x00000004,
185       0x00000002, 0x6e69616d, 0x00000000, 0x00000003, 0x00030010, 0x00000002,
186       0x00000007, 0x00030003, 0x00000002, 0x000001cc, 0x00040005, 0x00000002,
187       0x6e69616d, 0x00000000, 0x00040005, 0x00000003, 0x6f6c6f63, 0x00007275,
188       0x00040047, 0x00000003, 0x0000001e, 0x00000000, 0x00020013, 0x00000004,
189       0x00030021, 0x00000005, 0x00000004, 0x00020014, 0x00000006, 0x0003002a,
190       0x00000006, 0x00000007, 0x00030029, 0x00000006, 0x00000008, 0x00030016,
191       0x00000009, 0x00000020, 0x00040017, 0x0000000a, 0x00000009, 0x00000004,
192       0x00040020, 0x0000000b, 0x00000003, 0x0000000a, 0x0004003b, 0x0000000b,
193       0x00000003, 0x00000003, 0x0004002b, 0x00000009, 0x0000000c, 0x00000000,
194       0x0004002b, 0x00000009, 0x0000000d, 0x3f800000, 0x0007002c, 0x0000000a,
195       0x0000000e, 0x0000000c, 0x0000000d, 0x0000000c, 0x0000000d, 0x00050036,
196       0x00000004, 0x00000002, 0x00000000, 0x00000005, 0x000200f8, 0x0000000f,
197       0x000300f7, 0x00000010, 0x00000000, 0x000400fa, 0x00000008, 0x00000011,
198       0x00000012, 0x000200f8, 0x00000011, 0x000200f9, 0x00000012, 0x000200f8,
199       0x00000012, 0x000200f9, 0x00000010, 0x000200f8, 0x00000010, 0x0003003e,
200       0x00000003, 0x0000000e, 0x000100fd, 0x00010038,
201    };
202    get_nir(sizeof(words) / sizeof(words[0]), words, MESA_SHADER_FRAGMENT);
203    ASSERT_TRUE(shader);
204 }
205 
TEST_F(ControlFlow,SingleBlockLoop)206 TEST_F(ControlFlow, SingleBlockLoop)
207 {
208    /*
209 OpCapability Shader
210 OpMemoryModel Logical Simple
211 OpEntryPoint GLCompute %100 "main"
212 OpExecutionMode %100 LocalSize 1 1 1
213 %void = OpTypeVoid
214 %8 = OpTypeFunction %void
215 %bool = OpTypeBool
216 %cond = OpConstantNull %bool
217 
218 %100 = OpFunction %void None %8
219 %10 = OpLabel
220 OpBranch %20
221 
222 %20 = OpLabel
223 OpLoopMerge %30 %20 None
224 OpBranchConditional %cond %20 %30
225 
226 %30 = OpLabel
227 OpReturn
228 OpFunctionEnd
229  */
230    static const uint32_t words[] = {
231       0x07230203, 0x00010600, 0x00070000, 0x00000009, 0x00000000, 0x00020011,
232       0x00000001, 0x0003000e, 0x00000000, 0x00000000, 0x0005000f, 0x00000005,
233       0x00000001, 0x6e69616d, 0x00000000, 0x00060010, 0x00000001, 0x00000011,
234       0x00000001, 0x00000001, 0x00000001, 0x00020013, 0x00000002, 0x00030021,
235       0x00000003, 0x00000002, 0x00020014, 0x00000004, 0x0003002e, 0x00000004,
236       0x00000005, 0x00050036, 0x00000002, 0x00000001, 0x00000000, 0x00000003,
237       0x000200f8, 0x00000006, 0x000200f9, 0x00000007, 0x000200f8, 0x00000007,
238       0x000400f6, 0x00000008, 0x00000007, 0x00000000, 0x000400fa, 0x00000005,
239       0x00000007, 0x00000008, 0x000200f8, 0x00000008, 0x000100fd, 0x00010038,
240    };
241    get_nir(ARRAY_SIZE(words), words, MESA_SHADER_COMPUTE);
242    ASSERT_TRUE(shader);
243 }