copy_prop_array_test.cpp 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577
  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. %39 = 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