combine_access_chains_test.cpp 27 KB

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