combine_access_chains_test.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. // Copyright (c) 2018 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 "gmock/gmock.h"
  16. #include "test/opt/assembly_builder.h"
  17. #include "test/opt/pass_fixture.h"
  18. #include "test/opt/pass_utils.h"
  19. namespace spvtools {
  20. namespace opt {
  21. namespace {
  22. using CombineAccessChainsTest = PassTest<::testing::Test>;
  23. TEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainConstant) {
  24. const std::string text = R"(
  25. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  26. ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
  27. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  28. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  29. ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int3]]
  30. OpCapability Shader
  31. OpCapability VariablePointers
  32. OpExtension "SPV_KHR_variable_pointers"
  33. OpMemoryModel Logical GLSL450
  34. OpEntryPoint Fragment %main "main"
  35. OpExecutionMode %main OriginUpperLeft
  36. %void = OpTypeVoid
  37. %uint = OpTypeInt 32 0
  38. %uint_0 = OpConstant %uint 0
  39. %uint_3 = OpConstant %uint 3
  40. %uint_4 = OpConstant %uint 4
  41. %uint_array_4 = OpTypeArray %uint %uint_4
  42. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  43. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  44. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  45. %void_func = OpTypeFunction %void
  46. %main = OpFunction %void None %void_func
  47. %main_lab = OpLabel
  48. %gep = OpAccessChain %ptr_Workgroup_uint %var %uint_0
  49. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3
  50. OpReturn
  51. OpFunctionEnd
  52. )";
  53. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  54. }
  55. TEST_F(CombineAccessChainsTest, PtrAccessChainFromInBoundsAccessChainConstant) {
  56. const std::string text = R"(
  57. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  58. ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
  59. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  60. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  61. ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int3]]
  62. OpCapability Shader
  63. OpCapability VariablePointers
  64. OpExtension "SPV_KHR_variable_pointers"
  65. OpMemoryModel Logical GLSL450
  66. OpEntryPoint Fragment %main "main"
  67. OpExecutionMode %main OriginUpperLeft
  68. %void = OpTypeVoid
  69. %uint = OpTypeInt 32 0
  70. %uint_0 = OpConstant %uint 0
  71. %uint_3 = OpConstant %uint 3
  72. %uint_4 = OpConstant %uint 4
  73. %uint_array_4 = OpTypeArray %uint %uint_4
  74. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  75. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  76. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  77. %void_func = OpTypeFunction %void
  78. %main = OpFunction %void None %void_func
  79. %main_lab = OpLabel
  80. %gep = OpInBoundsAccessChain %ptr_Workgroup_uint %var %uint_0
  81. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3
  82. OpReturn
  83. OpFunctionEnd
  84. )";
  85. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  86. }
  87. TEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainCombineConstant) {
  88. const std::string text = R"(
  89. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  90. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  91. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  92. ; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2
  93. ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int2]]
  94. OpCapability Shader
  95. OpCapability VariablePointers
  96. OpExtension "SPV_KHR_variable_pointers"
  97. OpMemoryModel Logical GLSL450
  98. OpEntryPoint Fragment %main "main"
  99. OpExecutionMode %main OriginUpperLeft
  100. %void = OpTypeVoid
  101. %uint = OpTypeInt 32 0
  102. %uint_0 = OpConstant %uint 0
  103. %uint_1 = OpConstant %uint 1
  104. %uint_4 = OpConstant %uint 4
  105. %uint_array_4 = OpTypeArray %uint %uint_4
  106. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  107. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  108. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  109. %void_func = OpTypeFunction %void
  110. %main = OpFunction %void None %void_func
  111. %main_lab = OpLabel
  112. %gep = OpAccessChain %ptr_Workgroup_uint %var %uint_1
  113. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_1
  114. OpReturn
  115. OpFunctionEnd
  116. )";
  117. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  118. }
  119. TEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainNonConstant) {
  120. const std::string text = R"(
  121. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  122. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  123. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  124. ; CHECK: [[ld1:%\w+]] = OpLoad
  125. ; CHECK: [[ld2:%\w+]] = OpLoad
  126. ; CHECK: [[add:%\w+]] = OpIAdd [[int]] [[ld1]] [[ld2]]
  127. ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[add]]
  128. OpCapability Shader
  129. OpCapability VariablePointers
  130. OpExtension "SPV_KHR_variable_pointers"
  131. OpMemoryModel Logical GLSL450
  132. OpEntryPoint Fragment %main "main"
  133. OpExecutionMode %main OriginUpperLeft
  134. %void = OpTypeVoid
  135. %uint = OpTypeInt 32 0
  136. %uint_0 = OpConstant %uint 0
  137. %uint_4 = OpConstant %uint 4
  138. %uint_array_4 = OpTypeArray %uint %uint_4
  139. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  140. %ptr_Function_uint = OpTypePointer Function %uint
  141. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  142. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  143. %void_func = OpTypeFunction %void
  144. %main = OpFunction %void None %void_func
  145. %main_lab = OpLabel
  146. %local_var = OpVariable %ptr_Function_uint Function
  147. %ld1 = OpLoad %uint %local_var
  148. %gep = OpAccessChain %ptr_Workgroup_uint %var %ld1
  149. %ld2 = OpLoad %uint %local_var
  150. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %ld2
  151. OpReturn
  152. OpFunctionEnd
  153. )";
  154. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  155. }
  156. TEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainExtraIndices) {
  157. const std::string text = R"(
  158. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  159. ; CHECK: [[int1:%\w+]] = OpConstant [[int]] 1
  160. ; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2
  161. ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
  162. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  163. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  164. ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int1]] [[int2]] [[int3]]
  165. OpCapability Shader
  166. OpCapability VariablePointers
  167. OpExtension "SPV_KHR_variable_pointers"
  168. OpMemoryModel Logical GLSL450
  169. OpEntryPoint Fragment %main "main"
  170. OpExecutionMode %main OriginUpperLeft
  171. %void = OpTypeVoid
  172. %uint = OpTypeInt 32 0
  173. %uint_0 = OpConstant %uint 0
  174. %uint_1 = OpConstant %uint 1
  175. %uint_2 = OpConstant %uint 2
  176. %uint_3 = OpConstant %uint 3
  177. %uint_4 = OpConstant %uint 4
  178. %uint_array_4 = OpTypeArray %uint %uint_4
  179. %uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4
  180. %uint_array_4_array_4_array_4 = OpTypeArray %uint_array_4_array_4 %uint_4
  181. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  182. %ptr_Function_uint = OpTypePointer Function %uint
  183. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  184. %ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4
  185. %ptr_Workgroup_uint_array_4_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4_array_4
  186. %var = OpVariable %ptr_Workgroup_uint_array_4_array_4_array_4 Workgroup
  187. %void_func = OpTypeFunction %void
  188. %main = OpFunction %void None %void_func
  189. %main_lab = OpLabel
  190. %gep = OpAccessChain %ptr_Workgroup_uint_array_4 %var %uint_1 %uint_0
  191. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_2 %uint_3
  192. OpReturn
  193. OpFunctionEnd
  194. )";
  195. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  196. }
  197. TEST_F(CombineAccessChainsTest,
  198. PtrAccessChainFromPtrAccessChainCombineElementOperand) {
  199. const std::string text = R"(
  200. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  201. ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
  202. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  203. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  204. ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
  205. ; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int6]] [[int3]]
  206. OpCapability Shader
  207. OpCapability VariablePointers
  208. OpExtension "SPV_KHR_variable_pointers"
  209. OpMemoryModel Logical GLSL450
  210. OpEntryPoint Fragment %main "main"
  211. OpExecutionMode %main OriginUpperLeft
  212. %void = OpTypeVoid
  213. %uint = OpTypeInt 32 0
  214. %uint_0 = OpConstant %uint 0
  215. %uint_3 = OpConstant %uint 3
  216. %uint_4 = OpConstant %uint 4
  217. %uint_array_4 = OpTypeArray %uint %uint_4
  218. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  219. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  220. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  221. %void_func = OpTypeFunction %void
  222. %main = OpFunction %void None %void_func
  223. %main_lab = OpLabel
  224. %gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
  225. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3 %uint_3
  226. OpReturn
  227. OpFunctionEnd
  228. )";
  229. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  230. }
  231. TEST_F(CombineAccessChainsTest,
  232. PtrAccessChainFromPtrAccessChainOnlyElementOperand) {
  233. const std::string text = R"(
  234. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  235. ; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4
  236. ; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]]
  237. ; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]]
  238. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  239. ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
  240. ; CHECK: OpPtrAccessChain [[ptr_array]] [[var]] [[int6]]
  241. OpCapability Shader
  242. OpCapability VariablePointers
  243. OpExtension "SPV_KHR_variable_pointers"
  244. OpMemoryModel Logical GLSL450
  245. OpEntryPoint Fragment %main "main"
  246. OpExecutionMode %main OriginUpperLeft
  247. %void = OpTypeVoid
  248. %uint = OpTypeInt 32 0
  249. %uint_0 = OpConstant %uint 0
  250. %uint_3 = OpConstant %uint 3
  251. %uint_4 = OpConstant %uint 4
  252. %uint_array_4 = OpTypeArray %uint %uint_4
  253. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  254. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  255. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  256. %void_func = OpTypeFunction %void
  257. %main = OpFunction %void None %void_func
  258. %main_lab = OpLabel
  259. %gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
  260. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3
  261. OpReturn
  262. OpFunctionEnd
  263. )";
  264. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  265. }
  266. TEST_F(CombineAccessChainsTest,
  267. PtrAccessChainFromPtrAccessCombineNonElementIndex) {
  268. const std::string text = R"(
  269. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  270. ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
  271. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  272. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  273. ; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int3]] [[int3]] [[int3]]
  274. OpCapability Shader
  275. OpCapability VariablePointers
  276. OpExtension "SPV_KHR_variable_pointers"
  277. OpMemoryModel Logical GLSL450
  278. OpEntryPoint Fragment %main "main"
  279. OpExecutionMode %main OriginUpperLeft
  280. %void = OpTypeVoid
  281. %uint = OpTypeInt 32 0
  282. %uint_0 = OpConstant %uint 0
  283. %uint_3 = OpConstant %uint 3
  284. %uint_4 = OpConstant %uint 4
  285. %uint_array_4 = OpTypeArray %uint %uint_4
  286. %uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4
  287. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  288. %ptr_Function_uint = OpTypePointer Function %uint
  289. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  290. %ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4
  291. %var = OpVariable %ptr_Workgroup_uint_array_4_array_4 Workgroup
  292. %void_func = OpTypeFunction %void
  293. %main = OpFunction %void None %void_func
  294. %main_lab = OpLabel
  295. %gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3 %uint_0
  296. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3 %uint_3
  297. OpReturn
  298. OpFunctionEnd
  299. )";
  300. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  301. }
  302. TEST_F(CombineAccessChainsTest,
  303. AccessChainFromPtrAccessChainOnlyElementOperand) {
  304. const std::string text = R"(
  305. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  306. ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
  307. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  308. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  309. ; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int3]] [[int3]]
  310. OpCapability Shader
  311. OpCapability VariablePointers
  312. OpExtension "SPV_KHR_variable_pointers"
  313. OpMemoryModel Logical GLSL450
  314. OpEntryPoint Fragment %main "main"
  315. OpExecutionMode %main OriginUpperLeft
  316. %void = OpTypeVoid
  317. %uint = OpTypeInt 32 0
  318. %uint_0 = OpConstant %uint 0
  319. %uint_3 = OpConstant %uint 3
  320. %uint_4 = OpConstant %uint 4
  321. %uint_array_4 = OpTypeArray %uint %uint_4
  322. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  323. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  324. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  325. %void_func = OpTypeFunction %void
  326. %main = OpFunction %void None %void_func
  327. %main_lab = OpLabel
  328. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
  329. %gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_3
  330. OpReturn
  331. OpFunctionEnd
  332. )";
  333. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  334. }
  335. TEST_F(CombineAccessChainsTest, AccessChainFromPtrAccessChainAppend) {
  336. const std::string text = R"(
  337. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  338. ; CHECK: [[int1:%\w+]] = OpConstant [[int]] 1
  339. ; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2
  340. ; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
  341. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  342. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  343. ; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int1]] [[int2]] [[int3]]
  344. OpCapability Shader
  345. OpCapability VariablePointers
  346. OpExtension "SPV_KHR_variable_pointers"
  347. OpMemoryModel Logical GLSL450
  348. OpEntryPoint Fragment %main "main"
  349. OpExecutionMode %main OriginUpperLeft
  350. %void = OpTypeVoid
  351. %uint = OpTypeInt 32 0
  352. %uint_0 = OpConstant %uint 0
  353. %uint_1 = OpConstant %uint 1
  354. %uint_2 = OpConstant %uint 2
  355. %uint_3 = OpConstant %uint 3
  356. %uint_4 = OpConstant %uint 4
  357. %uint_array_4 = OpTypeArray %uint %uint_4
  358. %uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4
  359. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  360. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  361. %ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4
  362. %var = OpVariable %ptr_Workgroup_uint_array_4_array_4 Workgroup
  363. %void_func = OpTypeFunction %void
  364. %main = OpFunction %void None %void_func
  365. %main_lab = OpLabel
  366. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_1 %uint_2
  367. %gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_3
  368. OpReturn
  369. OpFunctionEnd
  370. )";
  371. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  372. }
  373. TEST_F(CombineAccessChainsTest, AccessChainFromAccessChainAppend) {
  374. const std::string text = R"(
  375. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  376. ; CHECK: [[int1:%\w+]] = OpConstant [[int]] 1
  377. ; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2
  378. ; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
  379. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  380. ; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int1]] [[int2]]
  381. OpCapability Shader
  382. OpCapability VariablePointers
  383. OpExtension "SPV_KHR_variable_pointers"
  384. OpMemoryModel Logical GLSL450
  385. OpEntryPoint Fragment %main "main"
  386. OpExecutionMode %main OriginUpperLeft
  387. %void = OpTypeVoid
  388. %uint = OpTypeInt 32 0
  389. %uint_0 = OpConstant %uint 0
  390. %uint_1 = OpConstant %uint 1
  391. %uint_2 = OpConstant %uint 2
  392. %uint_3 = OpConstant %uint 3
  393. %uint_4 = OpConstant %uint 4
  394. %uint_array_4 = OpTypeArray %uint %uint_4
  395. %uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4
  396. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  397. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  398. %ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4
  399. %var = OpVariable %ptr_Workgroup_uint_array_4_array_4 Workgroup
  400. %void_func = OpTypeFunction %void
  401. %main = OpFunction %void None %void_func
  402. %main_lab = OpLabel
  403. %ptr_gep = OpAccessChain %ptr_Workgroup_uint_array_4 %var %uint_1
  404. %gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_2
  405. OpReturn
  406. OpFunctionEnd
  407. )";
  408. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  409. }
  410. TEST_F(CombineAccessChainsTest, NonConstantStructSlide) {
  411. const std::string text = R"(
  412. ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
  413. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  414. ; CHECK: [[ld:%\w+]] = OpLoad
  415. ; CHECK: OpPtrAccessChain {{%\w+}} [[var]] [[ld]] [[int0]]
  416. OpCapability Shader
  417. OpCapability VariablePointers
  418. OpExtension "SPV_KHR_variable_pointers"
  419. OpMemoryModel Logical GLSL450
  420. OpEntryPoint Fragment %main "main"
  421. OpExecutionMode %main OriginUpperLeft
  422. %void = OpTypeVoid
  423. %uint = OpTypeInt 32 0
  424. %uint_0 = OpConstant %uint 0
  425. %struct = OpTypeStruct %uint %uint
  426. %ptr_Workgroup_struct = OpTypePointer Workgroup %struct
  427. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  428. %ptr_Function_uint = OpTypePointer Function %uint
  429. %wg_var = OpVariable %ptr_Workgroup_struct Workgroup
  430. %void_func = OpTypeFunction %void
  431. %main = OpFunction %void None %void_func
  432. %1 = OpLabel
  433. %func_var = OpVariable %ptr_Function_uint Function
  434. %ld = OpLoad %uint %func_var
  435. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_struct %wg_var %ld
  436. %gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_0
  437. OpReturn
  438. OpFunctionEnd
  439. )";
  440. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  441. }
  442. TEST_F(CombineAccessChainsTest, DontCombineNonConstantStructSlide) {
  443. const std::string text = R"(
  444. ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
  445. ; CHECK: [[ld:%\w+]] = OpLoad
  446. ; CHECK: [[gep:%\w+]] = OpAccessChain
  447. ; CHECK: OpPtrAccessChain {{%\w+}} [[gep]] [[ld]] [[int0]]
  448. OpCapability Shader
  449. OpCapability VariablePointers
  450. OpExtension "SPV_KHR_variable_pointers"
  451. OpMemoryModel Logical GLSL450
  452. OpEntryPoint Fragment %main "main"
  453. OpExecutionMode %main OriginUpperLeft
  454. %void = OpTypeVoid
  455. %uint = OpTypeInt 32 0
  456. %uint_0 = OpConstant %uint 0
  457. %uint_4 = OpConstant %uint 4
  458. %struct = OpTypeStruct %uint %uint
  459. %struct_array_4 = OpTypeArray %struct %uint_4
  460. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  461. %ptr_Function_uint = OpTypePointer Function %uint
  462. %ptr_Workgroup_struct = OpTypePointer Workgroup %struct
  463. %ptr_Workgroup_struct_array_4 = OpTypePointer Workgroup %struct_array_4
  464. %wg_var = OpVariable %ptr_Workgroup_struct_array_4 Workgroup
  465. %void_func = OpTypeFunction %void
  466. %main = OpFunction %void None %void_func
  467. %1 = OpLabel
  468. %func_var = OpVariable %ptr_Function_uint Function
  469. %ld = OpLoad %uint %func_var
  470. %gep = OpAccessChain %ptr_Workgroup_struct %wg_var %uint_0
  471. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %ld %uint_0
  472. OpReturn
  473. OpFunctionEnd
  474. )";
  475. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  476. }
  477. TEST_F(CombineAccessChainsTest, CombineNonConstantStructSlideElement) {
  478. const std::string text = R"(
  479. ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
  480. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  481. ; CHECK: [[ld:%\w+]] = OpLoad
  482. ; CHECK: [[add:%\w+]] = OpIAdd {{%\w+}} [[ld]] [[ld]]
  483. ; CHECK: OpPtrAccessChain {{%\w+}} [[var]] [[add]] [[int0]]
  484. OpCapability Shader
  485. OpCapability VariablePointers
  486. OpExtension "SPV_KHR_variable_pointers"
  487. OpMemoryModel Logical GLSL450
  488. OpEntryPoint Fragment %main "main"
  489. OpExecutionMode %main OriginUpperLeft
  490. %void = OpTypeVoid
  491. %uint = OpTypeInt 32 0
  492. %uint_0 = OpConstant %uint 0
  493. %uint_4 = OpConstant %uint 4
  494. %struct = OpTypeStruct %uint %uint
  495. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  496. %ptr_Function_uint = OpTypePointer Function %uint
  497. %ptr_Workgroup_struct = OpTypePointer Workgroup %struct
  498. %wg_var = OpVariable %ptr_Workgroup_struct Workgroup
  499. %void_func = OpTypeFunction %void
  500. %main = OpFunction %void None %void_func
  501. %1 = OpLabel
  502. %func_var = OpVariable %ptr_Function_uint Function
  503. %ld = OpLoad %uint %func_var
  504. %gep = OpPtrAccessChain %ptr_Workgroup_struct %wg_var %ld
  505. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %ld %uint_0
  506. OpReturn
  507. OpFunctionEnd
  508. )";
  509. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  510. }
  511. TEST_F(CombineAccessChainsTest, PtrAccessChainFromInBoundsPtrAccessChain) {
  512. const std::string text = R"(
  513. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  514. ; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4
  515. ; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]]
  516. ; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]]
  517. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  518. ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
  519. ; CHECK: OpPtrAccessChain [[ptr_array]] [[var]] [[int6]]
  520. OpCapability Shader
  521. OpCapability VariablePointers
  522. OpCapability Addresses
  523. OpExtension "SPV_KHR_variable_pointers"
  524. OpMemoryModel Logical GLSL450
  525. OpEntryPoint Fragment %main "main"
  526. OpExecutionMode %main OriginUpperLeft
  527. %void = OpTypeVoid
  528. %uint = OpTypeInt 32 0
  529. %uint_0 = OpConstant %uint 0
  530. %uint_3 = OpConstant %uint 3
  531. %uint_4 = OpConstant %uint 4
  532. %uint_array_4 = OpTypeArray %uint %uint_4
  533. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  534. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  535. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  536. %void_func = OpTypeFunction %void
  537. %main = OpFunction %void None %void_func
  538. %main_lab = OpLabel
  539. %gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
  540. %ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3
  541. OpReturn
  542. OpFunctionEnd
  543. )";
  544. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  545. }
  546. TEST_F(CombineAccessChainsTest, InBoundsPtrAccessChainFromPtrAccessChain) {
  547. const std::string text = R"(
  548. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  549. ; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4
  550. ; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]]
  551. ; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]]
  552. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  553. ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
  554. ; CHECK: OpPtrAccessChain [[ptr_array]] [[var]] [[int6]]
  555. OpCapability Shader
  556. OpCapability VariablePointers
  557. OpCapability Addresses
  558. OpExtension "SPV_KHR_variable_pointers"
  559. OpMemoryModel Logical GLSL450
  560. OpEntryPoint Fragment %main "main"
  561. OpExecutionMode %main OriginUpperLeft
  562. %void = OpTypeVoid
  563. %uint = OpTypeInt 32 0
  564. %uint_0 = OpConstant %uint 0
  565. %uint_3 = OpConstant %uint 3
  566. %uint_4 = OpConstant %uint 4
  567. %uint_array_4 = OpTypeArray %uint %uint_4
  568. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  569. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  570. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  571. %void_func = OpTypeFunction %void
  572. %main = OpFunction %void None %void_func
  573. %main_lab = OpLabel
  574. %gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
  575. %ptr_gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3
  576. OpReturn
  577. OpFunctionEnd
  578. )";
  579. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  580. }
  581. TEST_F(CombineAccessChainsTest,
  582. InBoundsPtrAccessChainFromInBoundsPtrAccessChain) {
  583. const std::string text = R"(
  584. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  585. ; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4
  586. ; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]]
  587. ; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]]
  588. ; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
  589. ; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
  590. ; CHECK: OpInBoundsPtrAccessChain [[ptr_array]] [[var]] [[int6]]
  591. OpCapability Shader
  592. OpCapability VariablePointers
  593. OpCapability Addresses
  594. OpExtension "SPV_KHR_variable_pointers"
  595. OpMemoryModel Logical GLSL450
  596. OpEntryPoint Fragment %main "main"
  597. OpExecutionMode %main OriginUpperLeft
  598. %void = OpTypeVoid
  599. %uint = OpTypeInt 32 0
  600. %uint_0 = OpConstant %uint 0
  601. %uint_3 = OpConstant %uint 3
  602. %uint_4 = OpConstant %uint 4
  603. %uint_array_4 = OpTypeArray %uint %uint_4
  604. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  605. %ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
  606. %var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
  607. %void_func = OpTypeFunction %void
  608. %main = OpFunction %void None %void_func
  609. %main_lab = OpLabel
  610. %gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
  611. %ptr_gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3
  612. OpReturn
  613. OpFunctionEnd
  614. )";
  615. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  616. }
  617. TEST_F(CombineAccessChainsTest, NoIndexAccessChains) {
  618. const std::string text = R"(
  619. ; CHECK: [[var:%\w+]] = OpVariable
  620. ; CHECK-NOT: OpConstant
  621. ; CHECK: [[gep:%\w+]] = OpAccessChain {{%\w+}} [[var]]
  622. ; CHECK: OpAccessChain {{%\w+}} [[var]]
  623. OpCapability Shader
  624. OpMemoryModel Logical GLSL450
  625. OpEntryPoint Fragment %func "func"
  626. OpExecutionMode %func OriginUpperLeft
  627. %void = OpTypeVoid
  628. %uint = OpTypeInt 32 0
  629. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  630. %var = OpVariable %ptr_Workgroup_uint Workgroup
  631. %void_func = OpTypeFunction %void
  632. %func = OpFunction %void None %void_func
  633. %1 = OpLabel
  634. %gep1 = OpAccessChain %ptr_Workgroup_uint %var
  635. %gep2 = OpAccessChain %ptr_Workgroup_uint %gep1
  636. OpReturn
  637. OpFunctionEnd
  638. )";
  639. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  640. }
  641. TEST_F(CombineAccessChainsTest, NoIndexPtrAccessChains) {
  642. const std::string text = R"(
  643. ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
  644. ; CHECK: [[var:%\w+]] = OpVariable
  645. ; CHECK: [[gep:%\w+]] = OpPtrAccessChain {{%\w+}} [[var]] [[int0]]
  646. ; CHECK: OpCopyObject {{%\w+}} [[gep]]
  647. OpCapability Shader
  648. OpCapability VariablePointers
  649. OpExtension "SPV_KHR_variable_pointers"
  650. OpMemoryModel Logical GLSL450
  651. OpEntryPoint Fragment %func "func"
  652. OpExecutionMode %func OriginUpperLeft
  653. %void = OpTypeVoid
  654. %uint = OpTypeInt 32 0
  655. %uint_0 = OpConstant %uint 0
  656. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  657. %var = OpVariable %ptr_Workgroup_uint Workgroup
  658. %void_func = OpTypeFunction %void
  659. %func = OpFunction %void None %void_func
  660. %1 = OpLabel
  661. %gep1 = OpPtrAccessChain %ptr_Workgroup_uint %var %uint_0
  662. %gep2 = OpAccessChain %ptr_Workgroup_uint %gep1
  663. OpReturn
  664. OpFunctionEnd
  665. )";
  666. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  667. }
  668. TEST_F(CombineAccessChainsTest, NoIndexPtrAccessChains2) {
  669. const std::string text = R"(
  670. ; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
  671. ; CHECK: [[var:%\w+]] = OpVariable
  672. ; CHECK: OpPtrAccessChain {{%\w+}} [[var]] [[int0]]
  673. OpCapability Shader
  674. OpCapability VariablePointers
  675. OpExtension "SPV_KHR_variable_pointers"
  676. OpMemoryModel Logical GLSL450
  677. OpEntryPoint Fragment %func "func"
  678. OpExecutionMode %func OriginUpperLeft
  679. %void = OpTypeVoid
  680. %uint = OpTypeInt 32 0
  681. %uint_0 = OpConstant %uint 0
  682. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  683. %var = OpVariable %ptr_Workgroup_uint Workgroup
  684. %void_func = OpTypeFunction %void
  685. %func = OpFunction %void None %void_func
  686. %1 = OpLabel
  687. %gep1 = OpAccessChain %ptr_Workgroup_uint %var
  688. %gep2 = OpPtrAccessChain %ptr_Workgroup_uint %gep1 %uint_0
  689. OpReturn
  690. OpFunctionEnd
  691. )";
  692. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  693. }
  694. TEST_F(CombineAccessChainsTest, CombineMixedSign) {
  695. const std::string text = R"(
  696. ; CHECK: [[uint:%\w+]] = OpTypeInt 32 0
  697. ; CHECK: [[var:%\w+]] = OpVariable
  698. ; CHECK: [[uint2:%\w+]] = OpConstant [[uint]] 2
  699. ; CHECK: OpInBoundsPtrAccessChain {{%\w+}} [[var]] [[uint2]]
  700. OpCapability Shader
  701. OpCapability VariablePointers
  702. OpCapability Addresses
  703. OpExtension "SPV_KHR_variable_pointers"
  704. OpMemoryModel Logical GLSL450
  705. OpEntryPoint Fragment %func "func"
  706. OpExecutionMode %func OriginUpperLeft
  707. %void = OpTypeVoid
  708. %uint = OpTypeInt 32 0
  709. %int = OpTypeInt 32 1
  710. %uint_1 = OpConstant %uint 1
  711. %int_1 = OpConstant %int 1
  712. %ptr_Workgroup_uint = OpTypePointer Workgroup %uint
  713. %var = OpVariable %ptr_Workgroup_uint Workgroup
  714. %void_func = OpTypeFunction %void
  715. %func = OpFunction %void None %void_func
  716. %1 = OpLabel
  717. %gep1 = OpInBoundsPtrAccessChain %ptr_Workgroup_uint %var %uint_1
  718. %gep2 = OpInBoundsPtrAccessChain %ptr_Workgroup_uint %gep1 %int_1
  719. OpReturn
  720. OpFunctionEnd
  721. )";
  722. SinglePassRunAndMatch<CombineAccessChains>(text, true);
  723. }
  724. } // namespace
  725. } // namespace opt
  726. } // namespace spvtools