copy_prop_array_test.cpp 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576
  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 <iostream>
  15. #include <string>
  16. #include "gmock/gmock.h"
  17. #include "test/opt/assembly_builder.h"
  18. #include "test/opt/pass_fixture.h"
  19. namespace spvtools {
  20. namespace opt {
  21. namespace {
  22. using CopyPropArrayPassTest = PassTest<::testing::Test>;
  23. TEST_F(CopyPropArrayPassTest, BasicPropagateArray) {
  24. const std::string before =
  25. R"(
  26. OpCapability Shader
  27. OpMemoryModel Logical GLSL450
  28. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  29. OpExecutionMode %main OriginUpperLeft
  30. OpSource HLSL 600
  31. OpName %type_MyCBuffer "type.MyCBuffer"
  32. OpMemberName %type_MyCBuffer 0 "Data"
  33. OpName %MyCBuffer "MyCBuffer"
  34. OpName %main "main"
  35. OpName %in_var_INDEX "in.var.INDEX"
  36. OpName %out_var_SV_Target "out.var.SV_Target"
  37. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  38. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  39. OpDecorate %type_MyCBuffer Block
  40. OpDecorate %in_var_INDEX Flat
  41. OpDecorate %in_var_INDEX Location 0
  42. OpDecorate %out_var_SV_Target Location 0
  43. OpDecorate %MyCBuffer DescriptorSet 0
  44. OpDecorate %MyCBuffer Binding 0
  45. %float = OpTypeFloat 32
  46. %v4float = OpTypeVector %float 4
  47. %uint = OpTypeInt 32 0
  48. %uint_8 = OpConstant %uint 8
  49. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  50. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  51. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  52. %void = OpTypeVoid
  53. %13 = OpTypeFunction %void
  54. %int = OpTypeInt 32 1
  55. %_ptr_Input_int = OpTypePointer Input %int
  56. %_ptr_Output_v4float = OpTypePointer Output %v4float
  57. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  58. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  59. %int_0 = OpConstant %int 0
  60. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  61. %_ptr_Function_v4float = OpTypePointer Function %v4float
  62. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  63. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  64. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  65. ; CHECK: OpFunction
  66. ; CHECK: OpLabel
  67. ; CHECK: OpVariable
  68. ; CHECK: OpAccessChain
  69. ; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  70. ; CHECK: [[element_ptr:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[new_address]] %24
  71. ; CHECK: [[load:%\w+]] = OpLoad %v4float [[element_ptr]]
  72. ; CHECK: OpStore %out_var_SV_Target [[load]]
  73. %main = OpFunction %void None %13
  74. %22 = OpLabel
  75. %23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  76. %24 = OpLoad %int %in_var_INDEX
  77. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  78. %26 = OpLoad %_arr_v4float_uint_8 %25
  79. %27 = OpCompositeExtract %v4float %26 0
  80. %28 = OpCompositeExtract %v4float %26 1
  81. %29 = OpCompositeExtract %v4float %26 2
  82. %30 = OpCompositeExtract %v4float %26 3
  83. %31 = OpCompositeExtract %v4float %26 4
  84. %32 = OpCompositeExtract %v4float %26 5
  85. %33 = OpCompositeExtract %v4float %26 6
  86. %34 = OpCompositeExtract %v4float %26 7
  87. %35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
  88. OpStore %23 %35
  89. %36 = OpAccessChain %_ptr_Function_v4float %23 %24
  90. %37 = OpLoad %v4float %36
  91. OpStore %out_var_SV_Target %37
  92. OpReturn
  93. OpFunctionEnd
  94. )";
  95. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  96. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  97. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  98. SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
  99. }
  100. TEST_F(CopyPropArrayPassTest, BasicPropagateArrayWithName) {
  101. const std::string before =
  102. R"(
  103. OpCapability Shader
  104. OpMemoryModel Logical GLSL450
  105. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  106. OpExecutionMode %main OriginUpperLeft
  107. OpSource HLSL 600
  108. OpName %type_MyCBuffer "type.MyCBuffer"
  109. OpMemberName %type_MyCBuffer 0 "Data"
  110. OpName %MyCBuffer "MyCBuffer"
  111. OpName %main "main"
  112. OpName %local "local"
  113. OpName %in_var_INDEX "in.var.INDEX"
  114. OpName %out_var_SV_Target "out.var.SV_Target"
  115. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  116. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  117. OpDecorate %type_MyCBuffer Block
  118. OpDecorate %in_var_INDEX Flat
  119. OpDecorate %in_var_INDEX Location 0
  120. OpDecorate %out_var_SV_Target Location 0
  121. OpDecorate %MyCBuffer DescriptorSet 0
  122. OpDecorate %MyCBuffer Binding 0
  123. %float = OpTypeFloat 32
  124. %v4float = OpTypeVector %float 4
  125. %uint = OpTypeInt 32 0
  126. %uint_8 = OpConstant %uint 8
  127. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  128. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  129. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  130. %void = OpTypeVoid
  131. %13 = OpTypeFunction %void
  132. %int = OpTypeInt 32 1
  133. %_ptr_Input_int = OpTypePointer Input %int
  134. %_ptr_Output_v4float = OpTypePointer Output %v4float
  135. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  136. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  137. %int_0 = OpConstant %int 0
  138. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  139. %_ptr_Function_v4float = OpTypePointer Function %v4float
  140. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  141. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  142. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  143. ; CHECK: OpFunction
  144. ; CHECK: OpLabel
  145. ; CHECK: OpVariable
  146. ; CHECK: OpAccessChain
  147. ; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  148. ; CHECK: [[element_ptr:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[new_address]] %24
  149. ; CHECK: [[load:%\w+]] = OpLoad %v4float [[element_ptr]]
  150. ; CHECK: OpStore %out_var_SV_Target [[load]]
  151. %main = OpFunction %void None %13
  152. %22 = OpLabel
  153. %local = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  154. %24 = OpLoad %int %in_var_INDEX
  155. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  156. %26 = OpLoad %_arr_v4float_uint_8 %25
  157. %27 = OpCompositeExtract %v4float %26 0
  158. %28 = OpCompositeExtract %v4float %26 1
  159. %29 = OpCompositeExtract %v4float %26 2
  160. %30 = OpCompositeExtract %v4float %26 3
  161. %31 = OpCompositeExtract %v4float %26 4
  162. %32 = OpCompositeExtract %v4float %26 5
  163. %33 = OpCompositeExtract %v4float %26 6
  164. %34 = OpCompositeExtract %v4float %26 7
  165. %35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
  166. OpStore %local %35
  167. %36 = OpAccessChain %_ptr_Function_v4float %local %24
  168. %37 = OpLoad %v4float %36
  169. OpStore %out_var_SV_Target %37
  170. OpReturn
  171. OpFunctionEnd
  172. )";
  173. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  174. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  175. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  176. SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
  177. }
  178. // Propagate 2d array. This test identifying a copy through multiple levels.
  179. // Also has to traverse multiple OpAccessChains.
  180. TEST_F(CopyPropArrayPassTest, Propagate2DArray) {
  181. const std::string text =
  182. R"(OpCapability Shader
  183. OpMemoryModel Logical GLSL450
  184. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  185. OpExecutionMode %main OriginUpperLeft
  186. OpSource HLSL 600
  187. OpName %type_MyCBuffer "type.MyCBuffer"
  188. OpMemberName %type_MyCBuffer 0 "Data"
  189. OpName %MyCBuffer "MyCBuffer"
  190. OpName %main "main"
  191. OpName %in_var_INDEX "in.var.INDEX"
  192. OpName %out_var_SV_Target "out.var.SV_Target"
  193. OpDecorate %_arr_v4float_uint_2 ArrayStride 16
  194. OpDecorate %_arr__arr_v4float_uint_2_uint_2 ArrayStride 32
  195. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  196. OpDecorate %type_MyCBuffer Block
  197. OpDecorate %in_var_INDEX Flat
  198. OpDecorate %in_var_INDEX Location 0
  199. OpDecorate %out_var_SV_Target Location 0
  200. OpDecorate %MyCBuffer DescriptorSet 0
  201. OpDecorate %MyCBuffer Binding 0
  202. %float = OpTypeFloat 32
  203. %v4float = OpTypeVector %float 4
  204. %uint = OpTypeInt 32 0
  205. %uint_2 = OpConstant %uint 2
  206. %_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
  207. %_arr__arr_v4float_uint_2_uint_2 = OpTypeArray %_arr_v4float_uint_2 %uint_2
  208. %type_MyCBuffer = OpTypeStruct %_arr__arr_v4float_uint_2_uint_2
  209. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  210. %void = OpTypeVoid
  211. %14 = OpTypeFunction %void
  212. %int = OpTypeInt 32 1
  213. %_ptr_Input_int = OpTypePointer Input %int
  214. %_ptr_Output_v4float = OpTypePointer Output %v4float
  215. %_arr_v4float_uint_2_0 = OpTypeArray %v4float %uint_2
  216. %_arr__arr_v4float_uint_2_0_uint_2 = OpTypeArray %_arr_v4float_uint_2_0 %uint_2
  217. %_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 = OpTypePointer Function %_arr__arr_v4float_uint_2_0_uint_2
  218. %int_0 = OpConstant %int 0
  219. %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_v4float_uint_2_uint_2
  220. %_ptr_Function__arr_v4float_uint_2_0 = OpTypePointer Function %_arr_v4float_uint_2_0
  221. %_ptr_Function_v4float = OpTypePointer Function %v4float
  222. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  223. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  224. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  225. ; CHECK: OpFunction
  226. ; CHECK: OpLabel
  227. ; CHECK: OpVariable
  228. ; CHECK: OpVariable
  229. ; CHECK: OpAccessChain
  230. ; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
  231. %main = OpFunction %void None %14
  232. %25 = OpLabel
  233. %26 = OpVariable %_ptr_Function__arr_v4float_uint_2_0 Function
  234. %27 = OpVariable %_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 Function
  235. %28 = OpLoad %int %in_var_INDEX
  236. %29 = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
  237. %30 = OpLoad %_arr__arr_v4float_uint_2_uint_2 %29
  238. %31 = OpCompositeExtract %_arr_v4float_uint_2 %30 0
  239. %32 = OpCompositeExtract %v4float %31 0
  240. %33 = OpCompositeExtract %v4float %31 1
  241. %34 = OpCompositeConstruct %_arr_v4float_uint_2_0 %32 %33
  242. %35 = OpCompositeExtract %_arr_v4float_uint_2 %30 1
  243. %36 = OpCompositeExtract %v4float %35 0
  244. %37 = OpCompositeExtract %v4float %35 1
  245. %38 = OpCompositeConstruct %_arr_v4float_uint_2_0 %36 %37
  246. %39 = OpCompositeConstruct %_arr__arr_v4float_uint_2_0_uint_2 %34 %38
  247. ; CHECK: OpStore
  248. OpStore %27 %39
  249. %40 = OpAccessChain %_ptr_Function__arr_v4float_uint_2_0 %27 %28
  250. %42 = OpAccessChain %_ptr_Function_v4float %40 %28
  251. %43 = OpLoad %v4float %42
  252. ; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_2 [[new_address]] %28
  253. ; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[ac1]] %28
  254. ; CHECK: [[load:%\w+]] = OpLoad %v4float [[ac2]]
  255. ; CHECK: OpStore %out_var_SV_Target [[load]]
  256. OpStore %out_var_SV_Target %43
  257. OpReturn
  258. OpFunctionEnd
  259. )";
  260. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  261. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  262. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  263. SinglePassRunAndMatch<CopyPropagateArrays>(text, false);
  264. }
  265. // Propagate 2d array. This test identifying a copy through multiple levels.
  266. // Also has to traverse multiple OpAccessChains.
  267. TEST_F(CopyPropArrayPassTest, Propagate2DArrayWithMultiLevelExtract) {
  268. const std::string text =
  269. R"(OpCapability Shader
  270. OpMemoryModel Logical GLSL450
  271. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  272. OpExecutionMode %main OriginUpperLeft
  273. OpSource HLSL 600
  274. OpName %type_MyCBuffer "type.MyCBuffer"
  275. OpMemberName %type_MyCBuffer 0 "Data"
  276. OpName %MyCBuffer "MyCBuffer"
  277. OpName %main "main"
  278. OpName %in_var_INDEX "in.var.INDEX"
  279. OpName %out_var_SV_Target "out.var.SV_Target"
  280. OpDecorate %_arr_v4float_uint_2 ArrayStride 16
  281. OpDecorate %_arr__arr_v4float_uint_2_uint_2 ArrayStride 32
  282. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  283. OpDecorate %type_MyCBuffer Block
  284. OpDecorate %in_var_INDEX Flat
  285. OpDecorate %in_var_INDEX Location 0
  286. OpDecorate %out_var_SV_Target Location 0
  287. OpDecorate %MyCBuffer DescriptorSet 0
  288. OpDecorate %MyCBuffer Binding 0
  289. %float = OpTypeFloat 32
  290. %v4float = OpTypeVector %float 4
  291. %uint = OpTypeInt 32 0
  292. %uint_2 = OpConstant %uint 2
  293. %_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
  294. %_arr__arr_v4float_uint_2_uint_2 = OpTypeArray %_arr_v4float_uint_2 %uint_2
  295. %type_MyCBuffer = OpTypeStruct %_arr__arr_v4float_uint_2_uint_2
  296. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  297. %void = OpTypeVoid
  298. %14 = OpTypeFunction %void
  299. %int = OpTypeInt 32 1
  300. %_ptr_Input_int = OpTypePointer Input %int
  301. %_ptr_Output_v4float = OpTypePointer Output %v4float
  302. %_arr_v4float_uint_2_0 = OpTypeArray %v4float %uint_2
  303. %_arr__arr_v4float_uint_2_0_uint_2 = OpTypeArray %_arr_v4float_uint_2_0 %uint_2
  304. %_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 = OpTypePointer Function %_arr__arr_v4float_uint_2_0_uint_2
  305. %int_0 = OpConstant %int 0
  306. %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_v4float_uint_2_uint_2
  307. %_ptr_Function__arr_v4float_uint_2_0 = OpTypePointer Function %_arr_v4float_uint_2_0
  308. %_ptr_Function_v4float = OpTypePointer Function %v4float
  309. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  310. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  311. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  312. ; CHECK: OpFunction
  313. ; CHECK: OpLabel
  314. ; CHECK: OpVariable
  315. ; CHECK: OpVariable
  316. ; CHECK: OpAccessChain
  317. ; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
  318. %main = OpFunction %void None %14
  319. %25 = OpLabel
  320. %26 = OpVariable %_ptr_Function__arr_v4float_uint_2_0 Function
  321. %27 = OpVariable %_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 Function
  322. %28 = OpLoad %int %in_var_INDEX
  323. %29 = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
  324. %30 = OpLoad %_arr__arr_v4float_uint_2_uint_2 %29
  325. %32 = OpCompositeExtract %v4float %30 0 0
  326. %33 = OpCompositeExtract %v4float %30 0 1
  327. %34 = OpCompositeConstruct %_arr_v4float_uint_2_0 %32 %33
  328. %36 = OpCompositeExtract %v4float %30 1 0
  329. %37 = OpCompositeExtract %v4float %30 1 1
  330. %38 = OpCompositeConstruct %_arr_v4float_uint_2_0 %36 %37
  331. %39 = OpCompositeConstruct %_arr__arr_v4float_uint_2_0_uint_2 %34 %38
  332. ; CHECK: OpStore
  333. OpStore %27 %39
  334. %40 = OpAccessChain %_ptr_Function__arr_v4float_uint_2_0 %27 %28
  335. %42 = OpAccessChain %_ptr_Function_v4float %40 %28
  336. %43 = OpLoad %v4float %42
  337. ; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_2 [[new_address]] %28
  338. ; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[ac1]] %28
  339. ; CHECK: [[load:%\w+]] = OpLoad %v4float [[ac2]]
  340. ; CHECK: OpStore %out_var_SV_Target [[load]]
  341. OpStore %out_var_SV_Target %43
  342. OpReturn
  343. OpFunctionEnd
  344. )";
  345. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  346. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  347. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  348. SinglePassRunAndMatch<CopyPropagateArrays>(text, false);
  349. }
  350. // Test decomposing an object when we need to "rewrite" a store.
  351. TEST_F(CopyPropArrayPassTest, DecomposeObjectForArrayStore) {
  352. const std::string text =
  353. R"( OpCapability Shader
  354. OpMemoryModel Logical GLSL450
  355. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  356. OpExecutionMode %main OriginUpperLeft
  357. OpSource HLSL 600
  358. OpName %type_MyCBuffer "type.MyCBuffer"
  359. OpMemberName %type_MyCBuffer 0 "Data"
  360. OpName %MyCBuffer "MyCBuffer"
  361. OpName %main "main"
  362. OpName %in_var_INDEX "in.var.INDEX"
  363. OpName %out_var_SV_Target "out.var.SV_Target"
  364. OpDecorate %_arr_v4float_uint_2 ArrayStride 16
  365. OpDecorate %_arr__arr_v4float_uint_2_uint_2 ArrayStride 32
  366. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  367. OpDecorate %type_MyCBuffer Block
  368. OpDecorate %in_var_INDEX Flat
  369. OpDecorate %in_var_INDEX Location 0
  370. OpDecorate %out_var_SV_Target Location 0
  371. OpDecorate %MyCBuffer DescriptorSet 0
  372. OpDecorate %MyCBuffer Binding 0
  373. %float = OpTypeFloat 32
  374. %v4float = OpTypeVector %float 4
  375. %uint = OpTypeInt 32 0
  376. %uint_2 = OpConstant %uint 2
  377. %_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
  378. %_arr__arr_v4float_uint_2_uint_2 = OpTypeArray %_arr_v4float_uint_2 %uint_2
  379. %type_MyCBuffer = OpTypeStruct %_arr__arr_v4float_uint_2_uint_2
  380. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  381. %void = OpTypeVoid
  382. %14 = OpTypeFunction %void
  383. %int = OpTypeInt 32 1
  384. %_ptr_Input_int = OpTypePointer Input %int
  385. %_ptr_Output_v4float = OpTypePointer Output %v4float
  386. %_arr_v4float_uint_2_0 = OpTypeArray %v4float %uint_2
  387. %_arr__arr_v4float_uint_2_0_uint_2 = OpTypeArray %_arr_v4float_uint_2_0 %uint_2
  388. %_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 = OpTypePointer Function %_arr__arr_v4float_uint_2_0_uint_2
  389. %int_0 = OpConstant %int 0
  390. %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_v4float_uint_2_uint_2
  391. %_ptr_Function__arr_v4float_uint_2_0 = OpTypePointer Function %_arr_v4float_uint_2_0
  392. %_ptr_Function_v4float = OpTypePointer Function %v4float
  393. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  394. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  395. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  396. %main = OpFunction %void None %14
  397. %25 = OpLabel
  398. %26 = OpVariable %_ptr_Function__arr_v4float_uint_2_0 Function
  399. %27 = OpVariable %_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 Function
  400. %28 = OpLoad %int %in_var_INDEX
  401. %29 = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
  402. %30 = OpLoad %_arr__arr_v4float_uint_2_uint_2 %29
  403. %31 = OpCompositeExtract %_arr_v4float_uint_2 %30 0
  404. %32 = OpCompositeExtract %v4float %31 0
  405. %33 = OpCompositeExtract %v4float %31 1
  406. %34 = OpCompositeConstruct %_arr_v4float_uint_2_0 %32 %33
  407. %35 = OpCompositeExtract %_arr_v4float_uint_2 %30 1
  408. %36 = OpCompositeExtract %v4float %35 0
  409. %37 = OpCompositeExtract %v4float %35 1
  410. %38 = OpCompositeConstruct %_arr_v4float_uint_2_0 %36 %37
  411. %39 = OpCompositeConstruct %_arr__arr_v4float_uint_2_0_uint_2 %34 %38
  412. OpStore %27 %39
  413. ; CHECK: [[access_chain:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_2
  414. %40 = OpAccessChain %_ptr_Function__arr_v4float_uint_2_0 %27 %28
  415. ; CHECK: [[load:%\w+]] = OpLoad %_arr_v4float_uint_2 [[access_chain]]
  416. %41 = OpLoad %_arr_v4float_uint_2_0 %40
  417. ; CHECK: [[extract1:%\w+]] = OpCompositeExtract %v4float [[load]] 0
  418. ; CHECK: [[extract2:%\w+]] = OpCompositeExtract %v4float [[load]] 1
  419. ; CHECK: [[construct:%\w+]] = OpCompositeConstruct %_arr_v4float_uint_2_0 [[extract1]] [[extract2]]
  420. ; CHECK: OpStore %26 [[construct]]
  421. OpStore %26 %41
  422. %42 = OpAccessChain %_ptr_Function_v4float %26 %28
  423. %43 = OpLoad %v4float %42
  424. OpStore %out_var_SV_Target %43
  425. OpReturn
  426. OpFunctionEnd
  427. )";
  428. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  429. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  430. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  431. SinglePassRunAndMatch<CopyPropagateArrays>(text, false);
  432. }
  433. // Test decomposing an object when we need to "rewrite" a store.
  434. TEST_F(CopyPropArrayPassTest, DecomposeObjectForStructStore) {
  435. const std::string text =
  436. R"( OpCapability Shader
  437. OpMemoryModel Logical GLSL450
  438. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  439. OpExecutionMode %main OriginUpperLeft
  440. OpSource HLSL 600
  441. OpName %type_MyCBuffer "type.MyCBuffer"
  442. OpMemberName %type_MyCBuffer 0 "Data"
  443. OpName %MyCBuffer "MyCBuffer"
  444. OpName %main "main"
  445. OpName %in_var_INDEX "in.var.INDEX"
  446. OpName %out_var_SV_Target "out.var.SV_Target"
  447. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  448. OpDecorate %type_MyCBuffer Block
  449. OpDecorate %in_var_INDEX Flat
  450. OpDecorate %in_var_INDEX Location 0
  451. OpDecorate %out_var_SV_Target Location 0
  452. OpDecorate %MyCBuffer DescriptorSet 0
  453. OpDecorate %MyCBuffer Binding 0
  454. ; CHECK: OpDecorate [[decorated_type:%\w+]] GLSLPacked
  455. OpDecorate %struct GLSLPacked
  456. %float = OpTypeFloat 32
  457. %v4float = OpTypeVector %float 4
  458. %uint = OpTypeInt 32 0
  459. %uint_2 = OpConstant %uint 2
  460. ; CHECK: [[decorated_type]] = OpTypeStruct
  461. %struct = OpTypeStruct %float %uint
  462. %_arr_struct_uint_2 = OpTypeArray %struct %uint_2
  463. %type_MyCBuffer = OpTypeStruct %_arr_struct_uint_2
  464. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  465. %void = OpTypeVoid
  466. %14 = OpTypeFunction %void
  467. %int = OpTypeInt 32 1
  468. %_ptr_Input_int = OpTypePointer Input %int
  469. %_ptr_Output_v4float = OpTypePointer Output %v4float
  470. ; CHECK: [[struct:%\w+]] = OpTypeStruct %float %uint
  471. %struct_0 = OpTypeStruct %float %uint
  472. %_arr_struct_0_uint_2 = OpTypeArray %struct_0 %uint_2
  473. %_ptr_Function__arr_struct_0_uint_2 = OpTypePointer Function %_arr_struct_0_uint_2
  474. %int_0 = OpConstant %int 0
  475. %_ptr_Uniform__arr_struct_uint_2 = OpTypePointer Uniform %_arr_struct_uint_2
  476. ; CHECK: [[decorated_ptr:%\w+]] = OpTypePointer Uniform [[decorated_type]]
  477. %_ptr_Function_struct_0 = OpTypePointer Function %struct_0
  478. %_ptr_Function_v4float = OpTypePointer Function %v4float
  479. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  480. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  481. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  482. %main = OpFunction %void None %14
  483. %25 = OpLabel
  484. %26 = OpVariable %_ptr_Function_struct_0 Function
  485. %27 = OpVariable %_ptr_Function__arr_struct_0_uint_2 Function
  486. %28 = OpLoad %int %in_var_INDEX
  487. %29 = OpAccessChain %_ptr_Uniform__arr_struct_uint_2 %MyCBuffer %int_0
  488. %30 = OpLoad %_arr_struct_uint_2 %29
  489. %31 = OpCompositeExtract %struct %30 0
  490. %32 = OpCompositeExtract %v4float %31 0
  491. %33 = OpCompositeExtract %v4float %31 1
  492. %34 = OpCompositeConstruct %struct_0 %32 %33
  493. %35 = OpCompositeExtract %struct %30 1
  494. %36 = OpCompositeExtract %float %35 0
  495. %37 = OpCompositeExtract %uint %35 1
  496. %38 = OpCompositeConstruct %struct_0 %36 %37
  497. %39 = OpCompositeConstruct %_arr_struct_0_uint_2 %34 %38
  498. OpStore %27 %39
  499. ; CHECK: [[access_chain:%\w+]] = OpAccessChain [[decorated_ptr]]
  500. %40 = OpAccessChain %_ptr_Function_struct_0 %27 %28
  501. ; CHECK: [[load:%\w+]] = OpLoad [[decorated_type]] [[access_chain]]
  502. %41 = OpLoad %struct_0 %40
  503. ; CHECK: [[extract1:%\w+]] = OpCompositeExtract %float [[load]] 0
  504. ; CHECK: [[extract2:%\w+]] = OpCompositeExtract %uint [[load]] 1
  505. ; CHECK: [[construct:%\w+]] = OpCompositeConstruct [[struct]] [[extract1]] [[extract2]]
  506. ; CHECK: OpStore %26 [[construct]]
  507. OpStore %26 %41
  508. %42 = OpAccessChain %_ptr_Function_v4float %26 %28
  509. %43 = OpLoad %v4float %42
  510. OpStore %out_var_SV_Target %43
  511. OpReturn
  512. OpFunctionEnd
  513. )";
  514. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  515. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  516. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  517. SinglePassRunAndMatch<CopyPropagateArrays>(text, false);
  518. }
  519. TEST_F(CopyPropArrayPassTest, CopyViaInserts) {
  520. const std::string before =
  521. R"(
  522. OpCapability Shader
  523. OpMemoryModel Logical GLSL450
  524. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  525. OpExecutionMode %main OriginUpperLeft
  526. OpSource HLSL 600
  527. OpName %type_MyCBuffer "type.MyCBuffer"
  528. OpMemberName %type_MyCBuffer 0 "Data"
  529. OpName %MyCBuffer "MyCBuffer"
  530. OpName %main "main"
  531. OpName %in_var_INDEX "in.var.INDEX"
  532. OpName %out_var_SV_Target "out.var.SV_Target"
  533. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  534. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  535. OpDecorate %type_MyCBuffer Block
  536. OpDecorate %in_var_INDEX Flat
  537. OpDecorate %in_var_INDEX Location 0
  538. OpDecorate %out_var_SV_Target Location 0
  539. OpDecorate %MyCBuffer DescriptorSet 0
  540. OpDecorate %MyCBuffer Binding 0
  541. %float = OpTypeFloat 32
  542. %v4float = OpTypeVector %float 4
  543. %uint = OpTypeInt 32 0
  544. %uint_8 = OpConstant %uint 8
  545. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  546. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  547. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  548. %void = OpTypeVoid
  549. %13 = OpTypeFunction %void
  550. %int = OpTypeInt 32 1
  551. %_ptr_Input_int = OpTypePointer Input %int
  552. %_ptr_Output_v4float = OpTypePointer Output %v4float
  553. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  554. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  555. %int_0 = OpConstant %int 0
  556. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  557. %_ptr_Function_v4float = OpTypePointer Function %v4float
  558. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  559. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  560. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  561. ; CHECK: OpFunction
  562. ; CHECK: OpLabel
  563. ; CHECK: OpVariable
  564. ; CHECK: OpAccessChain
  565. ; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  566. ; CHECK: [[element_ptr:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[new_address]] %24
  567. ; CHECK: [[load:%\w+]] = OpLoad %v4float [[element_ptr]]
  568. ; CHECK: OpStore %out_var_SV_Target [[load]]
  569. %main = OpFunction %void None %13
  570. %22 = OpLabel
  571. %23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  572. %undef = OpUndef %_arr_v4float_uint_8_0
  573. %24 = OpLoad %int %in_var_INDEX
  574. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  575. %26 = OpLoad %_arr_v4float_uint_8 %25
  576. %27 = OpCompositeExtract %v4float %26 0
  577. %i0 = OpCompositeInsert %_arr_v4float_uint_8_0 %27 %undef 0
  578. %28 = OpCompositeExtract %v4float %26 1
  579. %i1 = OpCompositeInsert %_arr_v4float_uint_8_0 %28 %i0 1
  580. %29 = OpCompositeExtract %v4float %26 2
  581. %i2 = OpCompositeInsert %_arr_v4float_uint_8_0 %29 %i1 2
  582. %30 = OpCompositeExtract %v4float %26 3
  583. %i3 = OpCompositeInsert %_arr_v4float_uint_8_0 %30 %i2 3
  584. %31 = OpCompositeExtract %v4float %26 4
  585. %i4 = OpCompositeInsert %_arr_v4float_uint_8_0 %31 %i3 4
  586. %32 = OpCompositeExtract %v4float %26 5
  587. %i5 = OpCompositeInsert %_arr_v4float_uint_8_0 %32 %i4 5
  588. %33 = OpCompositeExtract %v4float %26 6
  589. %i6 = OpCompositeInsert %_arr_v4float_uint_8_0 %33 %i5 6
  590. %34 = OpCompositeExtract %v4float %26 7
  591. %i7 = OpCompositeInsert %_arr_v4float_uint_8_0 %34 %i6 7
  592. OpStore %23 %i7
  593. %36 = OpAccessChain %_ptr_Function_v4float %23 %24
  594. %37 = OpLoad %v4float %36
  595. OpStore %out_var_SV_Target %37
  596. OpReturn
  597. OpFunctionEnd
  598. )";
  599. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  600. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  601. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  602. SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
  603. }
  604. TEST_F(CopyPropArrayPassTest, IsomorphicTypes1) {
  605. const std::string before =
  606. R"(
  607. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  608. ; CHECK: [[s1:%\w+]] = OpTypeStruct [[int]]
  609. ; CHECK: [[s2:%\w+]] = OpTypeStruct [[s1]]
  610. ; CHECK: [[a1:%\w+]] = OpTypeArray [[s2]]
  611. ; CHECK: [[s3:%\w+]] = OpTypeStruct [[a1]]
  612. ; CHECK: [[p_s3:%\w+]] = OpTypePointer Uniform [[s3]]
  613. ; CHECK: [[global_var:%\w+]] = OpVariable [[p_s3]] Uniform
  614. ; CHECK: [[p_a1:%\w+]] = OpTypePointer Uniform [[a1]]
  615. ; CHECK: [[p_s2:%\w+]] = OpTypePointer Uniform [[s2]]
  616. ; CHECK: [[ac1:%\w+]] = OpAccessChain [[p_a1]] [[global_var]] %uint_0
  617. ; CHECK: [[ac2:%\w+]] = OpAccessChain [[p_s2]] [[ac1]] %uint_0
  618. ; CHECK: [[ld:%\w+]] = OpLoad [[s2]] [[ac2]]
  619. ; CHECK: [[ex:%\w+]] = OpCompositeExtract [[s1]] [[ld]]
  620. OpCapability Shader
  621. %1 = OpExtInstImport "GLSL.std.450"
  622. OpMemoryModel Logical GLSL450
  623. OpEntryPoint Fragment %2 "PS_main"
  624. OpExecutionMode %2 OriginUpperLeft
  625. OpSource HLSL 600
  626. OpDecorate %3 DescriptorSet 0
  627. OpDecorate %3 Binding 101
  628. %uint = OpTypeInt 32 0
  629. %uint_1 = OpConstant %uint 1
  630. %s1 = OpTypeStruct %uint
  631. %s2 = OpTypeStruct %s1
  632. %a1 = OpTypeArray %s2 %uint_1
  633. %s3 = OpTypeStruct %a1
  634. %s1_1 = OpTypeStruct %uint
  635. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  636. %void = OpTypeVoid
  637. %13 = OpTypeFunction %void
  638. %uint_0 = OpConstant %uint 0
  639. %s1_0 = OpTypeStruct %uint
  640. %s2_0 = OpTypeStruct %s1_0
  641. %a1_0 = OpTypeArray %s2_0 %uint_1
  642. %s3_0 = OpTypeStruct %a1_0
  643. %p_s3 = OpTypePointer Uniform %s3
  644. %p_s3_0 = OpTypePointer Function %s3_0
  645. %3 = OpVariable %p_s3 Uniform
  646. %p_a1_0 = OpTypePointer Function %a1_0
  647. %p_s2_0 = OpTypePointer Function %s2_0
  648. %2 = OpFunction %void None %13
  649. %20 = OpLabel
  650. %21 = OpVariable %p_a1_0 Function
  651. %22 = OpLoad %s3 %3
  652. %23 = OpCompositeExtract %a1 %22 0
  653. %24 = OpCompositeExtract %s2 %23 0
  654. %25 = OpCompositeExtract %s1 %24 0
  655. %26 = OpCompositeExtract %uint %25 0
  656. %27 = OpCompositeConstruct %s1_0 %26
  657. %32 = OpCompositeConstruct %s2_0 %27
  658. %28 = OpCompositeConstruct %a1_0 %32
  659. OpStore %21 %28
  660. %29 = OpAccessChain %p_s2_0 %21 %uint_0
  661. %30 = OpLoad %s2 %29
  662. %31 = OpCompositeExtract %s1 %30 0
  663. OpReturn
  664. OpFunctionEnd
  665. )";
  666. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  667. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  668. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  669. SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
  670. }
  671. TEST_F(CopyPropArrayPassTest, IsomorphicTypes2) {
  672. const std::string before =
  673. R"(
  674. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  675. ; CHECK: [[s1:%\w+]] = OpTypeStruct [[int]]
  676. ; CHECK: [[s2:%\w+]] = OpTypeStruct [[s1]]
  677. ; CHECK: [[a1:%\w+]] = OpTypeArray [[s2]]
  678. ; CHECK: [[s3:%\w+]] = OpTypeStruct [[a1]]
  679. ; CHECK: [[p_s3:%\w+]] = OpTypePointer Uniform [[s3]]
  680. ; CHECK: [[global_var:%\w+]] = OpVariable [[p_s3]] Uniform
  681. ; CHECK: [[p_s2:%\w+]] = OpTypePointer Uniform [[s2]]
  682. ; CHECK: [[p_s1:%\w+]] = OpTypePointer Uniform [[s1]]
  683. ; CHECK: [[ac1:%\w+]] = OpAccessChain [[p_s2]] [[global_var]] %uint_0 %uint_0
  684. ; CHECK: [[ac2:%\w+]] = OpAccessChain [[p_s1]] [[ac1]] %uint_0
  685. ; CHECK: [[ld:%\w+]] = OpLoad [[s1]] [[ac2]]
  686. ; CHECK: [[ex:%\w+]] = OpCompositeExtract [[int]] [[ld]]
  687. OpCapability Shader
  688. %1 = OpExtInstImport "GLSL.std.450"
  689. OpMemoryModel Logical GLSL450
  690. OpEntryPoint Fragment %2 "PS_main"
  691. OpExecutionMode %2 OriginUpperLeft
  692. OpSource HLSL 600
  693. OpDecorate %3 DescriptorSet 0
  694. OpDecorate %3 Binding 101
  695. %uint = OpTypeInt 32 0
  696. %uint_1 = OpConstant %uint 1
  697. %_struct_6 = OpTypeStruct %uint
  698. %_struct_7 = OpTypeStruct %_struct_6
  699. %_arr__struct_7_uint_1 = OpTypeArray %_struct_7 %uint_1
  700. %_struct_9 = OpTypeStruct %_arr__struct_7_uint_1
  701. %_struct_10 = OpTypeStruct %uint
  702. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  703. %void = OpTypeVoid
  704. %13 = OpTypeFunction %void
  705. %uint_0 = OpConstant %uint 0
  706. %_struct_15 = OpTypeStruct %uint
  707. %_arr__struct_15_uint_1 = OpTypeArray %_struct_15 %uint_1
  708. %_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
  709. %_ptr_Function__struct_15 = OpTypePointer Function %_struct_15
  710. %3 = OpVariable %_ptr_Uniform__struct_9 Uniform
  711. %_ptr_Function__arr__struct_15_uint_1 = OpTypePointer Function %_arr__struct_15_uint_1
  712. %2 = OpFunction %void None %13
  713. %20 = OpLabel
  714. %21 = OpVariable %_ptr_Function__arr__struct_15_uint_1 Function
  715. %22 = OpLoad %_struct_9 %3
  716. %23 = OpCompositeExtract %_arr__struct_7_uint_1 %22 0
  717. %24 = OpCompositeExtract %_struct_7 %23 0
  718. %25 = OpCompositeExtract %_struct_6 %24 0
  719. %26 = OpCompositeExtract %uint %25 0
  720. %27 = OpCompositeConstruct %_struct_15 %26
  721. %28 = OpCompositeConstruct %_arr__struct_15_uint_1 %27
  722. OpStore %21 %28
  723. %29 = OpAccessChain %_ptr_Function__struct_15 %21 %uint_0
  724. %30 = OpLoad %_struct_15 %29
  725. %31 = OpCompositeExtract %uint %30 0
  726. OpReturn
  727. OpFunctionEnd
  728. )";
  729. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  730. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  731. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  732. SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
  733. }
  734. TEST_F(CopyPropArrayPassTest, IsomorphicTypes3) {
  735. const std::string before =
  736. R"(
  737. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  738. ; CHECK: [[s1:%\w+]] = OpTypeStruct [[int]]
  739. ; CHECK: [[s2:%\w+]] = OpTypeStruct [[s1]]
  740. ; CHECK: [[a1:%\w+]] = OpTypeArray [[s2]]
  741. ; CHECK: [[s3:%\w+]] = OpTypeStruct [[a1]]
  742. ; CHECK: [[s1_1:%\w+]] = OpTypeStruct [[int]]
  743. ; CHECK: [[p_s3:%\w+]] = OpTypePointer Uniform [[s3]]
  744. ; CHECK: [[p_s1_1:%\w+]] = OpTypePointer Function [[s1_1]]
  745. ; CHECK: [[global_var:%\w+]] = OpVariable [[p_s3]] Uniform
  746. ; CHECK: [[p_s2:%\w+]] = OpTypePointer Uniform [[s2]]
  747. ; CHECK: [[p_s1:%\w+]] = OpTypePointer Uniform [[s1]]
  748. ; CHECK: [[var:%\w+]] = OpVariable [[p_s1_1]] Function
  749. ; CHECK: [[ac1:%\w+]] = OpAccessChain [[p_s2]] [[global_var]] %uint_0 %uint_0
  750. ; CHECK: [[ac2:%\w+]] = OpAccessChain [[p_s1]] [[ac1]] %uint_0
  751. ; CHECK: [[ld:%\w+]] = OpLoad [[s1]] [[ac2]]
  752. ; CHECK: [[ex:%\w+]] = OpCompositeExtract [[int]] [[ld]]
  753. ; CHECK: [[copy:%\w+]] = OpCompositeConstruct [[s1_1]] [[ex]]
  754. ; CHECK: OpStore [[var]] [[copy]]
  755. OpCapability Shader
  756. %1 = OpExtInstImport "GLSL.std.450"
  757. OpMemoryModel Logical GLSL450
  758. OpEntryPoint Fragment %2 "PS_main"
  759. OpExecutionMode %2 OriginUpperLeft
  760. OpSource HLSL 600
  761. OpDecorate %3 DescriptorSet 0
  762. OpDecorate %3 Binding 101
  763. %uint = OpTypeInt 32 0
  764. %uint_1 = OpConstant %uint 1
  765. %_struct_6 = OpTypeStruct %uint
  766. %_struct_7 = OpTypeStruct %_struct_6
  767. %_arr__struct_7_uint_1 = OpTypeArray %_struct_7 %uint_1
  768. %_struct_9 = OpTypeStruct %_arr__struct_7_uint_1
  769. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  770. %void = OpTypeVoid
  771. %13 = OpTypeFunction %void
  772. %uint_0 = OpConstant %uint 0
  773. %_struct_15 = OpTypeStruct %uint
  774. %_struct_10 = OpTypeStruct %uint
  775. %_arr__struct_15_uint_1 = OpTypeArray %_struct_15 %uint_1
  776. %_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
  777. %_ptr_Function__struct_15 = OpTypePointer Function %_struct_15
  778. %3 = OpVariable %_ptr_Uniform__struct_9 Uniform
  779. %_ptr_Function__arr__struct_15_uint_1 = OpTypePointer Function %_arr__struct_15_uint_1
  780. %2 = OpFunction %void None %13
  781. %20 = OpLabel
  782. %21 = OpVariable %_ptr_Function__arr__struct_15_uint_1 Function
  783. %var = OpVariable %_ptr_Function__struct_15 Function
  784. %22 = OpLoad %_struct_9 %3
  785. %23 = OpCompositeExtract %_arr__struct_7_uint_1 %22 0
  786. %24 = OpCompositeExtract %_struct_7 %23 0
  787. %25 = OpCompositeExtract %_struct_6 %24 0
  788. %26 = OpCompositeExtract %uint %25 0
  789. %27 = OpCompositeConstruct %_struct_15 %26
  790. %28 = OpCompositeConstruct %_arr__struct_15_uint_1 %27
  791. OpStore %21 %28
  792. %29 = OpAccessChain %_ptr_Function__struct_15 %21 %uint_0
  793. %30 = OpLoad %_struct_15 %29
  794. OpStore %var %30
  795. OpReturn
  796. OpFunctionEnd
  797. )";
  798. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  799. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  800. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  801. SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
  802. }
  803. TEST_F(CopyPropArrayPassTest, BadMergingTwoObjects) {
  804. // The second element in the |OpCompositeConstruct| is from a different
  805. // object.
  806. const std::string text =
  807. R"(OpCapability Shader
  808. OpMemoryModel Logical GLSL450
  809. OpEntryPoint Fragment %main "main"
  810. OpExecutionMode %main OriginUpperLeft
  811. OpName %type_ConstBuf "type.ConstBuf"
  812. OpMemberName %type_ConstBuf 0 "TexSizeU"
  813. OpMemberName %type_ConstBuf 1 "TexSizeV"
  814. OpName %ConstBuf "ConstBuf"
  815. OpName %main "main"
  816. OpMemberDecorate %type_ConstBuf 0 Offset 0
  817. OpMemberDecorate %type_ConstBuf 1 Offset 8
  818. OpDecorate %type_ConstBuf Block
  819. OpDecorate %ConstBuf DescriptorSet 0
  820. OpDecorate %ConstBuf Binding 2
  821. %float = OpTypeFloat 32
  822. %v2float = OpTypeVector %float 2
  823. %type_ConstBuf = OpTypeStruct %v2float %v2float
  824. %_ptr_Uniform_type_ConstBuf = OpTypePointer Uniform %type_ConstBuf
  825. %void = OpTypeVoid
  826. %9 = OpTypeFunction %void
  827. %uint = OpTypeInt 32 0
  828. %int_0 = OpConstant %uint 0
  829. %uint_2 = OpConstant %uint 2
  830. %_arr_v2float_uint_2 = OpTypeArray %v2float %uint_2
  831. %_ptr_Function__arr_v2float_uint_2 = OpTypePointer Function %_arr_v2float_uint_2
  832. %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
  833. %ConstBuf = OpVariable %_ptr_Uniform_type_ConstBuf Uniform
  834. %main = OpFunction %void None %9
  835. %24 = OpLabel
  836. %25 = OpVariable %_ptr_Function__arr_v2float_uint_2 Function
  837. %27 = OpAccessChain %_ptr_Uniform_v2float %ConstBuf %int_0
  838. %28 = OpLoad %v2float %27
  839. %29 = OpAccessChain %_ptr_Uniform_v2float %ConstBuf %int_0
  840. %30 = OpLoad %v2float %29
  841. %31 = OpFNegate %v2float %30
  842. %37 = OpCompositeConstruct %_arr_v2float_uint_2 %28 %31
  843. OpStore %25 %37
  844. OpReturn
  845. OpFunctionEnd
  846. )";
  847. auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
  848. text, /* skip_nop = */ true, /* do_validation = */ false);
  849. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  850. }
  851. TEST_F(CopyPropArrayPassTest, SecondElementNotContained) {
  852. // The second element in the |OpCompositeConstruct| is not a memory object.
  853. // Make sure no change happends.
  854. const std::string text =
  855. R"(OpCapability Shader
  856. OpMemoryModel Logical GLSL450
  857. OpEntryPoint Fragment %main "main"
  858. OpExecutionMode %main OriginUpperLeft
  859. OpName %type_ConstBuf "type.ConstBuf"
  860. OpMemberName %type_ConstBuf 0 "TexSizeU"
  861. OpMemberName %type_ConstBuf 1 "TexSizeV"
  862. OpName %ConstBuf "ConstBuf"
  863. OpName %main "main"
  864. OpMemberDecorate %type_ConstBuf 0 Offset 0
  865. OpMemberDecorate %type_ConstBuf 1 Offset 8
  866. OpDecorate %type_ConstBuf Block
  867. OpDecorate %ConstBuf DescriptorSet 0
  868. OpDecorate %ConstBuf Binding 2
  869. OpDecorate %ConstBuf2 DescriptorSet 1
  870. OpDecorate %ConstBuf2 Binding 2
  871. %float = OpTypeFloat 32
  872. %v2float = OpTypeVector %float 2
  873. %type_ConstBuf = OpTypeStruct %v2float %v2float
  874. %_ptr_Uniform_type_ConstBuf = OpTypePointer Uniform %type_ConstBuf
  875. %void = OpTypeVoid
  876. %9 = OpTypeFunction %void
  877. %uint = OpTypeInt 32 0
  878. %int_0 = OpConstant %uint 0
  879. %int_1 = OpConstant %uint 1
  880. %uint_2 = OpConstant %uint 2
  881. %_arr_v2float_uint_2 = OpTypeArray %v2float %uint_2
  882. %_ptr_Function__arr_v2float_uint_2 = OpTypePointer Function %_arr_v2float_uint_2
  883. %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
  884. %ConstBuf = OpVariable %_ptr_Uniform_type_ConstBuf Uniform
  885. %ConstBuf2 = OpVariable %_ptr_Uniform_type_ConstBuf Uniform
  886. %main = OpFunction %void None %9
  887. %24 = OpLabel
  888. %25 = OpVariable %_ptr_Function__arr_v2float_uint_2 Function
  889. %27 = OpAccessChain %_ptr_Uniform_v2float %ConstBuf %int_0
  890. %28 = OpLoad %v2float %27
  891. %29 = OpAccessChain %_ptr_Uniform_v2float %ConstBuf2 %int_1
  892. %30 = OpLoad %v2float %29
  893. %37 = OpCompositeConstruct %_arr_v2float_uint_2 %28 %30
  894. OpStore %25 %37
  895. OpReturn
  896. OpFunctionEnd
  897. )";
  898. auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
  899. text, /* skip_nop = */ true, /* do_validation = */ false);
  900. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  901. }
  902. // This test will place a load before the store. We cannot propagate in this
  903. // case.
  904. TEST_F(CopyPropArrayPassTest, LoadBeforeStore) {
  905. const std::string text =
  906. R"(
  907. OpCapability Shader
  908. OpMemoryModel Logical GLSL450
  909. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  910. OpExecutionMode %main OriginUpperLeft
  911. OpSource HLSL 600
  912. OpName %type_MyCBuffer "type.MyCBuffer"
  913. OpMemberName %type_MyCBuffer 0 "Data"
  914. OpName %MyCBuffer "MyCBuffer"
  915. OpName %main "main"
  916. OpName %in_var_INDEX "in.var.INDEX"
  917. OpName %out_var_SV_Target "out.var.SV_Target"
  918. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  919. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  920. OpDecorate %type_MyCBuffer Block
  921. OpDecorate %in_var_INDEX Flat
  922. OpDecorate %in_var_INDEX Location 0
  923. OpDecorate %out_var_SV_Target Location 0
  924. OpDecorate %MyCBuffer DescriptorSet 0
  925. OpDecorate %MyCBuffer Binding 0
  926. %float = OpTypeFloat 32
  927. %v4float = OpTypeVector %float 4
  928. %uint = OpTypeInt 32 0
  929. %uint_8 = OpConstant %uint 8
  930. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  931. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  932. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  933. %void = OpTypeVoid
  934. %13 = OpTypeFunction %void
  935. %int = OpTypeInt 32 1
  936. %_ptr_Input_int = OpTypePointer Input %int
  937. %_ptr_Output_v4float = OpTypePointer Output %v4float
  938. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  939. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  940. %int_0 = OpConstant %int 0
  941. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  942. %_ptr_Function_v4float = OpTypePointer Function %v4float
  943. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  944. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  945. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  946. %main = OpFunction %void None %13
  947. %22 = OpLabel
  948. %23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  949. %38 = OpAccessChain %_ptr_Function_v4float %23 %24
  950. %39 = OpLoad %v4float %36
  951. %24 = OpLoad %int %in_var_INDEX
  952. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  953. %26 = OpLoad %_arr_v4float_uint_8 %25
  954. %27 = OpCompositeExtract %v4float %26 0
  955. %28 = OpCompositeExtract %v4float %26 1
  956. %29 = OpCompositeExtract %v4float %26 2
  957. %30 = OpCompositeExtract %v4float %26 3
  958. %31 = OpCompositeExtract %v4float %26 4
  959. %32 = OpCompositeExtract %v4float %26 5
  960. %33 = OpCompositeExtract %v4float %26 6
  961. %34 = OpCompositeExtract %v4float %26 7
  962. %35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
  963. OpStore %23 %35
  964. %36 = OpAccessChain %_ptr_Function_v4float %23 %24
  965. %37 = OpLoad %v4float %36
  966. OpStore %out_var_SV_Target %37
  967. OpReturn
  968. OpFunctionEnd
  969. )";
  970. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  971. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  972. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  973. auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
  974. text, /* skip_nop = */ true, /* do_validation = */ false);
  975. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  976. }
  977. // This test will place a load where it is not dominated by the store. We
  978. // cannot propagate in this case.
  979. TEST_F(CopyPropArrayPassTest, LoadNotDominated) {
  980. const std::string text =
  981. R"(
  982. OpCapability Shader
  983. OpMemoryModel Logical GLSL450
  984. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  985. OpExecutionMode %main OriginUpperLeft
  986. OpSource HLSL 600
  987. OpName %type_MyCBuffer "type.MyCBuffer"
  988. OpMemberName %type_MyCBuffer 0 "Data"
  989. OpName %MyCBuffer "MyCBuffer"
  990. OpName %main "main"
  991. OpName %in_var_INDEX "in.var.INDEX"
  992. OpName %out_var_SV_Target "out.var.SV_Target"
  993. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  994. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  995. OpDecorate %type_MyCBuffer Block
  996. OpDecorate %in_var_INDEX Flat
  997. OpDecorate %in_var_INDEX Location 0
  998. OpDecorate %out_var_SV_Target Location 0
  999. OpDecorate %MyCBuffer DescriptorSet 0
  1000. OpDecorate %MyCBuffer Binding 0
  1001. %bool = OpTypeBool
  1002. %true = OpConstantTrue %bool
  1003. %float = OpTypeFloat 32
  1004. %v4float = OpTypeVector %float 4
  1005. %uint = OpTypeInt 32 0
  1006. %uint_8 = OpConstant %uint 8
  1007. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  1008. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  1009. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  1010. %void = OpTypeVoid
  1011. %13 = OpTypeFunction %void
  1012. %int = OpTypeInt 32 1
  1013. %_ptr_Input_int = OpTypePointer Input %int
  1014. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1015. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  1016. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  1017. %int_0 = OpConstant %int 0
  1018. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  1019. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1020. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  1021. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  1022. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  1023. %main = OpFunction %void None %13
  1024. %22 = OpLabel
  1025. %23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  1026. OpSelectionMerge %merge None
  1027. OpBranchConditional %true %if %else
  1028. %if = OpLabel
  1029. %24 = OpLoad %int %in_var_INDEX
  1030. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  1031. %26 = OpLoad %_arr_v4float_uint_8 %25
  1032. %27 = OpCompositeExtract %v4float %26 0
  1033. %28 = OpCompositeExtract %v4float %26 1
  1034. %29 = OpCompositeExtract %v4float %26 2
  1035. %30 = OpCompositeExtract %v4float %26 3
  1036. %31 = OpCompositeExtract %v4float %26 4
  1037. %32 = OpCompositeExtract %v4float %26 5
  1038. %33 = OpCompositeExtract %v4float %26 6
  1039. %34 = OpCompositeExtract %v4float %26 7
  1040. %35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
  1041. OpStore %23 %35
  1042. %38 = OpAccessChain %_ptr_Function_v4float %23 %24
  1043. %39 = OpLoad %v4float %36
  1044. OpBranch %merge
  1045. %else = OpLabel
  1046. %36 = OpAccessChain %_ptr_Function_v4float %23 %24
  1047. %37 = OpLoad %v4float %36
  1048. OpBranch %merge
  1049. %merge = OpLabel
  1050. %phi = OpPhi %out_var_SV_Target %39 %if %37 %else
  1051. OpStore %out_var_SV_Target %phi
  1052. OpReturn
  1053. OpFunctionEnd
  1054. )";
  1055. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1056. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1057. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1058. auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
  1059. text, /* skip_nop = */ true, /* do_validation = */ false);
  1060. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  1061. }
  1062. // This test has a partial store to the variable. We cannot propagate in this
  1063. // case.
  1064. TEST_F(CopyPropArrayPassTest, PartialStore) {
  1065. const std::string text =
  1066. R"(
  1067. OpCapability Shader
  1068. OpMemoryModel Logical GLSL450
  1069. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  1070. OpExecutionMode %main OriginUpperLeft
  1071. OpSource HLSL 600
  1072. OpName %type_MyCBuffer "type.MyCBuffer"
  1073. OpMemberName %type_MyCBuffer 0 "Data"
  1074. OpName %MyCBuffer "MyCBuffer"
  1075. OpName %main "main"
  1076. OpName %in_var_INDEX "in.var.INDEX"
  1077. OpName %out_var_SV_Target "out.var.SV_Target"
  1078. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  1079. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  1080. OpDecorate %type_MyCBuffer Block
  1081. OpDecorate %in_var_INDEX Flat
  1082. OpDecorate %in_var_INDEX Location 0
  1083. OpDecorate %out_var_SV_Target Location 0
  1084. OpDecorate %MyCBuffer DescriptorSet 0
  1085. OpDecorate %MyCBuffer Binding 0
  1086. %float = OpTypeFloat 32
  1087. %v4float = OpTypeVector %float 4
  1088. %uint = OpTypeInt 32 0
  1089. %uint_8 = OpConstant %uint 8
  1090. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  1091. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  1092. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  1093. %void = OpTypeVoid
  1094. %13 = OpTypeFunction %void
  1095. %int = OpTypeInt 32 1
  1096. %_ptr_Input_int = OpTypePointer Input %int
  1097. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1098. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  1099. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  1100. %int_0 = OpConstant %int 0
  1101. %f0 = OpConstant %float 0
  1102. %v4const = OpConstantComposite %v4float %f0 %f0 %f0 %f0
  1103. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  1104. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1105. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  1106. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  1107. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  1108. %main = OpFunction %void None %13
  1109. %22 = OpLabel
  1110. %23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  1111. %24 = OpLoad %int %in_var_INDEX
  1112. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  1113. %26 = OpLoad %_arr_v4float_uint_8 %25
  1114. %27 = OpCompositeExtract %v4float %26 0
  1115. %28 = OpCompositeExtract %v4float %26 1
  1116. %29 = OpCompositeExtract %v4float %26 2
  1117. %30 = OpCompositeExtract %v4float %26 3
  1118. %31 = OpCompositeExtract %v4float %26 4
  1119. %32 = OpCompositeExtract %v4float %26 5
  1120. %33 = OpCompositeExtract %v4float %26 6
  1121. %34 = OpCompositeExtract %v4float %26 7
  1122. %35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
  1123. OpStore %23 %35
  1124. %36 = OpAccessChain %_ptr_Function_v4float %23 %24
  1125. %37 = OpLoad %v4float %36
  1126. OpStore %36 %v4const
  1127. OpStore %out_var_SV_Target %37
  1128. OpReturn
  1129. OpFunctionEnd
  1130. )";
  1131. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1132. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1133. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1134. auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
  1135. text, /* skip_nop = */ true, /* do_validation = */ false);
  1136. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  1137. }
  1138. // This test does not have a proper copy of an object. We cannot propagate in
  1139. // this case.
  1140. TEST_F(CopyPropArrayPassTest, NotACopy) {
  1141. const std::string text =
  1142. R"(
  1143. OpCapability Shader
  1144. OpMemoryModel Logical GLSL450
  1145. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  1146. OpExecutionMode %main OriginUpperLeft
  1147. OpSource HLSL 600
  1148. OpName %type_MyCBuffer "type.MyCBuffer"
  1149. OpMemberName %type_MyCBuffer 0 "Data"
  1150. OpName %MyCBuffer "MyCBuffer"
  1151. OpName %main "main"
  1152. OpName %in_var_INDEX "in.var.INDEX"
  1153. OpName %out_var_SV_Target "out.var.SV_Target"
  1154. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  1155. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  1156. OpDecorate %type_MyCBuffer Block
  1157. OpDecorate %in_var_INDEX Flat
  1158. OpDecorate %in_var_INDEX Location 0
  1159. OpDecorate %out_var_SV_Target Location 0
  1160. OpDecorate %MyCBuffer DescriptorSet 0
  1161. OpDecorate %MyCBuffer Binding 0
  1162. %float = OpTypeFloat 32
  1163. %v4float = OpTypeVector %float 4
  1164. %uint = OpTypeInt 32 0
  1165. %uint_8 = OpConstant %uint 8
  1166. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  1167. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  1168. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  1169. %void = OpTypeVoid
  1170. %13 = OpTypeFunction %void
  1171. %int = OpTypeInt 32 1
  1172. %_ptr_Input_int = OpTypePointer Input %int
  1173. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1174. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  1175. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  1176. %int_0 = OpConstant %int 0
  1177. %f0 = OpConstant %float 0
  1178. %v4const = OpConstantComposite %v4float %f0 %f0 %f0 %f0
  1179. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  1180. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1181. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  1182. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  1183. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  1184. %main = OpFunction %void None %13
  1185. %22 = OpLabel
  1186. %23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  1187. %24 = OpLoad %int %in_var_INDEX
  1188. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  1189. %26 = OpLoad %_arr_v4float_uint_8 %25
  1190. %27 = OpCompositeExtract %v4float %26 0
  1191. %28 = OpCompositeExtract %v4float %26 0
  1192. %29 = OpCompositeExtract %v4float %26 2
  1193. %30 = OpCompositeExtract %v4float %26 3
  1194. %31 = OpCompositeExtract %v4float %26 4
  1195. %32 = OpCompositeExtract %v4float %26 5
  1196. %33 = OpCompositeExtract %v4float %26 6
  1197. %34 = OpCompositeExtract %v4float %26 7
  1198. %35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
  1199. OpStore %23 %35
  1200. %36 = OpAccessChain %_ptr_Function_v4float %23 %24
  1201. %37 = OpLoad %v4float %36
  1202. OpStore %out_var_SV_Target %37
  1203. OpReturn
  1204. OpFunctionEnd
  1205. )";
  1206. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1207. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1208. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1209. auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
  1210. text, /* skip_nop = */ true, /* do_validation = */ false);
  1211. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  1212. }
  1213. TEST_F(CopyPropArrayPassTest, BadCopyViaInserts1) {
  1214. const std::string text =
  1215. R"(
  1216. OpCapability Shader
  1217. OpMemoryModel Logical GLSL450
  1218. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  1219. OpExecutionMode %main OriginUpperLeft
  1220. OpSource HLSL 600
  1221. OpName %type_MyCBuffer "type.MyCBuffer"
  1222. OpMemberName %type_MyCBuffer 0 "Data"
  1223. OpName %MyCBuffer "MyCBuffer"
  1224. OpName %main "main"
  1225. OpName %in_var_INDEX "in.var.INDEX"
  1226. OpName %out_var_SV_Target "out.var.SV_Target"
  1227. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  1228. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  1229. OpDecorate %type_MyCBuffer Block
  1230. OpDecorate %in_var_INDEX Flat
  1231. OpDecorate %in_var_INDEX Location 0
  1232. OpDecorate %out_var_SV_Target Location 0
  1233. OpDecorate %MyCBuffer DescriptorSet 0
  1234. OpDecorate %MyCBuffer Binding 0
  1235. %float = OpTypeFloat 32
  1236. %v4float = OpTypeVector %float 4
  1237. %uint = OpTypeInt 32 0
  1238. %uint_8 = OpConstant %uint 8
  1239. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  1240. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  1241. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  1242. %void = OpTypeVoid
  1243. %13 = OpTypeFunction %void
  1244. %int = OpTypeInt 32 1
  1245. %_ptr_Input_int = OpTypePointer Input %int
  1246. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1247. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  1248. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  1249. %int_0 = OpConstant %int 0
  1250. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  1251. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1252. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  1253. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  1254. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  1255. %main = OpFunction %void None %13
  1256. %22 = OpLabel
  1257. %23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  1258. %undef = OpUndef %_arr_v4float_uint_8_0
  1259. %24 = OpLoad %int %in_var_INDEX
  1260. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  1261. %26 = OpLoad %_arr_v4float_uint_8 %25
  1262. %27 = OpCompositeExtract %v4float %26 0
  1263. %i0 = OpCompositeInsert %_arr_v4float_uint_8_0 %27 %undef 0
  1264. %28 = OpCompositeExtract %v4float %26 1
  1265. %i1 = OpCompositeInsert %_arr_v4float_uint_8_0 %28 %i0 1
  1266. %29 = OpCompositeExtract %v4float %26 2
  1267. %i2 = OpCompositeInsert %_arr_v4float_uint_8_0 %29 %i1 3
  1268. %30 = OpCompositeExtract %v4float %26 3
  1269. %i3 = OpCompositeInsert %_arr_v4float_uint_8_0 %30 %i2 3
  1270. %31 = OpCompositeExtract %v4float %26 4
  1271. %i4 = OpCompositeInsert %_arr_v4float_uint_8_0 %31 %i3 4
  1272. %32 = OpCompositeExtract %v4float %26 5
  1273. %i5 = OpCompositeInsert %_arr_v4float_uint_8_0 %32 %i4 5
  1274. %33 = OpCompositeExtract %v4float %26 6
  1275. %i6 = OpCompositeInsert %_arr_v4float_uint_8_0 %33 %i5 6
  1276. %34 = OpCompositeExtract %v4float %26 7
  1277. %i7 = OpCompositeInsert %_arr_v4float_uint_8_0 %34 %i6 7
  1278. OpStore %23 %i7
  1279. %36 = OpAccessChain %_ptr_Function_v4float %23 %24
  1280. %37 = OpLoad %v4float %36
  1281. OpStore %out_var_SV_Target %37
  1282. OpReturn
  1283. OpFunctionEnd
  1284. )";
  1285. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1286. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1287. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1288. auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
  1289. text, /* skip_nop = */ true, /* do_validation = */ false);
  1290. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  1291. }
  1292. TEST_F(CopyPropArrayPassTest, BadCopyViaInserts2) {
  1293. const std::string text =
  1294. R"(
  1295. OpCapability Shader
  1296. OpMemoryModel Logical GLSL450
  1297. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  1298. OpExecutionMode %main OriginUpperLeft
  1299. OpSource HLSL 600
  1300. OpName %type_MyCBuffer "type.MyCBuffer"
  1301. OpMemberName %type_MyCBuffer 0 "Data"
  1302. OpName %MyCBuffer "MyCBuffer"
  1303. OpName %main "main"
  1304. OpName %in_var_INDEX "in.var.INDEX"
  1305. OpName %out_var_SV_Target "out.var.SV_Target"
  1306. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  1307. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  1308. OpDecorate %type_MyCBuffer Block
  1309. OpDecorate %in_var_INDEX Flat
  1310. OpDecorate %in_var_INDEX Location 0
  1311. OpDecorate %out_var_SV_Target Location 0
  1312. OpDecorate %MyCBuffer DescriptorSet 0
  1313. OpDecorate %MyCBuffer Binding 0
  1314. %float = OpTypeFloat 32
  1315. %v4float = OpTypeVector %float 4
  1316. %uint = OpTypeInt 32 0
  1317. %uint_8 = OpConstant %uint 8
  1318. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  1319. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  1320. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  1321. %void = OpTypeVoid
  1322. %13 = OpTypeFunction %void
  1323. %int = OpTypeInt 32 1
  1324. %_ptr_Input_int = OpTypePointer Input %int
  1325. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1326. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  1327. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  1328. %int_0 = OpConstant %int 0
  1329. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  1330. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1331. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  1332. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  1333. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  1334. %main = OpFunction %void None %13
  1335. %22 = OpLabel
  1336. %23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  1337. %undef = OpUndef %_arr_v4float_uint_8_0
  1338. %24 = OpLoad %int %in_var_INDEX
  1339. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  1340. %26 = OpLoad %_arr_v4float_uint_8 %25
  1341. %27 = OpCompositeExtract %v4float %26 0
  1342. %i0 = OpCompositeInsert %_arr_v4float_uint_8_0 %27 %undef 0
  1343. %28 = OpCompositeExtract %v4float %26 1
  1344. %i1 = OpCompositeInsert %_arr_v4float_uint_8_0 %28 %i0 1
  1345. %29 = OpCompositeExtract %v4float %26 3
  1346. %i2 = OpCompositeInsert %_arr_v4float_uint_8_0 %29 %i1 2
  1347. %30 = OpCompositeExtract %v4float %26 3
  1348. %i3 = OpCompositeInsert %_arr_v4float_uint_8_0 %30 %i2 3
  1349. %31 = OpCompositeExtract %v4float %26 4
  1350. %i4 = OpCompositeInsert %_arr_v4float_uint_8_0 %31 %i3 4
  1351. %32 = OpCompositeExtract %v4float %26 5
  1352. %i5 = OpCompositeInsert %_arr_v4float_uint_8_0 %32 %i4 5
  1353. %33 = OpCompositeExtract %v4float %26 6
  1354. %i6 = OpCompositeInsert %_arr_v4float_uint_8_0 %33 %i5 6
  1355. %34 = OpCompositeExtract %v4float %26 7
  1356. %i7 = OpCompositeInsert %_arr_v4float_uint_8_0 %34 %i6 7
  1357. OpStore %23 %i7
  1358. %36 = OpAccessChain %_ptr_Function_v4float %23 %24
  1359. %37 = OpLoad %v4float %36
  1360. OpStore %out_var_SV_Target %37
  1361. OpReturn
  1362. OpFunctionEnd
  1363. )";
  1364. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1365. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1366. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1367. auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
  1368. text, /* skip_nop = */ true, /* do_validation = */ false);
  1369. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  1370. }
  1371. TEST_F(CopyPropArrayPassTest, BadCopyViaInserts3) {
  1372. const std::string text =
  1373. R"(
  1374. OpCapability Shader
  1375. OpMemoryModel Logical GLSL450
  1376. OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
  1377. OpExecutionMode %main OriginUpperLeft
  1378. OpSource HLSL 600
  1379. OpName %type_MyCBuffer "type.MyCBuffer"
  1380. OpMemberName %type_MyCBuffer 0 "Data"
  1381. OpName %MyCBuffer "MyCBuffer"
  1382. OpName %main "main"
  1383. OpName %in_var_INDEX "in.var.INDEX"
  1384. OpName %out_var_SV_Target "out.var.SV_Target"
  1385. OpDecorate %_arr_v4float_uint_8 ArrayStride 16
  1386. OpMemberDecorate %type_MyCBuffer 0 Offset 0
  1387. OpDecorate %type_MyCBuffer Block
  1388. OpDecorate %in_var_INDEX Flat
  1389. OpDecorate %in_var_INDEX Location 0
  1390. OpDecorate %out_var_SV_Target Location 0
  1391. OpDecorate %MyCBuffer DescriptorSet 0
  1392. OpDecorate %MyCBuffer Binding 0
  1393. %float = OpTypeFloat 32
  1394. %v4float = OpTypeVector %float 4
  1395. %uint = OpTypeInt 32 0
  1396. %uint_8 = OpConstant %uint 8
  1397. %_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
  1398. %type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
  1399. %_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
  1400. %void = OpTypeVoid
  1401. %13 = OpTypeFunction %void
  1402. %int = OpTypeInt 32 1
  1403. %_ptr_Input_int = OpTypePointer Input %int
  1404. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1405. %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
  1406. %_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
  1407. %int_0 = OpConstant %int 0
  1408. %_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
  1409. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1410. %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
  1411. %in_var_INDEX = OpVariable %_ptr_Input_int Input
  1412. %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
  1413. %main = OpFunction %void None %13
  1414. %22 = OpLabel
  1415. %23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
  1416. %undef = OpUndef %_arr_v4float_uint_8_0
  1417. %24 = OpLoad %int %in_var_INDEX
  1418. %25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
  1419. %26 = OpLoad %_arr_v4float_uint_8 %25
  1420. %28 = OpCompositeExtract %v4float %26 1
  1421. %i1 = OpCompositeInsert %_arr_v4float_uint_8_0 %28 %undef 1
  1422. %29 = OpCompositeExtract %v4float %26 2
  1423. %i2 = OpCompositeInsert %_arr_v4float_uint_8_0 %29 %i1 2
  1424. %30 = OpCompositeExtract %v4float %26 3
  1425. %i3 = OpCompositeInsert %_arr_v4float_uint_8_0 %30 %i2 3
  1426. %31 = OpCompositeExtract %v4float %26 4
  1427. %i4 = OpCompositeInsert %_arr_v4float_uint_8_0 %31 %i3 4
  1428. %32 = OpCompositeExtract %v4float %26 5
  1429. %i5 = OpCompositeInsert %_arr_v4float_uint_8_0 %32 %i4 5
  1430. %33 = OpCompositeExtract %v4float %26 6
  1431. %i6 = OpCompositeInsert %_arr_v4float_uint_8_0 %33 %i5 6
  1432. %34 = OpCompositeExtract %v4float %26 7
  1433. %i7 = OpCompositeInsert %_arr_v4float_uint_8_0 %34 %i6 7
  1434. OpStore %23 %i7
  1435. %36 = OpAccessChain %_ptr_Function_v4float %23 %24
  1436. %37 = OpLoad %v4float %36
  1437. OpStore %out_var_SV_Target %37
  1438. OpReturn
  1439. OpFunctionEnd
  1440. )";
  1441. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1442. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1443. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1444. auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
  1445. text, /* skip_nop = */ true, /* do_validation = */ false);
  1446. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  1447. }
  1448. TEST_F(CopyPropArrayPassTest, AtomicAdd) {
  1449. const std::string before = R"(OpCapability SampledBuffer
  1450. OpCapability StorageImageExtendedFormats
  1451. OpCapability ImageBuffer
  1452. OpCapability Shader
  1453. %1 = OpExtInstImport "GLSL.std.450"
  1454. OpMemoryModel Logical GLSL450
  1455. OpEntryPoint GLCompute %2 "min" %gl_GlobalInvocationID
  1456. OpExecutionMode %2 LocalSize 64 1 1
  1457. OpSource HLSL 600
  1458. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  1459. OpDecorate %4 DescriptorSet 4
  1460. OpDecorate %4 Binding 70
  1461. %uint = OpTypeInt 32 0
  1462. %6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui
  1463. %_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6
  1464. %_ptr_Function_6 = OpTypePointer Function %6
  1465. %void = OpTypeVoid
  1466. %10 = OpTypeFunction %void
  1467. %uint_0 = OpConstant %uint 0
  1468. %uint_1 = OpConstant %uint 1
  1469. %v3uint = OpTypeVector %uint 3
  1470. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  1471. %_ptr_Image_uint = OpTypePointer Image %uint
  1472. %4 = OpVariable %_ptr_UniformConstant_6 UniformConstant
  1473. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  1474. %2 = OpFunction %void None %10
  1475. %17 = OpLabel
  1476. %16 = OpVariable %_ptr_Function_6 Function
  1477. %18 = OpLoad %6 %4
  1478. OpStore %16 %18
  1479. %19 = OpImageTexelPointer %_ptr_Image_uint %16 %uint_0 %uint_0
  1480. %20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1
  1481. OpReturn
  1482. OpFunctionEnd
  1483. )";
  1484. const std::string after = R"(OpCapability SampledBuffer
  1485. OpCapability StorageImageExtendedFormats
  1486. OpCapability ImageBuffer
  1487. OpCapability Shader
  1488. %1 = OpExtInstImport "GLSL.std.450"
  1489. OpMemoryModel Logical GLSL450
  1490. OpEntryPoint GLCompute %2 "min" %gl_GlobalInvocationID
  1491. OpExecutionMode %2 LocalSize 64 1 1
  1492. OpSource HLSL 600
  1493. OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
  1494. OpDecorate %4 DescriptorSet 4
  1495. OpDecorate %4 Binding 70
  1496. %uint = OpTypeInt 32 0
  1497. %6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui
  1498. %_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6
  1499. %_ptr_Function_6 = OpTypePointer Function %6
  1500. %void = OpTypeVoid
  1501. %10 = OpTypeFunction %void
  1502. %uint_0 = OpConstant %uint 0
  1503. %uint_1 = OpConstant %uint 1
  1504. %v3uint = OpTypeVector %uint 3
  1505. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  1506. %_ptr_Image_uint = OpTypePointer Image %uint
  1507. %4 = OpVariable %_ptr_UniformConstant_6 UniformConstant
  1508. %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
  1509. %2 = OpFunction %void None %10
  1510. %17 = OpLabel
  1511. %16 = OpVariable %_ptr_Function_6 Function
  1512. %18 = OpLoad %6 %4
  1513. OpStore %16 %18
  1514. %19 = OpImageTexelPointer %_ptr_Image_uint %4 %uint_0 %uint_0
  1515. %20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1
  1516. OpReturn
  1517. OpFunctionEnd
  1518. )";
  1519. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1520. SinglePassRunAndCheck<CopyPropagateArrays>(before, after, true, true);
  1521. }
  1522. } // namespace
  1523. } // namespace opt
  1524. } // namespace spvtools