fix_storage_class_test.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038
  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. #include <string>
  15. #include "test/opt/pass_fixture.h"
  16. #include "test/opt/pass_utils.h"
  17. namespace spvtools {
  18. namespace opt {
  19. namespace {
  20. using FixStorageClassTest = PassTest<::testing::Test>;
  21. TEST_F(FixStorageClassTest, FixAccessChain) {
  22. const std::string text = R"(
  23. ; CHECK: OpAccessChain %_ptr_Workgroup_float
  24. ; CHECK: OpAccessChain %_ptr_Uniform_float
  25. OpCapability Shader
  26. OpMemoryModel Logical GLSL450
  27. OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
  28. OpExecutionMode %1 LocalSize 8 8 1
  29. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  30. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  31. OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
  32. OpDecorate %8 DescriptorSet 0
  33. OpDecorate %8 Binding 0
  34. OpDecorate %_runtimearr_float ArrayStride 4
  35. OpMemberDecorate %_struct_7 0 Offset 0
  36. OpDecorate %_struct_7 BufferBlock
  37. %int = OpTypeInt 32 1
  38. %int_0 = OpConstant %int 0
  39. %float = OpTypeFloat 32
  40. %float_2 = OpConstant %float 2
  41. %uint = OpTypeInt 32 0
  42. %uint_10 = OpConstant %uint 10
  43. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  44. %ptr = OpTypePointer Function %_arr_float_uint_10
  45. %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
  46. %_struct_5 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
  47. %_ptr_Workgroup__struct_5 = OpTypePointer Workgroup %_struct_5
  48. %_runtimearr_float = OpTypeRuntimeArray %float
  49. %_struct_7 = OpTypeStruct %_runtimearr_float
  50. %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
  51. %v3uint = OpTypeVector %uint 3
  52. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  53. %void = OpTypeVoid
  54. %30 = OpTypeFunction %void
  55. %_ptr_Function_float = OpTypePointer Function %float
  56. %_ptr_Uniform_float = OpTypePointer Uniform %float
  57. %6 = OpVariable %_ptr_Workgroup__struct_5 Workgroup
  58. %8 = OpVariable %_ptr_Uniform__struct_7 Uniform
  59. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  60. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  61. %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
  62. %1 = OpFunction %void None %30
  63. %38 = OpLabel
  64. %44 = OpLoad %v3uint %gl_LocalInvocationID
  65. %50 = OpAccessChain %_ptr_Function_float %6 %int_0 %int_0 %int_0
  66. %51 = OpLoad %float %50
  67. %52 = OpFMul %float %float_2 %51
  68. OpStore %50 %52
  69. %55 = OpLoad %float %50
  70. %59 = OpCompositeExtract %uint %44 0
  71. %60 = OpAccessChain %_ptr_Uniform_float %8 %int_0 %59
  72. OpStore %60 %55
  73. OpReturn
  74. OpFunctionEnd
  75. )";
  76. SinglePassRunAndMatch<FixStorageClass>(text, false);
  77. }
  78. TEST_F(FixStorageClassTest, FixLinkedAccessChain) {
  79. const std::string text = R"(
  80. ; CHECK: OpAccessChain %_ptr_Workgroup__arr_float_uint_10
  81. ; CHECK: OpAccessChain %_ptr_Workgroup_float
  82. ; CHECK: OpAccessChain %_ptr_Uniform_float
  83. OpCapability Shader
  84. OpMemoryModel Logical GLSL450
  85. OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
  86. OpExecutionMode %1 LocalSize 8 8 1
  87. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  88. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  89. OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
  90. OpDecorate %5 DescriptorSet 0
  91. OpDecorate %5 Binding 0
  92. OpDecorate %_runtimearr_float ArrayStride 4
  93. OpMemberDecorate %_struct_7 0 Offset 0
  94. OpDecorate %_struct_7 BufferBlock
  95. %int = OpTypeInt 32 1
  96. %int_0 = OpConstant %int 0
  97. %float = OpTypeFloat 32
  98. %float_2 = OpConstant %float 2
  99. %uint = OpTypeInt 32 0
  100. %uint_10 = OpConstant %uint 10
  101. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  102. %_ptr_Function__arr_float_uint_10 = OpTypePointer Function %_arr_float_uint_10
  103. %_ptr = OpTypePointer Function %_arr_float_uint_10
  104. %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
  105. %_struct_17 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
  106. %_ptr_Workgroup__struct_17 = OpTypePointer Workgroup %_struct_17
  107. %_runtimearr_float = OpTypeRuntimeArray %float
  108. %_struct_7 = OpTypeStruct %_runtimearr_float
  109. %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
  110. %v3uint = OpTypeVector %uint 3
  111. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  112. %void = OpTypeVoid
  113. %23 = OpTypeFunction %void
  114. %_ptr_Function_float = OpTypePointer Function %float
  115. %_ptr_Uniform_float = OpTypePointer Uniform %float
  116. %27 = OpVariable %_ptr_Workgroup__struct_17 Workgroup
  117. %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
  118. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  119. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  120. %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
  121. %1 = OpFunction %void None %23
  122. %28 = OpLabel
  123. %29 = OpLoad %v3uint %gl_LocalInvocationID
  124. %30 = OpAccessChain %_ptr_Function__arr_float_uint_10 %27 %int_0 %int_0
  125. %31 = OpAccessChain %_ptr_Function_float %30 %int_0
  126. %32 = OpLoad %float %31
  127. %33 = OpFMul %float %float_2 %32
  128. OpStore %31 %33
  129. %34 = OpLoad %float %31
  130. %35 = OpCompositeExtract %uint %29 0
  131. %36 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %35
  132. OpStore %36 %34
  133. OpReturn
  134. OpFunctionEnd
  135. )";
  136. SinglePassRunAndMatch<FixStorageClass>(text, false);
  137. }
  138. TEST_F(FixStorageClassTest, FixCopyObject) {
  139. const std::string text = R"(
  140. ; CHECK: OpCopyObject %_ptr_Workgroup__struct_17
  141. ; CHECK: OpAccessChain %_ptr_Workgroup_float
  142. ; CHECK: OpAccessChain %_ptr_Uniform_float
  143. OpCapability Shader
  144. OpMemoryModel Logical GLSL450
  145. OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
  146. OpExecutionMode %1 LocalSize 8 8 1
  147. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  148. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  149. OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
  150. OpDecorate %8 DescriptorSet 0
  151. OpDecorate %8 Binding 0
  152. OpDecorate %_runtimearr_float ArrayStride 4
  153. OpMemberDecorate %_struct_7 0 Offset 0
  154. OpDecorate %_struct_7 BufferBlock
  155. %int = OpTypeInt 32 1
  156. %int_0 = OpConstant %int 0
  157. %float = OpTypeFloat 32
  158. %float_2 = OpConstant %float 2
  159. %uint = OpTypeInt 32 0
  160. %uint_10 = OpConstant %uint 10
  161. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  162. %ptr = OpTypePointer Function %_arr_float_uint_10
  163. %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
  164. %_struct_17 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
  165. %_ptr_Workgroup__struct_17 = OpTypePointer Workgroup %_struct_17
  166. %_ptr_Function__struct_17 = OpTypePointer Function %_struct_17
  167. %_runtimearr_float = OpTypeRuntimeArray %float
  168. %_struct_7 = OpTypeStruct %_runtimearr_float
  169. %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
  170. %v3uint = OpTypeVector %uint 3
  171. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  172. %void = OpTypeVoid
  173. %30 = OpTypeFunction %void
  174. %_ptr_Function_float = OpTypePointer Function %float
  175. %_ptr_Uniform_float = OpTypePointer Uniform %float
  176. %6 = OpVariable %_ptr_Workgroup__struct_17 Workgroup
  177. %8 = OpVariable %_ptr_Uniform__struct_7 Uniform
  178. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  179. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  180. %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
  181. %1 = OpFunction %void None %30
  182. %38 = OpLabel
  183. %44 = OpLoad %v3uint %gl_LocalInvocationID
  184. %cp = OpCopyObject %_ptr_Function__struct_17 %6
  185. %50 = OpAccessChain %_ptr_Function_float %cp %int_0 %int_0 %int_0
  186. %51 = OpLoad %float %50
  187. %52 = OpFMul %float %float_2 %51
  188. OpStore %50 %52
  189. %55 = OpLoad %float %50
  190. %59 = OpCompositeExtract %uint %44 0
  191. %60 = OpAccessChain %_ptr_Uniform_float %8 %int_0 %59
  192. OpStore %60 %55
  193. OpReturn
  194. OpFunctionEnd
  195. )";
  196. SinglePassRunAndMatch<FixStorageClass>(text, false);
  197. }
  198. TEST_F(FixStorageClassTest, FixPhiInSelMerge) {
  199. const std::string text = R"(
  200. ; CHECK: OpPhi %_ptr_Workgroup__struct_19
  201. ; CHECK: OpAccessChain %_ptr_Workgroup_float
  202. ; CHECK: OpAccessChain %_ptr_Uniform_float
  203. OpCapability Shader
  204. OpMemoryModel Logical GLSL450
  205. OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
  206. OpExecutionMode %1 LocalSize 8 8 1
  207. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  208. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  209. OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
  210. OpDecorate %5 DescriptorSet 0
  211. OpDecorate %5 Binding 0
  212. OpDecorate %_runtimearr_float ArrayStride 4
  213. OpMemberDecorate %_struct_7 0 Offset 0
  214. OpDecorate %_struct_7 BufferBlock
  215. %bool = OpTypeBool
  216. %true = OpConstantTrue %bool
  217. %int = OpTypeInt 32 1
  218. %int_0 = OpConstant %int 0
  219. %float = OpTypeFloat 32
  220. %float_2 = OpConstant %float 2
  221. %uint = OpTypeInt 32 0
  222. %uint_10 = OpConstant %uint 10
  223. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  224. %_ptr_Function__arr_float_uint_10 = OpTypePointer Function %_arr_float_uint_10
  225. %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
  226. %_struct_19 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
  227. %_ptr_Workgroup__struct_19 = OpTypePointer Workgroup %_struct_19
  228. %_ptr_Function__struct_19 = OpTypePointer Function %_struct_19
  229. %_runtimearr_float = OpTypeRuntimeArray %float
  230. %_struct_7 = OpTypeStruct %_runtimearr_float
  231. %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
  232. %v3uint = OpTypeVector %uint 3
  233. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  234. %void = OpTypeVoid
  235. %25 = OpTypeFunction %void
  236. %_ptr_Function_float = OpTypePointer Function %float
  237. %_ptr_Uniform_float = OpTypePointer Uniform %float
  238. %28 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
  239. %29 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
  240. %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
  241. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  242. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  243. %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
  244. %1 = OpFunction %void None %25
  245. %30 = OpLabel
  246. OpSelectionMerge %31 None
  247. OpBranchConditional %true %32 %31
  248. %32 = OpLabel
  249. OpBranch %31
  250. %31 = OpLabel
  251. %33 = OpPhi %_ptr_Function__struct_19 %28 %30 %29 %32
  252. %34 = OpLoad %v3uint %gl_LocalInvocationID
  253. %35 = OpAccessChain %_ptr_Function_float %33 %int_0 %int_0 %int_0
  254. %36 = OpLoad %float %35
  255. %37 = OpFMul %float %float_2 %36
  256. OpStore %35 %37
  257. %38 = OpLoad %float %35
  258. %39 = OpCompositeExtract %uint %34 0
  259. %40 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %39
  260. OpStore %40 %38
  261. OpReturn
  262. OpFunctionEnd
  263. )";
  264. SinglePassRunAndMatch<FixStorageClass>(text, false);
  265. }
  266. TEST_F(FixStorageClassTest, FixPhiInLoop) {
  267. const std::string text = R"(
  268. ; CHECK: OpPhi %_ptr_Workgroup__struct_19
  269. ; CHECK: OpAccessChain %_ptr_Workgroup_float
  270. ; CHECK: OpAccessChain %_ptr_Uniform_float
  271. OpCapability Shader
  272. OpMemoryModel Logical GLSL450
  273. OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
  274. OpExecutionMode %1 LocalSize 8 8 1
  275. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  276. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  277. OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
  278. OpDecorate %5 DescriptorSet 0
  279. OpDecorate %5 Binding 0
  280. OpDecorate %_runtimearr_float ArrayStride 4
  281. OpMemberDecorate %_struct_7 0 Offset 0
  282. OpDecorate %_struct_7 BufferBlock
  283. %bool = OpTypeBool
  284. %true = OpConstantTrue %bool
  285. %int = OpTypeInt 32 1
  286. %int_0 = OpConstant %int 0
  287. %float = OpTypeFloat 32
  288. %float_2 = OpConstant %float 2
  289. %uint = OpTypeInt 32 0
  290. %uint_10 = OpConstant %uint 10
  291. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  292. %_ptr_Function__arr_float_uint_10 = OpTypePointer Function %_arr_float_uint_10
  293. %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
  294. %_struct_19 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
  295. %_ptr_Workgroup__struct_19 = OpTypePointer Workgroup %_struct_19
  296. %_ptr_Function__struct_19 = OpTypePointer Function %_struct_19
  297. %_runtimearr_float = OpTypeRuntimeArray %float
  298. %_struct_7 = OpTypeStruct %_runtimearr_float
  299. %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
  300. %v3uint = OpTypeVector %uint 3
  301. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  302. %void = OpTypeVoid
  303. %25 = OpTypeFunction %void
  304. %_ptr_Function_float = OpTypePointer Function %float
  305. %_ptr_Uniform_float = OpTypePointer Uniform %float
  306. %28 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
  307. %29 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
  308. %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
  309. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  310. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  311. %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
  312. %1 = OpFunction %void None %25
  313. %30 = OpLabel
  314. OpSelectionMerge %31 None
  315. OpBranchConditional %true %32 %31
  316. %32 = OpLabel
  317. OpBranch %31
  318. %31 = OpLabel
  319. %33 = OpPhi %_ptr_Function__struct_19 %28 %30 %29 %32
  320. %34 = OpLoad %v3uint %gl_LocalInvocationID
  321. %35 = OpAccessChain %_ptr_Function_float %33 %int_0 %int_0 %int_0
  322. %36 = OpLoad %float %35
  323. %37 = OpFMul %float %float_2 %36
  324. OpStore %35 %37
  325. %38 = OpLoad %float %35
  326. %39 = OpCompositeExtract %uint %34 0
  327. %40 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %39
  328. OpStore %40 %38
  329. OpReturn
  330. OpFunctionEnd
  331. )";
  332. SinglePassRunAndMatch<FixStorageClass>(text, false);
  333. }
  334. TEST_F(FixStorageClassTest, DontChangeFunctionCalls) {
  335. const std::string text = R"(OpCapability Shader
  336. OpMemoryModel Logical GLSL450
  337. OpEntryPoint GLCompute %1 "testMain"
  338. OpExecutionMode %1 LocalSize 8 8 1
  339. OpDecorate %2 DescriptorSet 0
  340. OpDecorate %2 Binding 0
  341. %int = OpTypeInt 32 1
  342. %_ptr_Function_int = OpTypePointer Function %int
  343. %_ptr_Workgroup_int = OpTypePointer Workgroup %int
  344. %_ptr_Uniform_int = OpTypePointer Uniform %int
  345. %void = OpTypeVoid
  346. %8 = OpTypeFunction %void
  347. %9 = OpTypeFunction %_ptr_Uniform_int %_ptr_Function_int
  348. %10 = OpVariable %_ptr_Workgroup_int Workgroup
  349. %2 = OpVariable %_ptr_Uniform_int Uniform
  350. %1 = OpFunction %void None %8
  351. %11 = OpLabel
  352. %12 = OpFunctionCall %_ptr_Uniform_int %13 %10
  353. OpReturn
  354. OpFunctionEnd
  355. %13 = OpFunction %_ptr_Uniform_int None %9
  356. %14 = OpFunctionParameter %_ptr_Function_int
  357. %15 = OpLabel
  358. OpReturnValue %2
  359. OpFunctionEnd
  360. )";
  361. SinglePassRunAndCheck<FixStorageClass>(text, text, false, false);
  362. }
  363. TEST_F(FixStorageClassTest, FixSelect) {
  364. const std::string text = R"(
  365. ; CHECK: OpSelect %_ptr_Workgroup__struct_19
  366. ; CHECK: OpAccessChain %_ptr_Workgroup_float
  367. ; CHECK: OpAccessChain %_ptr_Uniform_float
  368. OpCapability Shader
  369. OpMemoryModel Logical GLSL450
  370. OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
  371. OpExecutionMode %1 LocalSize 8 8 1
  372. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  373. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  374. OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
  375. OpDecorate %5 DescriptorSet 0
  376. OpDecorate %5 Binding 0
  377. OpDecorate %_runtimearr_float ArrayStride 4
  378. OpMemberDecorate %_struct_7 0 Offset 0
  379. OpDecorate %_struct_7 BufferBlock
  380. %bool = OpTypeBool
  381. %true = OpConstantTrue %bool
  382. %int = OpTypeInt 32 1
  383. %int_0 = OpConstant %int 0
  384. %float = OpTypeFloat 32
  385. %float_2 = OpConstant %float 2
  386. %uint = OpTypeInt 32 0
  387. %uint_10 = OpConstant %uint 10
  388. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  389. %_ptr_Function__arr_float_uint_10 = OpTypePointer Function %_arr_float_uint_10
  390. %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
  391. %_struct_19 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
  392. %_ptr_Workgroup__struct_19 = OpTypePointer Workgroup %_struct_19
  393. %_ptr_Function__struct_19 = OpTypePointer Function %_struct_19
  394. %_runtimearr_float = OpTypeRuntimeArray %float
  395. %_struct_7 = OpTypeStruct %_runtimearr_float
  396. %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
  397. %v3uint = OpTypeVector %uint 3
  398. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  399. %void = OpTypeVoid
  400. %25 = OpTypeFunction %void
  401. %_ptr_Function_float = OpTypePointer Function %float
  402. %_ptr_Uniform_float = OpTypePointer Uniform %float
  403. %28 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
  404. %29 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
  405. %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
  406. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  407. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  408. %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
  409. %1 = OpFunction %void None %25
  410. %30 = OpLabel
  411. %33 = OpSelect %_ptr_Function__struct_19 %true %28 %29
  412. %34 = OpLoad %v3uint %gl_LocalInvocationID
  413. %35 = OpAccessChain %_ptr_Function_float %33 %int_0 %int_0 %int_0
  414. %36 = OpLoad %float %35
  415. %37 = OpFMul %float %float_2 %36
  416. OpStore %35 %37
  417. %38 = OpLoad %float %35
  418. %39 = OpCompositeExtract %uint %34 0
  419. %40 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %39
  420. OpStore %40 %38
  421. OpReturn
  422. OpFunctionEnd
  423. )";
  424. SinglePassRunAndMatch<FixStorageClass>(text, false);
  425. }
  426. TEST_F(FixStorageClassTest, BitCast) {
  427. const std::string text = R"(OpCapability VariablePointersStorageBuffer
  428. OpMemoryModel Logical GLSL450
  429. OpEntryPoint GLCompute %1 "main"
  430. %void = OpTypeVoid
  431. %3 = OpTypeFunction %void
  432. %_ptr_Output_void = OpTypePointer Output %void
  433. %_ptr_Private__ptr_Output_void = OpTypePointer Private %_ptr_Output_void
  434. %6 = OpVariable %_ptr_Private__ptr_Output_void Private
  435. %1 = OpFunction %void Inline %3
  436. %7 = OpLabel
  437. %8 = OpBitcast %_ptr_Output_void %6
  438. OpReturn
  439. OpFunctionEnd
  440. )";
  441. SinglePassRunAndCheck<FixStorageClass>(text, text, false);
  442. }
  443. TEST_F(FixStorageClassTest, FixLinkedAccessChain2) {
  444. // This case is similar to FixLinkedAccessChain. The difference is that the
  445. // first OpAccessChain instruction starts as workgroup storage class. Only
  446. // the second one needs to change.
  447. const std::string text = R"(
  448. ; CHECK: OpAccessChain %_ptr_Workgroup__arr_float_uint_10
  449. ; CHECK: OpAccessChain %_ptr_Workgroup_float
  450. ; CHECK: OpAccessChain %_ptr_Uniform_float
  451. OpCapability Shader
  452. OpMemoryModel Logical GLSL450
  453. OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
  454. OpExecutionMode %1 LocalSize 8 8 1
  455. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  456. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  457. OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
  458. OpDecorate %5 DescriptorSet 0
  459. OpDecorate %5 Binding 0
  460. OpDecorate %_runtimearr_float ArrayStride 4
  461. OpMemberDecorate %_struct_7 0 Offset 0
  462. OpDecorate %_struct_7 BufferBlock
  463. %int = OpTypeInt 32 1
  464. %int_0 = OpConstant %int 0
  465. %float = OpTypeFloat 32
  466. %float_2 = OpConstant %float 2
  467. %uint = OpTypeInt 32 0
  468. %uint_10 = OpConstant %uint 10
  469. %_arr_float_uint_10 = OpTypeArray %float %uint_10
  470. %_ptr_Workgroup__arr_float_uint_10 = OpTypePointer Workgroup %_arr_float_uint_10
  471. %_ptr = OpTypePointer Function %_arr_float_uint_10
  472. %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
  473. %_struct_17 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
  474. %_ptr_Workgroup__struct_17 = OpTypePointer Workgroup %_struct_17
  475. %_runtimearr_float = OpTypeRuntimeArray %float
  476. %_struct_7 = OpTypeStruct %_runtimearr_float
  477. %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
  478. %v3uint = OpTypeVector %uint 3
  479. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  480. %void = OpTypeVoid
  481. %23 = OpTypeFunction %void
  482. %_ptr_Function_float = OpTypePointer Function %float
  483. %_ptr_Uniform_float = OpTypePointer Uniform %float
  484. %27 = OpVariable %_ptr_Workgroup__struct_17 Workgroup
  485. %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
  486. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  487. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  488. %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
  489. %1 = OpFunction %void None %23
  490. %28 = OpLabel
  491. %29 = OpLoad %v3uint %gl_LocalInvocationID
  492. %30 = OpAccessChain %_ptr_Workgroup__arr_float_uint_10 %27 %int_0 %int_0
  493. %31 = OpAccessChain %_ptr_Function_float %30 %int_0
  494. %32 = OpLoad %float %31
  495. %33 = OpFMul %float %float_2 %32
  496. OpStore %31 %33
  497. %34 = OpLoad %float %31
  498. %35 = OpCompositeExtract %uint %29 0
  499. %36 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %35
  500. OpStore %36 %34
  501. OpReturn
  502. OpFunctionEnd
  503. )";
  504. SinglePassRunAndMatch<FixStorageClass>(text, false);
  505. }
  506. TEST_F(FixStorageClassTest, AllowImageFormatMismatch) {
  507. const std::string text = R"(OpCapability Shader
  508. OpCapability SampledBuffer
  509. OpCapability ImageBuffer
  510. OpMemoryModel Logical GLSL450
  511. OpEntryPoint GLCompute %main "main"
  512. OpExecutionMode %main LocalSize 1 1 1
  513. OpSource HLSL 600
  514. OpName %type_buffer_image "type.buffer.image"
  515. OpName %Buf "Buf"
  516. OpName %main "main"
  517. OpName %src_main "src.main"
  518. OpName %bb_entry "bb.entry"
  519. OpName %type_buffer_image_0 "type.buffer.image"
  520. OpName %b "b"
  521. OpDecorate %Buf DescriptorSet 0
  522. OpDecorate %Buf Binding 0
  523. %float = OpTypeFloat 32
  524. %type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 Rgba16f
  525. %_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image
  526. %void = OpTypeVoid
  527. %11 = OpTypeFunction %void
  528. %type_buffer_image_0 = OpTypeImage %float Buffer 2 0 0 2 Rgba32f
  529. %_ptr_Function_type_buffer_image_0 = OpTypePointer Function %type_buffer_image_0
  530. %Buf = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant
  531. %main = OpFunction %void None %11
  532. %13 = OpLabel
  533. %14 = OpFunctionCall %void %src_main
  534. OpReturn
  535. OpFunctionEnd
  536. %src_main = OpFunction %void None %11
  537. %bb_entry = OpLabel
  538. %b = OpVariable %_ptr_Function_type_buffer_image_0 Function
  539. %15 = OpLoad %type_buffer_image %Buf
  540. OpStore %b %15
  541. OpReturn
  542. OpFunctionEnd
  543. )";
  544. SinglePassRunAndCheck<FixStorageClass>(text, text, false, false);
  545. }
  546. using FixTypeTest = PassTest<::testing::Test>;
  547. TEST_F(FixTypeTest, FixAccessChain) {
  548. const std::string text = R"(
  549. ; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
  550. ; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_T [[ac1]] %int_0
  551. OpCapability Shader
  552. OpMemoryModel Logical GLSL450
  553. OpEntryPoint GLCompute %main "main"
  554. OpExecutionMode %main LocalSize 1 1 1
  555. OpSource HLSL 600
  556. OpName %type_RWStructuredBuffer_S "type.RWStructuredBuffer.S"
  557. OpName %S "S"
  558. OpMemberName %S 0 "t"
  559. OpName %T "T"
  560. OpMemberName %T 0 "a"
  561. OpName %A "A"
  562. OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
  563. OpMemberName %type_ACSBuffer_counter 0 "counter"
  564. OpName %counter_var_A "counter.var.A"
  565. OpName %main "main"
  566. OpName %S_0 "S"
  567. OpMemberName %S_0 0 "t"
  568. OpName %T_0 "T"
  569. OpMemberName %T_0 0 "a"
  570. OpDecorate %A DescriptorSet 0
  571. OpDecorate %A Binding 0
  572. OpDecorate %counter_var_A DescriptorSet 0
  573. OpDecorate %counter_var_A Binding 1
  574. OpMemberDecorate %T 0 Offset 0
  575. OpMemberDecorate %S 0 Offset 0
  576. OpDecorate %_runtimearr_S ArrayStride 4
  577. OpMemberDecorate %type_RWStructuredBuffer_S 0 Offset 0
  578. OpDecorate %type_RWStructuredBuffer_S BufferBlock
  579. OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
  580. OpDecorate %type_ACSBuffer_counter BufferBlock
  581. %int = OpTypeInt 32 1
  582. %int_0 = OpConstant %int 0
  583. %uint = OpTypeInt 32 0
  584. %uint_0 = OpConstant %uint 0
  585. %T = OpTypeStruct %int
  586. %S = OpTypeStruct %T
  587. %_runtimearr_S = OpTypeRuntimeArray %S
  588. %type_RWStructuredBuffer_S = OpTypeStruct %_runtimearr_S
  589. %_ptr_Uniform_type_RWStructuredBuffer_S = OpTypePointer Uniform %type_RWStructuredBuffer_S
  590. %type_ACSBuffer_counter = OpTypeStruct %int
  591. %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
  592. %void = OpTypeVoid
  593. %18 = OpTypeFunction %void
  594. %T_0 = OpTypeStruct %int
  595. %S_0 = OpTypeStruct %T_0
  596. %_ptr_Function_S_0 = OpTypePointer Function %S_0
  597. %_ptr_Uniform_S = OpTypePointer Uniform %S
  598. %_ptr_Uniform_T = OpTypePointer Uniform %T
  599. %22 = OpTypeFunction %T_0 %_ptr_Function_S_0
  600. %_ptr_Function_T_0 = OpTypePointer Function %T_0
  601. %A = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_S Uniform
  602. %counter_var_A = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
  603. %main = OpFunction %void None %18
  604. %24 = OpLabel
  605. %25 = OpVariable %_ptr_Function_T_0 Function
  606. %26 = OpVariable %_ptr_Function_S_0 Function
  607. %27 = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
  608. %28 = OpAccessChain %_ptr_Function_T_0 %27 %int_0
  609. OpReturn
  610. OpFunctionEnd
  611. )";
  612. SinglePassRunAndMatch<FixStorageClass>(text, false);
  613. }
  614. TEST_F(FixTypeTest, FixLoad) {
  615. const std::string text = R"(
  616. ; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
  617. ; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_T [[ac1]] %int_0
  618. ; CHECK: [[ld:%\w+]] = OpLoad %T [[ac2]]
  619. OpCapability Shader
  620. OpMemoryModel Logical GLSL450
  621. OpEntryPoint GLCompute %main "main"
  622. OpExecutionMode %main LocalSize 1 1 1
  623. OpSource HLSL 600
  624. OpName %type_RWStructuredBuffer_S "type.RWStructuredBuffer.S"
  625. OpName %S "S"
  626. OpMemberName %S 0 "t"
  627. OpName %T "T"
  628. OpMemberName %T 0 "a"
  629. OpName %A "A"
  630. OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
  631. OpMemberName %type_ACSBuffer_counter 0 "counter"
  632. OpName %counter_var_A "counter.var.A"
  633. OpName %main "main"
  634. OpName %S_0 "S"
  635. OpMemberName %S_0 0 "t"
  636. OpName %T_0 "T"
  637. OpMemberName %T_0 0 "a"
  638. OpDecorate %A DescriptorSet 0
  639. OpDecorate %A Binding 0
  640. OpDecorate %counter_var_A DescriptorSet 0
  641. OpDecorate %counter_var_A Binding 1
  642. OpMemberDecorate %T 0 Offset 0
  643. OpMemberDecorate %S 0 Offset 0
  644. OpDecorate %_runtimearr_S ArrayStride 4
  645. OpMemberDecorate %type_RWStructuredBuffer_S 0 Offset 0
  646. OpDecorate %type_RWStructuredBuffer_S BufferBlock
  647. OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
  648. OpDecorate %type_ACSBuffer_counter BufferBlock
  649. %int = OpTypeInt 32 1
  650. %int_0 = OpConstant %int 0
  651. %uint = OpTypeInt 32 0
  652. %uint_0 = OpConstant %uint 0
  653. %T = OpTypeStruct %int
  654. %S = OpTypeStruct %T
  655. %_runtimearr_S = OpTypeRuntimeArray %S
  656. %type_RWStructuredBuffer_S = OpTypeStruct %_runtimearr_S
  657. %_ptr_Uniform_type_RWStructuredBuffer_S = OpTypePointer Uniform %type_RWStructuredBuffer_S
  658. %type_ACSBuffer_counter = OpTypeStruct %int
  659. %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
  660. %void = OpTypeVoid
  661. %18 = OpTypeFunction %void
  662. %T_0 = OpTypeStruct %int
  663. %S_0 = OpTypeStruct %T_0
  664. %_ptr_Function_S_0 = OpTypePointer Function %S_0
  665. %_ptr_Uniform_S = OpTypePointer Uniform %S
  666. %_ptr_Uniform_T = OpTypePointer Uniform %T
  667. %22 = OpTypeFunction %T_0 %_ptr_Function_S_0
  668. %_ptr_Function_T_0 = OpTypePointer Function %T_0
  669. %A = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_S Uniform
  670. %counter_var_A = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
  671. %main = OpFunction %void None %18
  672. %24 = OpLabel
  673. %25 = OpVariable %_ptr_Function_T_0 Function
  674. %26 = OpVariable %_ptr_Function_S_0 Function
  675. %27 = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
  676. %28 = OpAccessChain %_ptr_Uniform_T %27 %int_0
  677. %29 = OpLoad %T_0 %28
  678. OpReturn
  679. OpFunctionEnd
  680. )";
  681. SinglePassRunAndMatch<FixStorageClass>(text, false);
  682. }
  683. TEST_F(FixTypeTest, FixStore) {
  684. const std::string text = R"(
  685. ; CHECK: [[ld:%\w+]] = OpLoad %T
  686. ; CHECK: OpStore
  687. OpCapability Shader
  688. OpMemoryModel Logical GLSL450
  689. OpEntryPoint GLCompute %main "main"
  690. OpExecutionMode %main LocalSize 1 1 1
  691. OpSource HLSL 600
  692. OpName %type_RWStructuredBuffer_S "type.RWStructuredBuffer.S"
  693. OpName %S "S"
  694. OpMemberName %S 0 "t"
  695. OpName %T "T"
  696. OpMemberName %T 0 "a"
  697. OpName %A "A"
  698. OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
  699. OpMemberName %type_ACSBuffer_counter 0 "counter"
  700. OpName %counter_var_A "counter.var.A"
  701. OpName %main "main"
  702. OpName %S_0 "S"
  703. OpMemberName %S_0 0 "t"
  704. OpName %T_0 "T"
  705. OpMemberName %T_0 0 "a"
  706. OpDecorate %A DescriptorSet 0
  707. OpDecorate %A Binding 0
  708. OpDecorate %counter_var_A DescriptorSet 0
  709. OpDecorate %counter_var_A Binding 1
  710. OpMemberDecorate %T 0 Offset 0
  711. OpMemberDecorate %S 0 Offset 0
  712. OpDecorate %_runtimearr_S ArrayStride 4
  713. OpMemberDecorate %type_RWStructuredBuffer_S 0 Offset 0
  714. OpDecorate %type_RWStructuredBuffer_S BufferBlock
  715. OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
  716. OpDecorate %type_ACSBuffer_counter BufferBlock
  717. %int = OpTypeInt 32 1
  718. %int_0 = OpConstant %int 0
  719. %uint = OpTypeInt 32 0
  720. %uint_0 = OpConstant %uint 0
  721. %T = OpTypeStruct %int
  722. %S = OpTypeStruct %T
  723. %_runtimearr_S = OpTypeRuntimeArray %S
  724. %type_RWStructuredBuffer_S = OpTypeStruct %_runtimearr_S
  725. %_ptr_Uniform_type_RWStructuredBuffer_S = OpTypePointer Uniform %type_RWStructuredBuffer_S
  726. %type_ACSBuffer_counter = OpTypeStruct %int
  727. %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
  728. %void = OpTypeVoid
  729. %18 = OpTypeFunction %void
  730. %T_0 = OpTypeStruct %int
  731. %S_0 = OpTypeStruct %T_0
  732. %_ptr_Function_S_0 = OpTypePointer Function %S_0
  733. %_ptr_Uniform_S = OpTypePointer Uniform %S
  734. %_ptr_Uniform_T = OpTypePointer Uniform %T
  735. %22 = OpTypeFunction %T_0 %_ptr_Function_S_0
  736. %_ptr_Function_T_0 = OpTypePointer Function %T_0
  737. %A = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_S Uniform
  738. %counter_var_A = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
  739. %main = OpFunction %void None %18
  740. %24 = OpLabel
  741. %25 = OpVariable %_ptr_Function_T_0 Function
  742. %26 = OpVariable %_ptr_Function_S_0 Function
  743. %27 = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
  744. %28 = OpAccessChain %_ptr_Uniform_T %27 %int_0
  745. %29 = OpLoad %T %28
  746. OpStore %25 %29
  747. OpReturn
  748. OpFunctionEnd
  749. )";
  750. SinglePassRunAndMatch<FixStorageClass>(text, false);
  751. }
  752. TEST_F(FixTypeTest, FixSelect) {
  753. const std::string text = R"(
  754. ; CHECK: OpSelect %_ptr_Uniform__struct_3
  755. OpCapability Shader
  756. OpMemoryModel Logical GLSL450
  757. OpEntryPoint GLCompute %1 "main"
  758. OpExecutionMode %1 LocalSize 1 1 1
  759. OpSource HLSL 600
  760. OpDecorate %2 DescriptorSet 0
  761. OpDecorate %2 Binding 0
  762. OpMemberDecorate %_struct_3 0 Offset 0
  763. OpDecorate %_runtimearr__struct_3 ArrayStride 4
  764. OpMemberDecorate %_struct_5 0 Offset 0
  765. OpDecorate %_struct_5 BufferBlock
  766. %uint = OpTypeInt 32 0
  767. %uint_0 = OpConstant %uint 0
  768. %uint_1 = OpConstant %uint 1
  769. %_struct_3 = OpTypeStruct %uint
  770. %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
  771. %_struct_5 = OpTypeStruct %_runtimearr__struct_3
  772. %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
  773. %void = OpTypeVoid
  774. %11 = OpTypeFunction %void
  775. %_struct_12 = OpTypeStruct %uint
  776. %_ptr_Function__struct_12 = OpTypePointer Function %_struct_12
  777. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  778. %bool = OpTypeBool
  779. %_ptr_Uniform__struct_3 = OpTypePointer Uniform %_struct_3
  780. %2 = OpVariable %_ptr_Uniform__struct_5 Uniform
  781. %1 = OpFunction %void None %11
  782. %17 = OpLabel
  783. %18 = OpAccessChain %_ptr_Uniform_uint %2 %uint_0 %uint_0 %uint_0
  784. %19 = OpLoad %uint %18
  785. %20 = OpSGreaterThan %bool %19 %uint_0
  786. %21 = OpAccessChain %_ptr_Uniform__struct_3 %2 %uint_0 %uint_0
  787. %22 = OpAccessChain %_ptr_Uniform__struct_3 %2 %uint_0 %uint_1
  788. %23 = OpSelect %_ptr_Function__struct_12 %20 %21 %22
  789. OpReturn
  790. OpFunctionEnd
  791. )";
  792. SinglePassRunAndMatch<FixStorageClass>(text, false);
  793. }
  794. TEST_F(FixTypeTest, FixPhiInLoop) {
  795. const std::string text = R"(
  796. ; CHECK: [[ac_init:%\w+]] = OpAccessChain %_ptr_Uniform__struct_3
  797. ; CHECK: [[ac_phi:%\w+]] = OpPhi %_ptr_Uniform__struct_3 [[ac_init]] {{%\w+}} [[ac_update:%\w+]] {{%\w+}}
  798. ; CHECK: [[ac_update]] = OpPtrAccessChain %_ptr_Uniform__struct_3 [[ac_phi]] %int_1
  799. OpCapability Shader
  800. OpMemoryModel Logical GLSL450
  801. OpEntryPoint GLCompute %1 "main"
  802. OpExecutionMode %1 LocalSize 1 1 1
  803. OpSource HLSL 600
  804. OpDecorate %2 DescriptorSet 0
  805. OpDecorate %2 Binding 0
  806. OpMemberDecorate %_struct_3 0 Offset 0
  807. OpDecorate %_runtimearr__struct_3 ArrayStride 4
  808. OpMemberDecorate %_struct_5 0 Offset 0
  809. OpDecorate %_struct_5 BufferBlock
  810. %int = OpTypeInt 32 1
  811. %int_0 = OpConstant %int 0
  812. %int_1 = OpConstant %int 1
  813. %_struct_3 = OpTypeStruct %int
  814. %_struct_9 = OpTypeStruct %int
  815. %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
  816. %_struct_5 = OpTypeStruct %_runtimearr__struct_3
  817. %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
  818. %void = OpTypeVoid
  819. %12 = OpTypeFunction %void
  820. %bool = OpTypeBool
  821. %_ptr_Uniform__struct_3 = OpTypePointer Uniform %_struct_3
  822. %_ptr_Function__struct_9 = OpTypePointer Function %_struct_9
  823. %2 = OpVariable %_ptr_Uniform__struct_5 Uniform
  824. %1 = OpFunction %void None %12
  825. %16 = OpLabel
  826. %17 = OpAccessChain %_ptr_Uniform__struct_3 %2 %int_0 %int_0
  827. OpBranch %18
  828. %18 = OpLabel
  829. %20 = OpPhi %_ptr_Function__struct_9 %17 %16 %21 %22
  830. %23 = OpUndef %bool
  831. OpLoopMerge %24 %22 None
  832. OpBranchConditional %23 %22 %24
  833. %22 = OpLabel
  834. %21 = OpPtrAccessChain %_ptr_Function__struct_9 %20 %int_1
  835. OpBranch %18
  836. %24 = OpLabel
  837. OpReturn
  838. OpFunctionEnd
  839. )";
  840. SinglePassRunAndMatch<FixStorageClass>(text, false);
  841. }
  842. TEST_F(FixStorageClassTest, SupportsU64Index) {
  843. const std::string text = R"(
  844. ; CHECK: OpAccessChain %_ptr_Uniform_float
  845. OpCapability Shader
  846. OpMemoryModel Logical GLSL450
  847. OpEntryPoint GLCompute %1 "testMain" %gl_LocalInvocationID
  848. OpExecutionMode %1 LocalSize 8 8 1
  849. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  850. OpDecorate %8 DescriptorSet 0
  851. OpDecorate %8 Binding 0
  852. OpDecorate %_runtimearr_float ArrayStride 4
  853. OpMemberDecorate %_struct_7 0 Offset 0
  854. OpDecorate %_struct_7 BufferBlock
  855. %ulong = OpTypeInt 64 0
  856. %ulong_0 = OpConstant %ulong 0
  857. %float = OpTypeFloat 32
  858. %float_123 = OpConstant %float 123
  859. %uint = OpTypeInt 32 0
  860. %uint_10 = OpConstant %uint 10
  861. %_runtimearr_float = OpTypeRuntimeArray %float
  862. %_struct_7 = OpTypeStruct %_runtimearr_float
  863. %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
  864. %v3uint = OpTypeVector %uint 3
  865. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  866. %void = OpTypeVoid
  867. %30 = OpTypeFunction %void
  868. %_ptr_Uniform_float = OpTypePointer Uniform %float
  869. %8 = OpVariable %_ptr_Uniform__struct_7 Uniform
  870. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  871. %1 = OpFunction %void None %30
  872. %38 = OpLabel
  873. %44 = OpLoad %v3uint %gl_LocalInvocationID
  874. %59 = OpCompositeExtract %uint %44 0
  875. %60 = OpAccessChain %_ptr_Uniform_float %8 %ulong_0 %59
  876. OpStore %60 %float_123
  877. OpReturn
  878. OpFunctionEnd
  879. )";
  880. SinglePassRunAndMatch<FixStorageClass>(text, false);
  881. }
  882. TEST_F(FixStorageClassTest, CorrectlyProcessAccessChainOnCoopMatrix) {
  883. const std::string text = R"(OpCapability CooperativeMatrixKHR
  884. OpCapability Shader
  885. OpExtension "SPV_KHR_cooperative_matrix"
  886. OpMemoryModel Logical GLSL450
  887. OpEntryPoint GLCompute %1 "main"
  888. OpExecutionMode %1 LocalSize 64 1 1
  889. OpSource HLSL 600
  890. %int = OpTypeInt 32 1
  891. %int_0 = OpConstant %int 0
  892. %uint = OpTypeInt 32 0
  893. %uint_0 = OpConstant %uint 0
  894. %uint_3 = OpConstant %uint 3
  895. %uint_16 = OpConstant %uint 16
  896. %uint_4 = OpConstant %uint 4
  897. %9 = OpTypeCooperativeMatrixKHR %int %uint_3 %uint_16 %uint_4 %uint_0
  898. %void = OpTypeVoid
  899. %11 = OpTypeFunction %void
  900. %_struct_12 = OpTypeStruct %9
  901. %_ptr_Function__struct_12 = OpTypePointer Function %_struct_12
  902. %_ptr_Function_9 = OpTypePointer Function %9
  903. %_ptr_Function_int = OpTypePointer Function %int
  904. %_ptr_Function__ptr_Function_int = OpTypePointer Function %_ptr_Function_int
  905. %1 = OpFunction %void None %11
  906. %17 = OpLabel
  907. %18 = OpVariable %_ptr_Function__ptr_Function_int Function
  908. %19 = OpVariable %_ptr_Function__struct_12 Function
  909. %20 = OpAccessChain %_ptr_Function_9 %19 %int_0
  910. %21 = OpAccessChain %_ptr_Function_int %20 %uint_4
  911. OpStore %18 %21
  912. OpReturn
  913. OpFunctionEnd
  914. )";
  915. SinglePassRunAndCheck<FixStorageClass>(text, text, false, false);
  916. }
  917. // Tests that the pass is not confused when there are multiple definitions
  918. // of a pointer type to the same type with the same storage class.
  919. TEST_F(FixStorageClassTest, DuplicatePointerType) {
  920. const std::string text = R"(OpCapability Shader
  921. OpMemoryModel Logical GLSL450
  922. OpEntryPoint GLCompute %1 "main"
  923. OpExecutionMode %1 LocalSize 64 1 1
  924. OpSource HLSL 600
  925. %uint = OpTypeInt 32 0
  926. %uint_0 = OpConstant %uint 0
  927. %uint_3 = OpConstant %uint 3
  928. %_arr_uint_uint_3 = OpTypeArray %uint %uint_3
  929. %void = OpTypeVoid
  930. %7 = OpTypeFunction %void
  931. %_struct_8 = OpTypeStruct %_arr_uint_uint_3
  932. %_ptr_Function__struct_8 = OpTypePointer Function %_struct_8
  933. %_ptr_Function_uint = OpTypePointer Function %uint
  934. %_ptr_Function__arr_uint_uint_3 = OpTypePointer Function %_arr_uint_uint_3
  935. %_ptr_Function_uint_0 = OpTypePointer Function %uint
  936. %_ptr_Function__ptr_Function_uint_0 = OpTypePointer Function %_ptr_Function_uint_0
  937. %1 = OpFunction %void None %7
  938. %14 = OpLabel
  939. %15 = OpVariable %_ptr_Function__ptr_Function_uint_0 Function
  940. %16 = OpVariable %_ptr_Function__struct_8 Function
  941. %17 = OpAccessChain %_ptr_Function__arr_uint_uint_3 %16 %uint_0
  942. %18 = OpAccessChain %_ptr_Function_uint_0 %17 %uint_0
  943. OpStore %15 %18
  944. OpReturn
  945. OpFunctionEnd
  946. )";
  947. SinglePassRunAndCheck<FixStorageClass>(text, text, false);
  948. }
  949. // This example is generated by DXC when certain inline spiir-v is used.
  950. // The intention is that the function scope variable will eventually be
  951. // optimized away, removing the type mismatch. We want to make sure the
  952. // OpCopyObject is rewritten, and that the pass does not fail.
  953. TEST_F(FixStorageClassTest, DoNotFailWithMismatchedPointerTypes) {
  954. const std::string text = R"(
  955. OpCapability Shader
  956. OpMemoryModel Logical GLSL450
  957. OpEntryPoint GLCompute %1 "main" %38
  958. OpExecutionMode %1 LocalSize 64 1 1
  959. OpSource HLSL 600
  960. %int = OpTypeInt 32 1
  961. %int_0 = OpConstant %int 0
  962. %float = OpTypeFloat 32
  963. %uint = OpTypeInt 32 0
  964. %uint_64 = OpConstant %uint 64
  965. %_arr_float_uint_64 = OpTypeArray %float %uint_64
  966. %_ptr_Workgroup__arr_float_uint_64 = OpTypePointer Workgroup %_arr_float_uint_64
  967. %void = OpTypeVoid
  968. %80 = OpTypeFunction %void
  969. %_ptr_Workgroup_float = OpTypePointer Workgroup %float
  970. %_ptr_Function__ptr_Workgroup_float = OpTypePointer Function %_ptr_Workgroup_float
  971. %_ptr_Workgroup_float_0 = OpTypePointer Workgroup %float
  972. %38 = OpVariable %_ptr_Workgroup__arr_float_uint_64 Workgroup
  973. %1 = OpFunction %void None %80
  974. %98 = OpLabel
  975. ; CHECK: [[var:%\d+]] = OpVariable %_ptr_Function__ptr_Workgroup_float Function
  976. %113 = OpVariable %_ptr_Function__ptr_Workgroup_float Function
  977. ; CHECK: [[ac:%\d+]] = OpAccessChain %_ptr_Workgroup_float_0 {{%\d+}} %int_0
  978. %136 = OpAccessChain %_ptr_Workgroup_float_0 %38 %int_0
  979. ; Verify that the type for the OpCopyObject has changed to match [[ac]].
  980. ; CHECK: [[copy:%\d+]] = OpCopyObject %_ptr_Workgroup_float_0 [[ac]]
  981. %137 = OpCopyObject %_ptr_Workgroup_float %136
  982. ; This has a type mismatch, but this is because we do not have a way to copy
  983. ; a pointer from one type to another, so FixStorageClass cannot do anything
  984. ; about it. We want fix storage class to leave it as is, and the validator
  985. ; will report an error if the store is not remove by a later optimization.
  986. ; CHECK: OpStore [[var]] [[copy]]
  987. OpStore %113 %137
  988. OpReturn
  989. OpFunctionEnd
  990. )";
  991. SinglePassRunAndMatch<FixStorageClass>(text, false);
  992. }
  993. } // namespace
  994. } // namespace opt
  995. } // namespace spvtools