2
0

upgrade_memory_model_test.cpp 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271
  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 "assembly_builder.h"
  15. #include "pass_fixture.h"
  16. #include "pass_utils.h"
  17. namespace {
  18. using namespace spvtools;
  19. using UpgradeMemoryModelTest = opt::PassTest<::testing::Test>;
  20. TEST_F(UpgradeMemoryModelTest, InvalidMemoryModelOpenCL) {
  21. const std::string text = R"(
  22. ; CHECK: OpMemoryModel Logical OpenCL
  23. OpCapability Kernel
  24. OpCapability Linkage
  25. OpMemoryModel Logical OpenCL
  26. )";
  27. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  28. }
  29. TEST_F(UpgradeMemoryModelTest, InvalidMemoryModelVulkan) {
  30. const std::string text = R"(
  31. ; CHECK: OpMemoryModel Logical Vulkan
  32. OpCapability Shader
  33. OpCapability Linkage
  34. OpCapability VulkanMemoryModel
  35. OpExtension "SPV_KHR_vulkan_memory_model"
  36. OpMemoryModel Logical Vulkan
  37. )";
  38. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  39. }
  40. TEST_F(UpgradeMemoryModelTest, JustMemoryModel) {
  41. const std::string text = R"(
  42. ; CHECK: OpCapability VulkanMemoryModel
  43. ; CHECK: OpExtension "SPV_KHR_vulkan_memory_model"
  44. ; CHECK: OpMemoryModel Logical Vulkan
  45. OpCapability Shader
  46. OpCapability Linkage
  47. OpMemoryModel Logical GLSL450
  48. )";
  49. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  50. }
  51. TEST_F(UpgradeMemoryModelTest, RemoveDecorations) {
  52. const std::string text = R"(
  53. ; CHECK-NOT: OpDecorate
  54. OpCapability Shader
  55. OpCapability Linkage
  56. OpMemoryModel Logical GLSL450
  57. OpDecorate %var Volatile
  58. OpDecorate %var Coherent
  59. %int = OpTypeInt 32 0
  60. %ptr_int_Uniform = OpTypePointer Uniform %int
  61. %var = OpVariable %ptr_int_Uniform Uniform
  62. )";
  63. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  64. }
  65. TEST_F(UpgradeMemoryModelTest, WorkgroupVariable) {
  66. const std::string text = R"(
  67. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 2
  68. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  69. ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
  70. OpCapability Shader
  71. OpCapability Linkage
  72. OpMemoryModel Logical GLSL450
  73. %void = OpTypeVoid
  74. %int = OpTypeInt 32 0
  75. %ptr_int_Workgroup = OpTypePointer Workgroup %int
  76. %var = OpVariable %ptr_int_Workgroup Workgroup
  77. %func_ty = OpTypeFunction %void
  78. %func = OpFunction %void None %func_ty
  79. %1 = OpLabel
  80. %ld = OpLoad %int %var
  81. OpStore %var %ld
  82. OpReturn
  83. OpFunctionEnd
  84. )";
  85. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  86. }
  87. TEST_F(UpgradeMemoryModelTest, WorkgroupFunctionParameter) {
  88. const std::string text = R"(
  89. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 2
  90. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  91. ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
  92. OpCapability Shader
  93. OpCapability Linkage
  94. OpMemoryModel Logical GLSL450
  95. %void = OpTypeVoid
  96. %int = OpTypeInt 32 0
  97. %ptr_int_Workgroup = OpTypePointer Workgroup %int
  98. %func_ty = OpTypeFunction %void %ptr_int_Workgroup
  99. %func = OpFunction %void None %func_ty
  100. %param = OpFunctionParameter %ptr_int_Workgroup
  101. %1 = OpLabel
  102. %ld = OpLoad %int %param
  103. OpStore %param %ld
  104. OpReturn
  105. OpFunctionEnd
  106. )";
  107. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  108. }
  109. TEST_F(UpgradeMemoryModelTest, SimpleUniformVariable) {
  110. const std::string text = R"(
  111. ; CHECK-NOT: OpDecorate
  112. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  113. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
  114. ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
  115. OpCapability Shader
  116. OpCapability Linkage
  117. OpMemoryModel Logical GLSL450
  118. OpDecorate %var Coherent
  119. OpDecorate %var Volatile
  120. %void = OpTypeVoid
  121. %int = OpTypeInt 32 0
  122. %ptr_int_Uniform = OpTypePointer Uniform %int
  123. %var = OpVariable %ptr_int_Uniform Uniform
  124. %func_ty = OpTypeFunction %void
  125. %func = OpFunction %void None %func_ty
  126. %1 = OpLabel
  127. %ld = OpLoad %int %var
  128. OpStore %var %ld
  129. OpReturn
  130. OpFunctionEnd
  131. )";
  132. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  133. }
  134. TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameter) {
  135. const std::string text = R"(
  136. ; CHECK-NOT: OpDecorate
  137. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  138. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
  139. ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
  140. OpCapability Shader
  141. OpCapability Linkage
  142. OpMemoryModel Logical GLSL450
  143. OpDecorate %param Coherent
  144. OpDecorate %param Volatile
  145. %void = OpTypeVoid
  146. %int = OpTypeInt 32 0
  147. %ptr_int_Uniform = OpTypePointer Uniform %int
  148. %func_ty = OpTypeFunction %void %ptr_int_Uniform
  149. %func = OpFunction %void None %func_ty
  150. %param = OpFunctionParameter %ptr_int_Uniform
  151. %1 = OpLabel
  152. %ld = OpLoad %int %param
  153. OpStore %param %ld
  154. OpReturn
  155. OpFunctionEnd
  156. )";
  157. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  158. }
  159. TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableOnlyVolatile) {
  160. const std::string text = R"(
  161. ; CHECK-NOT: OpDecorate
  162. ; CHECK-NOT: OpConstant
  163. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
  164. ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile
  165. OpCapability Shader
  166. OpCapability Linkage
  167. OpMemoryModel Logical GLSL450
  168. OpDecorate %var Volatile
  169. %void = OpTypeVoid
  170. %int = OpTypeInt 32 0
  171. %ptr_int_Uniform = OpTypePointer Uniform %int
  172. %var = OpVariable %ptr_int_Uniform Uniform
  173. %func_ty = OpTypeFunction %void
  174. %func = OpFunction %void None %func_ty
  175. %1 = OpLabel
  176. %ld = OpLoad %int %var
  177. OpStore %var %ld
  178. OpReturn
  179. OpFunctionEnd
  180. )";
  181. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  182. }
  183. TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableCopied) {
  184. const std::string text = R"(
  185. ; CHECK-NOT: OpDecorate
  186. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  187. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
  188. ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
  189. OpCapability Shader
  190. OpCapability Linkage
  191. OpMemoryModel Logical GLSL450
  192. OpDecorate %var Coherent
  193. OpDecorate %var Volatile
  194. %void = OpTypeVoid
  195. %int = OpTypeInt 32 0
  196. %ptr_int_Uniform = OpTypePointer Uniform %int
  197. %var = OpVariable %ptr_int_Uniform Uniform
  198. %func_ty = OpTypeFunction %void
  199. %func = OpFunction %void None %func_ty
  200. %1 = OpLabel
  201. %copy = OpCopyObject %ptr_int_Uniform %var
  202. %ld = OpLoad %int %copy
  203. OpStore %copy %ld
  204. OpReturn
  205. OpFunctionEnd
  206. )";
  207. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  208. }
  209. TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameterCopied) {
  210. const std::string text = R"(
  211. ; CHECK-NOT: OpDecorate
  212. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  213. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
  214. ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
  215. OpCapability Shader
  216. OpCapability Linkage
  217. OpMemoryModel Logical GLSL450
  218. OpDecorate %param Coherent
  219. OpDecorate %param Volatile
  220. %void = OpTypeVoid
  221. %int = OpTypeInt 32 0
  222. %ptr_int_Uniform = OpTypePointer Uniform %int
  223. %func_ty = OpTypeFunction %void %ptr_int_Uniform
  224. %func = OpFunction %void None %func_ty
  225. %param = OpFunctionParameter %ptr_int_Uniform
  226. %1 = OpLabel
  227. %copy = OpCopyObject %ptr_int_Uniform %param
  228. %ld = OpLoad %int %copy
  229. %copy2 = OpCopyObject %ptr_int_Uniform %param
  230. OpStore %copy2 %ld
  231. OpReturn
  232. OpFunctionEnd
  233. )";
  234. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  235. }
  236. TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableAccessChain) {
  237. const std::string text = R"(
  238. ; CHECK-NOT: OpDecorate
  239. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  240. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
  241. ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
  242. OpCapability Shader
  243. OpCapability Linkage
  244. OpMemoryModel Logical GLSL450
  245. OpDecorate %var Coherent
  246. OpDecorate %var Volatile
  247. %void = OpTypeVoid
  248. %int = OpTypeInt 32 0
  249. %int0 = OpConstant %int 0
  250. %int3 = OpConstant %int 3
  251. %int_array_3 = OpTypeArray %int %int3
  252. %ptr_intarray_Uniform = OpTypePointer Uniform %int_array_3
  253. %ptr_int_Uniform = OpTypePointer Uniform %int
  254. %var = OpVariable %ptr_intarray_Uniform Uniform
  255. %func_ty = OpTypeFunction %void
  256. %func = OpFunction %void None %func_ty
  257. %1 = OpLabel
  258. %gep = OpAccessChain %ptr_int_Uniform %var %int0
  259. %ld = OpLoad %int %gep
  260. OpStore %gep %ld
  261. OpReturn
  262. OpFunctionEnd
  263. )";
  264. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  265. }
  266. TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameterAccessChain) {
  267. const std::string text = R"(
  268. ; CHECK-NOT: OpDecorate
  269. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  270. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
  271. ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
  272. OpCapability Shader
  273. OpCapability Linkage
  274. OpMemoryModel Logical GLSL450
  275. OpDecorate %param Coherent
  276. OpDecorate %param Volatile
  277. %void = OpTypeVoid
  278. %int = OpTypeInt 32 0
  279. %int0 = OpConstant %int 0
  280. %int3 = OpConstant %int 3
  281. %int_array_3 = OpTypeArray %int %int3
  282. %ptr_intarray_Uniform = OpTypePointer Uniform %int_array_3
  283. %ptr_int_Uniform = OpTypePointer Uniform %int
  284. %func_ty = OpTypeFunction %void %ptr_intarray_Uniform
  285. %func = OpFunction %void None %func_ty
  286. %param = OpFunctionParameter %ptr_intarray_Uniform
  287. %1 = OpLabel
  288. %ld_gep = OpAccessChain %ptr_int_Uniform %param %int0
  289. %ld = OpLoad %int %ld_gep
  290. %st_gep = OpAccessChain %ptr_int_Uniform %param %int0
  291. OpStore %st_gep %ld
  292. OpReturn
  293. OpFunctionEnd
  294. )";
  295. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  296. }
  297. TEST_F(UpgradeMemoryModelTest, VariablePointerSelect) {
  298. const std::string text = R"(
  299. ; CHECK-NOT: OpDecorate
  300. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  301. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
  302. ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
  303. OpCapability Shader
  304. OpCapability Linkage
  305. OpCapability VariablePointers
  306. OpExtension "SPV_KHR_variable_pointers"
  307. OpMemoryModel Logical GLSL450
  308. OpDecorate %var Coherent
  309. OpDecorate %var Volatile
  310. %void = OpTypeVoid
  311. %int = OpTypeInt 32 0
  312. %bool = OpTypeBool
  313. %true = OpConstantTrue %bool
  314. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  315. %null = OpConstantNull %ptr_int_StorageBuffer
  316. %var = OpVariable %ptr_int_StorageBuffer StorageBuffer
  317. %func_ty = OpTypeFunction %void
  318. %func = OpFunction %void None %func_ty
  319. %1 = OpLabel
  320. %select = OpSelect %ptr_int_StorageBuffer %true %var %null
  321. %ld = OpLoad %int %select
  322. OpStore %var %ld
  323. OpReturn
  324. OpFunctionEnd
  325. )";
  326. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  327. }
  328. TEST_F(UpgradeMemoryModelTest, VariablePointerSelectConservative) {
  329. const std::string text = R"(
  330. ; CHECK-NOT: OpDecorate
  331. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  332. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
  333. ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
  334. OpCapability Shader
  335. OpCapability Linkage
  336. OpCapability VariablePointers
  337. OpExtension "SPV_KHR_variable_pointers"
  338. OpMemoryModel Logical GLSL450
  339. OpDecorate %var1 Coherent
  340. OpDecorate %var2 Volatile
  341. %void = OpTypeVoid
  342. %int = OpTypeInt 32 0
  343. %bool = OpTypeBool
  344. %true = OpConstantTrue %bool
  345. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  346. %var1 = OpVariable %ptr_int_StorageBuffer StorageBuffer
  347. %var2 = OpVariable %ptr_int_StorageBuffer StorageBuffer
  348. %func_ty = OpTypeFunction %void
  349. %func = OpFunction %void None %func_ty
  350. %1 = OpLabel
  351. %select = OpSelect %ptr_int_StorageBuffer %true %var1 %var2
  352. %ld = OpLoad %int %select
  353. OpStore %select %ld
  354. OpReturn
  355. OpFunctionEnd
  356. )";
  357. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  358. }
  359. TEST_F(UpgradeMemoryModelTest, VariablePointerIncrement) {
  360. const std::string text = R"(
  361. ; CHECK-NOT: OpDecorate {{%\w+}} Coherent
  362. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  363. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  364. ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
  365. OpCapability Shader
  366. OpCapability Linkage
  367. OpCapability VariablePointers
  368. OpExtension "SPV_KHR_variable_pointers"
  369. OpMemoryModel Logical GLSL450
  370. OpDecorate %param Coherent
  371. OpDecorate %ptr_int_StorageBuffer ArrayStride 4
  372. %void = OpTypeVoid
  373. %bool = OpTypeBool
  374. %int = OpTypeInt 32 0
  375. %int0 = OpConstant %int 0
  376. %int1 = OpConstant %int 1
  377. %int10 = OpConstant %int 10
  378. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  379. %func_ty = OpTypeFunction %void %ptr_int_StorageBuffer
  380. %func = OpFunction %void None %func_ty
  381. %param = OpFunctionParameter %ptr_int_StorageBuffer
  382. %1 = OpLabel
  383. OpBranch %2
  384. %2 = OpLabel
  385. %phi = OpPhi %ptr_int_StorageBuffer %param %1 %ptr_next %2
  386. %iv = OpPhi %int %int0 %1 %inc %2
  387. %inc = OpIAdd %int %iv %int1
  388. %ptr_next = OpPtrAccessChain %ptr_int_StorageBuffer %phi %int1
  389. %cmp = OpIEqual %bool %iv %int10
  390. OpLoopMerge %3 %2 None
  391. OpBranchConditional %cmp %3 %2
  392. %3 = OpLabel
  393. %ld = OpLoad %int %phi
  394. OpStore %phi %ld
  395. OpReturn
  396. OpFunctionEnd
  397. )";
  398. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  399. }
  400. TEST_F(UpgradeMemoryModelTest, CoherentStructElement) {
  401. const std::string text = R"(
  402. ; CHECK-NOT: OpMemberDecorate
  403. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  404. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  405. ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
  406. OpCapability Shader
  407. OpCapability Linkage
  408. OpExtension "SPV_KHR_storage_buffer_storage_class"
  409. OpMemoryModel Logical GLSL450
  410. OpMemberDecorate %struct 0 Coherent
  411. %void = OpTypeVoid
  412. %int = OpTypeInt 32 0
  413. %int0 = OpConstant %int 0
  414. %struct = OpTypeStruct %int
  415. %ptr_struct_StorageBuffer = OpTypePointer StorageBuffer %struct
  416. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  417. %func_ty = OpTypeFunction %void %ptr_struct_StorageBuffer
  418. %func = OpFunction %void None %func_ty
  419. %param = OpFunctionParameter %ptr_struct_StorageBuffer
  420. %1 = OpLabel
  421. %gep = OpAccessChain %ptr_int_StorageBuffer %param %int0
  422. %ld = OpLoad %int %gep
  423. OpStore %gep %ld
  424. OpReturn
  425. OpFunctionEnd
  426. )";
  427. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  428. }
  429. TEST_F(UpgradeMemoryModelTest, CoherentElementFullStructAccess) {
  430. const std::string text = R"(
  431. ; CHECK-NOT: OpMemberDecorate
  432. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  433. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  434. ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
  435. OpCapability Shader
  436. OpCapability Linkage
  437. OpExtension "SPV_KHR_storage_buffer_storage_class"
  438. OpMemoryModel Logical GLSL450
  439. OpMemberDecorate %struct 0 Coherent
  440. %void = OpTypeVoid
  441. %int = OpTypeInt 32 0
  442. %struct = OpTypeStruct %int
  443. %ptr_struct_StorageBuffer = OpTypePointer StorageBuffer %struct
  444. %func_ty = OpTypeFunction %void %ptr_struct_StorageBuffer
  445. %func = OpFunction %void None %func_ty
  446. %param = OpFunctionParameter %ptr_struct_StorageBuffer
  447. %1 = OpLabel
  448. %ld = OpLoad %struct %param
  449. OpStore %param %ld
  450. OpReturn
  451. OpFunctionEnd
  452. )";
  453. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  454. }
  455. TEST_F(UpgradeMemoryModelTest, CoherentElementNotAccessed) {
  456. const std::string text = R"(
  457. ; CHECK-NOT: OpMemberDecorate
  458. ; CHECK-NOT: MakePointerAvailable
  459. ; CHECK-NOT: NonPrivatePointer
  460. ; CHECK-NOT: MakePointerVisible
  461. OpCapability Shader
  462. OpCapability Linkage
  463. OpExtension "SPV_KHR_storage_buffer_storage_class"
  464. OpMemoryModel Logical GLSL450
  465. OpMemberDecorate %struct 1 Coherent
  466. %void = OpTypeVoid
  467. %int = OpTypeInt 32 0
  468. %int0 = OpConstant %int 0
  469. %struct = OpTypeStruct %int %int
  470. %ptr_struct_StorageBuffer = OpTypePointer StorageBuffer %struct
  471. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  472. %func_ty = OpTypeFunction %void %ptr_struct_StorageBuffer
  473. %func = OpFunction %void None %func_ty
  474. %param = OpFunctionParameter %ptr_struct_StorageBuffer
  475. %1 = OpLabel
  476. %gep = OpAccessChain %ptr_int_StorageBuffer %param %int0
  477. %ld = OpLoad %int %gep
  478. OpStore %gep %ld
  479. OpReturn
  480. OpFunctionEnd
  481. )";
  482. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  483. }
  484. TEST_F(UpgradeMemoryModelTest, MultiIndexAccessCoherent) {
  485. const std::string text = R"(
  486. ; CHECK-NOT: OpMemberDecorate
  487. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  488. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  489. ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
  490. OpCapability Shader
  491. OpCapability Linkage
  492. OpExtension "SPV_KHR_storage_buffer_storage_class"
  493. OpMemoryModel Logical GLSL450
  494. OpMemberDecorate %inner 1 Coherent
  495. %void = OpTypeVoid
  496. %int = OpTypeInt 32 0
  497. %int0 = OpConstant %int 0
  498. %int1 = OpConstant %int 1
  499. %inner = OpTypeStruct %int %int
  500. %middle = OpTypeStruct %inner
  501. %outer = OpTypeStruct %middle %middle
  502. %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
  503. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  504. %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
  505. %func = OpFunction %void None %func_ty
  506. %param = OpFunctionParameter %ptr_outer_StorageBuffer
  507. %1 = OpLabel
  508. %ld_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int0 %int0 %int1
  509. %ld = OpLoad %int %ld_gep
  510. %st_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int1 %int0 %int1
  511. OpStore %st_gep %ld
  512. OpReturn
  513. OpFunctionEnd
  514. )";
  515. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  516. }
  517. TEST_F(UpgradeMemoryModelTest, MultiIndexAccessNonCoherent) {
  518. const std::string text = R"(
  519. ; CHECK-NOT: OpMemberDecorate
  520. ; CHECK-NOT: MakePointerAvailable
  521. ; CHECK-NOT: NonPrivatePointer
  522. ; CHECK-NOT: MakePointerVisible
  523. OpCapability Shader
  524. OpCapability Linkage
  525. OpExtension "SPV_KHR_storage_buffer_storage_class"
  526. OpMemoryModel Logical GLSL450
  527. OpMemberDecorate %inner 1 Coherent
  528. %void = OpTypeVoid
  529. %int = OpTypeInt 32 0
  530. %int0 = OpConstant %int 0
  531. %int1 = OpConstant %int 1
  532. %inner = OpTypeStruct %int %int
  533. %middle = OpTypeStruct %inner
  534. %outer = OpTypeStruct %middle %middle
  535. %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
  536. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  537. %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
  538. %func = OpFunction %void None %func_ty
  539. %param = OpFunctionParameter %ptr_outer_StorageBuffer
  540. %1 = OpLabel
  541. %ld_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int0 %int0 %int0
  542. %ld = OpLoad %int %ld_gep
  543. %st_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int1 %int0 %int0
  544. OpStore %st_gep %ld
  545. OpReturn
  546. OpFunctionEnd
  547. )";
  548. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  549. }
  550. TEST_F(UpgradeMemoryModelTest, ConsecutiveAccessChainCoherent) {
  551. const std::string text = R"(
  552. ; CHECK-NOT: OpMemberDecorate
  553. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  554. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  555. ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
  556. OpCapability Shader
  557. OpCapability Linkage
  558. OpExtension "SPV_KHR_storage_buffer_storage_class"
  559. OpMemoryModel Logical GLSL450
  560. OpMemberDecorate %inner 1 Coherent
  561. %void = OpTypeVoid
  562. %int = OpTypeInt 32 0
  563. %int0 = OpConstant %int 0
  564. %int1 = OpConstant %int 1
  565. %inner = OpTypeStruct %int %int
  566. %middle = OpTypeStruct %inner
  567. %outer = OpTypeStruct %middle %middle
  568. %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
  569. %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
  570. %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
  571. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  572. %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
  573. %func = OpFunction %void None %func_ty
  574. %param = OpFunctionParameter %ptr_outer_StorageBuffer
  575. %1 = OpLabel
  576. %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
  577. %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
  578. %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int1
  579. %ld = OpLoad %int %ld_gep3
  580. %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
  581. %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
  582. %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int1
  583. OpStore %st_gep3 %ld
  584. OpReturn
  585. OpFunctionEnd
  586. )";
  587. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  588. }
  589. TEST_F(UpgradeMemoryModelTest, ConsecutiveAccessChainNonCoherent) {
  590. const std::string text = R"(
  591. ; CHECK-NOT: OpMemberDecorate
  592. ; CHECK-NOT: MakePointerAvailable
  593. ; CHECK-NOT: NonPrivatePointer
  594. ; CHECK-NOT: MakePointerVisible
  595. OpCapability Shader
  596. OpCapability Linkage
  597. OpExtension "SPV_KHR_storage_buffer_storage_class"
  598. OpMemoryModel Logical GLSL450
  599. OpMemberDecorate %inner 1 Coherent
  600. %void = OpTypeVoid
  601. %int = OpTypeInt 32 0
  602. %int0 = OpConstant %int 0
  603. %int1 = OpConstant %int 1
  604. %inner = OpTypeStruct %int %int
  605. %middle = OpTypeStruct %inner
  606. %outer = OpTypeStruct %middle %middle
  607. %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
  608. %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
  609. %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
  610. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  611. %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
  612. %func = OpFunction %void None %func_ty
  613. %param = OpFunctionParameter %ptr_outer_StorageBuffer
  614. %1 = OpLabel
  615. %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
  616. %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
  617. %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int0
  618. %ld = OpLoad %int %ld_gep3
  619. %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
  620. %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
  621. %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int0
  622. OpStore %st_gep3 %ld
  623. OpReturn
  624. OpFunctionEnd
  625. )";
  626. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  627. }
  628. TEST_F(UpgradeMemoryModelTest, CoherentStructElementAccess) {
  629. const std::string text = R"(
  630. ; CHECK-NOT: OpMemberDecorate
  631. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  632. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  633. ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
  634. OpCapability Shader
  635. OpCapability Linkage
  636. OpExtension "SPV_KHR_storage_buffer_storage_class"
  637. OpMemoryModel Logical GLSL450
  638. OpMemberDecorate %middle 0 Coherent
  639. %void = OpTypeVoid
  640. %int = OpTypeInt 32 0
  641. %int0 = OpConstant %int 0
  642. %int1 = OpConstant %int 1
  643. %inner = OpTypeStruct %int %int
  644. %middle = OpTypeStruct %inner
  645. %outer = OpTypeStruct %middle %middle
  646. %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
  647. %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
  648. %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
  649. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  650. %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
  651. %func = OpFunction %void None %func_ty
  652. %param = OpFunctionParameter %ptr_outer_StorageBuffer
  653. %1 = OpLabel
  654. %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
  655. %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
  656. %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int1
  657. %ld = OpLoad %int %ld_gep3
  658. %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
  659. %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
  660. %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int1
  661. OpStore %st_gep3 %ld
  662. OpReturn
  663. OpFunctionEnd
  664. )";
  665. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  666. }
  667. TEST_F(UpgradeMemoryModelTest, NonCoherentLoadCoherentStore) {
  668. const std::string text = R"(
  669. ; CHECK-NOT: OpMemberDecorate
  670. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  671. ; CHECK-NOT: MakePointerVisible
  672. ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
  673. OpCapability Shader
  674. OpCapability Linkage
  675. OpExtension "SPV_KHR_storage_buffer_storage_class"
  676. OpMemoryModel Logical GLSL450
  677. OpMemberDecorate %outer 1 Coherent
  678. %void = OpTypeVoid
  679. %int = OpTypeInt 32 0
  680. %int0 = OpConstant %int 0
  681. %int1 = OpConstant %int 1
  682. %inner = OpTypeStruct %int %int
  683. %middle = OpTypeStruct %inner
  684. %outer = OpTypeStruct %middle %middle
  685. %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
  686. %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
  687. %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
  688. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  689. %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
  690. %func = OpFunction %void None %func_ty
  691. %param = OpFunctionParameter %ptr_outer_StorageBuffer
  692. %1 = OpLabel
  693. %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
  694. %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
  695. %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int1
  696. %ld = OpLoad %int %ld_gep3
  697. %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
  698. %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
  699. %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int1
  700. OpStore %st_gep3 %ld
  701. OpReturn
  702. OpFunctionEnd
  703. )";
  704. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  705. }
  706. TEST_F(UpgradeMemoryModelTest, CopyMemory) {
  707. const std::string text = R"(
  708. ; CHECK-NOT: OpDecorate
  709. ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
  710. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[queuefamily]]
  711. ; CHECK-NOT: [[queuefamily]]
  712. OpCapability Shader
  713. OpCapability Linkage
  714. OpExtension "SPV_KHR_storage_buffer_storage_class"
  715. OpMemoryModel Logical GLSL450
  716. OpDecorate %in_var Coherent
  717. OpDecorate %out_var Volatile
  718. %void = OpTypeVoid
  719. %int = OpTypeInt 32 0
  720. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  721. %in_var = OpVariable %ptr_int_StorageBuffer StorageBuffer
  722. %out_var = OpVariable %ptr_int_StorageBuffer StorageBuffer
  723. %func_ty = OpTypeFunction %void
  724. %func = OpFunction %void None %func_ty
  725. %1 = OpLabel
  726. OpCopyMemory %out_var %in_var
  727. OpReturn
  728. OpFunctionEnd
  729. )";
  730. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  731. }
  732. TEST_F(UpgradeMemoryModelTest, CopyMemorySized) {
  733. const std::string text = R"(
  734. ; CHECK-NOT: OpDecorate
  735. ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
  736. ; CHECK: OpCopyMemorySized {{%\w+}} {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[queuefamily]]
  737. ; CHECK-NOT: [[queuefamily]]
  738. OpCapability Shader
  739. OpCapability Linkage
  740. OpCapability Addresses
  741. OpExtension "SPV_KHR_storage_buffer_storage_class"
  742. OpMemoryModel Logical GLSL450
  743. OpDecorate %out_param Coherent
  744. OpDecorate %in_param Volatile
  745. %void = OpTypeVoid
  746. %int = OpTypeInt 32 0
  747. %int4 = OpConstant %int 4
  748. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  749. %func_ty = OpTypeFunction %void %ptr_int_StorageBuffer %ptr_int_StorageBuffer
  750. %func = OpFunction %void None %func_ty
  751. %in_param = OpFunctionParameter %ptr_int_StorageBuffer
  752. %out_param = OpFunctionParameter %ptr_int_StorageBuffer
  753. %1 = OpLabel
  754. OpCopyMemorySized %out_param %in_param %int4
  755. OpReturn
  756. OpFunctionEnd
  757. )";
  758. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  759. }
  760. TEST_F(UpgradeMemoryModelTest, CopyMemoryTwoScopes) {
  761. const std::string text = R"(
  762. ; CHECK-NOT: OpDecorate
  763. ; CHECK-DAG: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
  764. ; CHECK-DAG: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
  765. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|MakePointerVisible|NonPrivatePointer [[workgroup]] [[queuefamily]]
  766. OpCapability Shader
  767. OpCapability Linkage
  768. OpExtension "SPV_KHR_storage_buffer_storage_class"
  769. OpMemoryModel Logical GLSL450
  770. OpDecorate %in_var Coherent
  771. OpDecorate %out_var Coherent
  772. %void = OpTypeVoid
  773. %int = OpTypeInt 32 0
  774. %ptr_int_Workgroup = OpTypePointer Workgroup %int
  775. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  776. %in_var = OpVariable %ptr_int_StorageBuffer StorageBuffer
  777. %out_var = OpVariable %ptr_int_Workgroup Workgroup
  778. %func_ty = OpTypeFunction %void
  779. %func = OpFunction %void None %func_ty
  780. %1 = OpLabel
  781. OpCopyMemory %out_var %in_var
  782. OpReturn
  783. OpFunctionEnd
  784. )";
  785. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  786. }
  787. TEST_F(UpgradeMemoryModelTest, VolatileImageRead) {
  788. const std::string text = R"(
  789. ; CHECK-NOT: OpDecorate
  790. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
  791. ; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexel
  792. OpCapability Shader
  793. OpCapability Linkage
  794. OpCapability StorageImageReadWithoutFormat
  795. OpExtension "SPV_KHR_storage_buffer_storage_class"
  796. OpMemoryModel Logical GLSL450
  797. OpDecorate %var Volatile
  798. %void = OpTypeVoid
  799. %int = OpTypeInt 32 0
  800. %v2int = OpTypeVector %int 2
  801. %float = OpTypeFloat 32
  802. %int0 = OpConstant %int 0
  803. %v2int_0 = OpConstantComposite %v2int %int0 %int0
  804. %image = OpTypeImage %float 2D 0 0 0 2 Unknown
  805. %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
  806. %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
  807. %func_ty = OpTypeFunction %void
  808. %func = OpFunction %void None %func_ty
  809. %1 = OpLabel
  810. %ld = OpLoad %image %var
  811. %rd = OpImageRead %float %ld %v2int_0
  812. OpReturn
  813. OpFunctionEnd
  814. )";
  815. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  816. }
  817. TEST_F(UpgradeMemoryModelTest, CoherentImageRead) {
  818. const std::string text = R"(
  819. ; CHECK-NOT: OpDecorate
  820. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  821. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  822. ; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
  823. OpCapability Shader
  824. OpCapability Linkage
  825. OpCapability StorageImageReadWithoutFormat
  826. OpExtension "SPV_KHR_storage_buffer_storage_class"
  827. OpMemoryModel Logical GLSL450
  828. OpDecorate %var Coherent
  829. %void = OpTypeVoid
  830. %int = OpTypeInt 32 0
  831. %v2int = OpTypeVector %int 2
  832. %float = OpTypeFloat 32
  833. %int0 = OpConstant %int 0
  834. %v2int_0 = OpConstantComposite %v2int %int0 %int0
  835. %image = OpTypeImage %float 2D 0 0 0 2 Unknown
  836. %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
  837. %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
  838. %func_ty = OpTypeFunction %void
  839. %func = OpFunction %void None %func_ty
  840. %1 = OpLabel
  841. %ld = OpLoad %image %var
  842. %rd = OpImageRead %float %ld %v2int_0
  843. OpReturn
  844. OpFunctionEnd
  845. )";
  846. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  847. }
  848. TEST_F(UpgradeMemoryModelTest, CoherentImageReadExtractedFromSampledImage) {
  849. const std::string text = R"(
  850. ; CHECK-NOT: OpDecorate
  851. ; CHECK: [[image:%\w+]] = OpTypeImage
  852. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  853. ; CHECK: OpLoad [[image]] {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  854. ; CHECK-NOT: NonPrivatePointer
  855. ; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
  856. OpCapability Shader
  857. OpCapability Linkage
  858. OpCapability StorageImageReadWithoutFormat
  859. OpExtension "SPV_KHR_storage_buffer_storage_class"
  860. OpMemoryModel Logical GLSL450
  861. OpDecorate %var Coherent
  862. %void = OpTypeVoid
  863. %int = OpTypeInt 32 0
  864. %v2int = OpTypeVector %int 2
  865. %float = OpTypeFloat 32
  866. %int0 = OpConstant %int 0
  867. %v2int_0 = OpConstantComposite %v2int %int0 %int0
  868. %image = OpTypeImage %float 2D 0 0 0 0 Unknown
  869. %sampled_image = OpTypeSampledImage %image
  870. %sampler = OpTypeSampler
  871. %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
  872. %ptr_sampler_StorageBuffer = OpTypePointer StorageBuffer %sampler
  873. %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
  874. %sampler_var = OpVariable %ptr_sampler_StorageBuffer StorageBuffer
  875. %func_ty = OpTypeFunction %void
  876. %func = OpFunction %void None %func_ty
  877. %1 = OpLabel
  878. %ld = OpLoad %image %var
  879. %ld_sampler = OpLoad %sampler %sampler_var
  880. %sample = OpSampledImage %sampled_image %ld %ld_sampler
  881. %extract = OpImage %image %sample
  882. %rd = OpImageRead %float %extract %v2int_0
  883. OpReturn
  884. OpFunctionEnd
  885. )";
  886. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  887. }
  888. TEST_F(UpgradeMemoryModelTest, VolatileImageWrite) {
  889. const std::string text = R"(
  890. ; CHECK-NOT: OpDecorate
  891. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
  892. ; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexel
  893. OpCapability Shader
  894. OpCapability Linkage
  895. OpCapability StorageImageWriteWithoutFormat
  896. OpExtension "SPV_KHR_storage_buffer_storage_class"
  897. OpMemoryModel Logical GLSL450
  898. OpDecorate %param Volatile
  899. %void = OpTypeVoid
  900. %int = OpTypeInt 32 0
  901. %v2int = OpTypeVector %int 2
  902. %float = OpTypeFloat 32
  903. %float0 = OpConstant %float 0
  904. %v2int_null = OpConstantNull %v2int
  905. %image = OpTypeImage %float 2D 0 0 0 0 Unknown
  906. %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
  907. %func_ty = OpTypeFunction %void %ptr_image_StorageBuffer
  908. %func = OpFunction %void None %func_ty
  909. %param = OpFunctionParameter %ptr_image_StorageBuffer
  910. %1 = OpLabel
  911. %ld = OpLoad %image %param
  912. OpImageWrite %ld %v2int_null %float0
  913. OpReturn
  914. OpFunctionEnd
  915. )";
  916. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  917. }
  918. TEST_F(UpgradeMemoryModelTest, CoherentImageWrite) {
  919. const std::string text = R"(
  920. ; CHECK-NOT: OpDecorate
  921. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  922. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer
  923. ; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailable|NonPrivateTexel [[scope]]
  924. OpCapability Shader
  925. OpCapability Linkage
  926. OpCapability StorageImageWriteWithoutFormat
  927. OpExtension "SPV_KHR_storage_buffer_storage_class"
  928. OpMemoryModel Logical GLSL450
  929. OpDecorate %param Coherent
  930. %void = OpTypeVoid
  931. %int = OpTypeInt 32 0
  932. %v2int = OpTypeVector %int 2
  933. %float = OpTypeFloat 32
  934. %float0 = OpConstant %float 0
  935. %v2int_null = OpConstantNull %v2int
  936. %image = OpTypeImage %float 2D 0 0 0 0 Unknown
  937. %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
  938. %func_ty = OpTypeFunction %void %ptr_image_StorageBuffer
  939. %func = OpFunction %void None %func_ty
  940. %param = OpFunctionParameter %ptr_image_StorageBuffer
  941. %1 = OpLabel
  942. %ld = OpLoad %image %param
  943. OpImageWrite %ld %v2int_null %float0
  944. OpReturn
  945. OpFunctionEnd
  946. )";
  947. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  948. }
  949. TEST_F(UpgradeMemoryModelTest, CoherentImageWriteExtractFromSampledImage) {
  950. const std::string text = R"(
  951. ; CHECK-NOT: OpDecorate
  952. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  953. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer
  954. ; CHECK-NOT: NonPrivatePointer
  955. ; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailable|NonPrivateTexel [[scope]]
  956. OpCapability Shader
  957. OpCapability Linkage
  958. OpCapability StorageImageWriteWithoutFormat
  959. OpExtension "SPV_KHR_storage_buffer_storage_class"
  960. OpMemoryModel Logical GLSL450
  961. OpDecorate %param Coherent
  962. %void = OpTypeVoid
  963. %int = OpTypeInt 32 0
  964. %v2int = OpTypeVector %int 2
  965. %float = OpTypeFloat 32
  966. %float0 = OpConstant %float 0
  967. %v2int_null = OpConstantNull %v2int
  968. %image = OpTypeImage %float 2D 0 0 0 0 Unknown
  969. %sampled_image = OpTypeSampledImage %image
  970. %sampler = OpTypeSampler
  971. %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
  972. %ptr_sampler_StorageBuffer = OpTypePointer StorageBuffer %sampler
  973. %func_ty = OpTypeFunction %void %ptr_image_StorageBuffer %ptr_sampler_StorageBuffer
  974. %func = OpFunction %void None %func_ty
  975. %param = OpFunctionParameter %ptr_image_StorageBuffer
  976. %sampler_param = OpFunctionParameter %ptr_sampler_StorageBuffer
  977. %1 = OpLabel
  978. %ld = OpLoad %image %param
  979. %ld_sampler = OpLoad %sampler %sampler_param
  980. %sample = OpSampledImage %sampled_image %ld %ld_sampler
  981. %extract = OpImage %image %sample
  982. OpImageWrite %extract %v2int_null %float0
  983. OpReturn
  984. OpFunctionEnd
  985. )";
  986. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  987. }
  988. TEST_F(UpgradeMemoryModelTest, VolatileImageSparseRead) {
  989. const std::string text = R"(
  990. ; CHECK-NOT: OpDecorate
  991. ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
  992. ; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexel
  993. OpCapability Shader
  994. OpCapability Linkage
  995. OpCapability StorageImageReadWithoutFormat
  996. OpCapability SparseResidency
  997. OpExtension "SPV_KHR_storage_buffer_storage_class"
  998. OpMemoryModel Logical GLSL450
  999. OpDecorate %var Volatile
  1000. %void = OpTypeVoid
  1001. %int = OpTypeInt 32 0
  1002. %v2int = OpTypeVector %int 2
  1003. %float = OpTypeFloat 32
  1004. %int0 = OpConstant %int 0
  1005. %v2int_0 = OpConstantComposite %v2int %int0 %int0
  1006. %image = OpTypeImage %float 2D 0 0 0 2 Unknown
  1007. %struct = OpTypeStruct %int %float
  1008. %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
  1009. %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
  1010. %func_ty = OpTypeFunction %void
  1011. %func = OpFunction %void None %func_ty
  1012. %1 = OpLabel
  1013. %ld = OpLoad %image %var
  1014. %rd = OpImageSparseRead %struct %ld %v2int_0
  1015. OpReturn
  1016. OpFunctionEnd
  1017. )";
  1018. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1019. }
  1020. TEST_F(UpgradeMemoryModelTest, CoherentImageSparseRead) {
  1021. const std::string text = R"(
  1022. ; CHECK-NOT: OpDecorate
  1023. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  1024. ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  1025. ; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
  1026. OpCapability Shader
  1027. OpCapability Linkage
  1028. OpCapability StorageImageReadWithoutFormat
  1029. OpCapability SparseResidency
  1030. OpExtension "SPV_KHR_storage_buffer_storage_class"
  1031. OpMemoryModel Logical GLSL450
  1032. OpDecorate %var Coherent
  1033. %void = OpTypeVoid
  1034. %int = OpTypeInt 32 0
  1035. %v2int = OpTypeVector %int 2
  1036. %float = OpTypeFloat 32
  1037. %int0 = OpConstant %int 0
  1038. %v2int_0 = OpConstantComposite %v2int %int0 %int0
  1039. %image = OpTypeImage %float 2D 0 0 0 2 Unknown
  1040. %struct = OpTypeStruct %int %float
  1041. %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
  1042. %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
  1043. %func_ty = OpTypeFunction %void
  1044. %func = OpFunction %void None %func_ty
  1045. %1 = OpLabel
  1046. %ld = OpLoad %image %var
  1047. %rd = OpImageSparseRead %struct %ld %v2int_0
  1048. OpReturn
  1049. OpFunctionEnd
  1050. )";
  1051. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1052. }
  1053. TEST_F(UpgradeMemoryModelTest,
  1054. CoherentImageSparseReadExtractedFromSampledImage) {
  1055. const std::string text = R"(
  1056. ; CHECK-NOT: OpDecorate
  1057. ; CHECK: [[image:%\w+]] = OpTypeImage
  1058. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  1059. ; CHECK: OpLoad [[image]] {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
  1060. ; CHECK-NOT: NonPrivatePointer
  1061. ; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
  1062. OpCapability Shader
  1063. OpCapability Linkage
  1064. OpCapability StorageImageReadWithoutFormat
  1065. OpCapability SparseResidency
  1066. OpExtension "SPV_KHR_storage_buffer_storage_class"
  1067. OpMemoryModel Logical GLSL450
  1068. OpDecorate %var Coherent
  1069. %void = OpTypeVoid
  1070. %int = OpTypeInt 32 0
  1071. %v2int = OpTypeVector %int 2
  1072. %float = OpTypeFloat 32
  1073. %int0 = OpConstant %int 0
  1074. %v2int_0 = OpConstantComposite %v2int %int0 %int0
  1075. %image = OpTypeImage %float 2D 0 0 0 0 Unknown
  1076. %struct = OpTypeStruct %int %float
  1077. %sampled_image = OpTypeSampledImage %image
  1078. %sampler = OpTypeSampler
  1079. %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
  1080. %ptr_sampler_StorageBuffer = OpTypePointer StorageBuffer %sampler
  1081. %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
  1082. %sampler_var = OpVariable %ptr_sampler_StorageBuffer StorageBuffer
  1083. %func_ty = OpTypeFunction %void
  1084. %func = OpFunction %void None %func_ty
  1085. %1 = OpLabel
  1086. %ld = OpLoad %image %var
  1087. %ld_sampler = OpLoad %sampler %sampler_var
  1088. %sample = OpSampledImage %sampled_image %ld %ld_sampler
  1089. %extract = OpImage %image %sample
  1090. %rd = OpImageSparseRead %struct %extract %v2int_0
  1091. OpReturn
  1092. OpFunctionEnd
  1093. )";
  1094. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1095. }
  1096. TEST_F(UpgradeMemoryModelTest, TessellationControlBarrierNoChange) {
  1097. const std::string text = R"(
  1098. ; CHECK: [[none:%\w+]] = OpConstant {{%\w+}} 0
  1099. ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
  1100. ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[none]]
  1101. OpCapability Tessellation
  1102. OpMemoryModel Logical GLSL450
  1103. OpEntryPoint TessellationControl %func "func"
  1104. %void = OpTypeVoid
  1105. %int = OpTypeInt 32 0
  1106. %none = OpConstant %int 0
  1107. %workgroup = OpConstant %int 2
  1108. %func_ty = OpTypeFunction %void
  1109. %func = OpFunction %void None %func_ty
  1110. %1 = OpLabel
  1111. OpControlBarrier %workgroup %workgroup %none
  1112. OpReturn
  1113. OpFunctionEnd
  1114. )";
  1115. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1116. }
  1117. TEST_F(UpgradeMemoryModelTest, TessellationControlBarrierAddOutput) {
  1118. const std::string text = R"(
  1119. ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
  1120. ; CHECK: [[output:%\w+]] = OpConstant {{%\w+}} 4096
  1121. ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[output]]
  1122. OpCapability Tessellation
  1123. OpMemoryModel Logical GLSL450
  1124. OpEntryPoint TessellationControl %func "func" %var
  1125. %void = OpTypeVoid
  1126. %int = OpTypeInt 32 0
  1127. %none = OpConstant %int 0
  1128. %workgroup = OpConstant %int 2
  1129. %ptr_int_Output = OpTypePointer Output %int
  1130. %var = OpVariable %ptr_int_Output Output
  1131. %func_ty = OpTypeFunction %void
  1132. %func = OpFunction %void None %func_ty
  1133. %1 = OpLabel
  1134. %ld = OpLoad %int %var
  1135. OpControlBarrier %workgroup %workgroup %none
  1136. OpStore %var %ld
  1137. OpReturn
  1138. OpFunctionEnd
  1139. )";
  1140. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1141. }
  1142. TEST_F(UpgradeMemoryModelTest, TessellationMemoryBarrierNoChange) {
  1143. const std::string text = R"(
  1144. ; CHECK: [[none:%\w+]] = OpConstant {{%\w+}} 0
  1145. ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
  1146. ; CHECK: OpMemoryBarrier [[workgroup]] [[none]]
  1147. OpCapability Tessellation
  1148. OpMemoryModel Logical GLSL450
  1149. OpEntryPoint TessellationControl %func "func" %var
  1150. %void = OpTypeVoid
  1151. %int = OpTypeInt 32 0
  1152. %none = OpConstant %int 0
  1153. %workgroup = OpConstant %int 2
  1154. %ptr_int_Output = OpTypePointer Output %int
  1155. %var = OpVariable %ptr_int_Output Output
  1156. %func_ty = OpTypeFunction %void
  1157. %func = OpFunction %void None %func_ty
  1158. %1 = OpLabel
  1159. %ld = OpLoad %int %var
  1160. OpMemoryBarrier %workgroup %none
  1161. OpStore %var %ld
  1162. OpReturn
  1163. OpFunctionEnd
  1164. )";
  1165. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1166. }
  1167. TEST_F(UpgradeMemoryModelTest, TessellationControlBarrierAddOutputSubFunction) {
  1168. const std::string text = R"(
  1169. ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
  1170. ; CHECK: [[output:%\w+]] = OpConstant {{%\w+}} 4096
  1171. ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[output]]
  1172. OpCapability Tessellation
  1173. OpMemoryModel Logical GLSL450
  1174. OpEntryPoint TessellationControl %func "func" %var
  1175. %void = OpTypeVoid
  1176. %int = OpTypeInt 32 0
  1177. %none = OpConstant %int 0
  1178. %workgroup = OpConstant %int 2
  1179. %ptr_int_Output = OpTypePointer Output %int
  1180. %var = OpVariable %ptr_int_Output Output
  1181. %func_ty = OpTypeFunction %void
  1182. %func = OpFunction %void None %func_ty
  1183. %1 = OpLabel
  1184. %call = OpFunctionCall %void %sub_func
  1185. OpReturn
  1186. OpFunctionEnd
  1187. %sub_func = OpFunction %void None %func_ty
  1188. %2 = OpLabel
  1189. %ld = OpLoad %int %var
  1190. OpControlBarrier %workgroup %workgroup %none
  1191. OpStore %var %ld
  1192. OpReturn
  1193. OpFunctionEnd
  1194. )";
  1195. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1196. }
  1197. TEST_F(UpgradeMemoryModelTest,
  1198. TessellationControlBarrierAddOutputDifferentFunctions) {
  1199. const std::string text = R"(
  1200. ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
  1201. ; CHECK: [[output:%\w+]] = OpConstant {{%\w+}} 4096
  1202. ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[output]]
  1203. OpCapability Tessellation
  1204. OpMemoryModel Logical GLSL450
  1205. OpEntryPoint TessellationControl %func "func" %var
  1206. %void = OpTypeVoid
  1207. %int = OpTypeInt 32 0
  1208. %none = OpConstant %int 0
  1209. %workgroup = OpConstant %int 2
  1210. %ptr_int_Output = OpTypePointer Output %int
  1211. %var = OpVariable %ptr_int_Output Output
  1212. %func_ty = OpTypeFunction %void
  1213. %ld_func_ty = OpTypeFunction %int
  1214. %st_func_ty = OpTypeFunction %void %int
  1215. %func = OpFunction %void None %func_ty
  1216. %1 = OpLabel
  1217. %call_ld = OpFunctionCall %int %ld_func
  1218. %call_barrier = OpFunctionCall %void %barrier_func
  1219. %call_st = OpFunctionCall %void %st_func %call_ld
  1220. OpReturn
  1221. OpFunctionEnd
  1222. %ld_func = OpFunction %int None %ld_func_ty
  1223. %2 = OpLabel
  1224. %ld = OpLoad %int %var
  1225. OpReturnValue %ld
  1226. OpFunctionEnd
  1227. %barrier_func = OpFunction %void None %func_ty
  1228. %3 = OpLabel
  1229. OpControlBarrier %workgroup %workgroup %none
  1230. OpReturn
  1231. OpFunctionEnd
  1232. %st_func = OpFunction %void None %st_func_ty
  1233. %param = OpFunctionParameter %int
  1234. %4 = OpLabel
  1235. OpStore %var %param
  1236. OpReturn
  1237. OpFunctionEnd
  1238. )";
  1239. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1240. }
  1241. TEST_F(UpgradeMemoryModelTest, ChangeControlBarrierMemoryScope) {
  1242. std::string text = R"(
  1243. ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
  1244. ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
  1245. ; CHECK: OpControlBarrier [[workgroup]] [[queuefamily]]
  1246. OpCapability Shader
  1247. OpMemoryModel Logical GLSL450
  1248. OpEntryPoint GLCompute %func "func"
  1249. %void = OpTypeVoid
  1250. %int = OpTypeInt 32 0
  1251. %none = OpConstant %int 0
  1252. %device = OpConstant %int 1
  1253. %workgroup = OpConstant %int 2
  1254. %func_ty = OpTypeFunction %void
  1255. %func = OpFunction %void None %func_ty
  1256. %1 = OpLabel
  1257. OpControlBarrier %workgroup %device %none
  1258. OpReturn
  1259. OpFunctionEnd
  1260. )";
  1261. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1262. }
  1263. TEST_F(UpgradeMemoryModelTest, ChangeMemoryBarrierMemoryScope) {
  1264. std::string text = R"(
  1265. ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
  1266. ; CHECK: OpMemoryBarrier [[queuefamily]]
  1267. OpCapability Shader
  1268. OpMemoryModel Logical GLSL450
  1269. OpEntryPoint GLCompute %func "func"
  1270. %void = OpTypeVoid
  1271. %int = OpTypeInt 32 0
  1272. %none = OpConstant %int 0
  1273. %device = OpConstant %int 1
  1274. %func_ty = OpTypeFunction %void
  1275. %func = OpFunction %void None %func_ty
  1276. %1 = OpLabel
  1277. OpMemoryBarrier %device %none
  1278. OpReturn
  1279. OpFunctionEnd
  1280. )";
  1281. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1282. }
  1283. TEST_F(UpgradeMemoryModelTest, ChangeAtomicMemoryScope) {
  1284. std::string text = R"(
  1285. ; CHECK: [[int:%\w+]] = OpTypeInt
  1286. ; CHECK: [[var:%\w+]] = OpVariable
  1287. ; CHECK: [[qf:%\w+]] = OpConstant [[int]] 5
  1288. ; CHECK: OpAtomicLoad [[int]] [[var]] [[qf]]
  1289. ; CHECK: OpAtomicStore [[var]] [[qf]]
  1290. ; CHECK: OpAtomicExchange [[int]] [[var]] [[qf]]
  1291. ; CHECK: OpAtomicCompareExchange [[int]] [[var]] [[qf]]
  1292. ; CHECK: OpAtomicIIncrement [[int]] [[var]] [[qf]]
  1293. ; CHECK: OpAtomicIDecrement [[int]] [[var]] [[qf]]
  1294. ; CHECK: OpAtomicIAdd [[int]] [[var]] [[qf]]
  1295. ; CHECK: OpAtomicISub [[int]] [[var]] [[qf]]
  1296. ; CHECK: OpAtomicSMin [[int]] [[var]] [[qf]]
  1297. ; CHECK: OpAtomicSMax [[int]] [[var]] [[qf]]
  1298. ; CHECK: OpAtomicUMin [[int]] [[var]] [[qf]]
  1299. ; CHECK: OpAtomicUMax [[int]] [[var]] [[qf]]
  1300. ; CHECK: OpAtomicAnd [[int]] [[var]] [[qf]]
  1301. ; CHECK: OpAtomicOr [[int]] [[var]] [[qf]]
  1302. ; CHECK: OpAtomicXor [[int]] [[var]] [[qf]]
  1303. OpCapability Shader
  1304. OpExtension "SPV_KHR_storage_buffer_storage_class"
  1305. OpMemoryModel Logical GLSL450
  1306. OpEntryPoint GLCompute %func "func"
  1307. %void = OpTypeVoid
  1308. %int = OpTypeInt 32 0
  1309. %none = OpConstant %int 0
  1310. %device = OpConstant %int 1
  1311. %func_ty = OpTypeFunction %void
  1312. %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
  1313. %var = OpVariable %ptr_int_StorageBuffer StorageBuffer
  1314. %func = OpFunction %void None %func_ty
  1315. %1 = OpLabel
  1316. %ld = OpAtomicLoad %int %var %device %none
  1317. OpAtomicStore %var %device %none %ld
  1318. %ex = OpAtomicExchange %int %var %device %none %ld
  1319. %cmp_ex = OpAtomicCompareExchange %int %var %device %none %none %ld %ld
  1320. %inc = OpAtomicIIncrement %int %var %device %none
  1321. %dec = OpAtomicIDecrement %int %var %device %none
  1322. %add = OpAtomicIAdd %int %var %device %none %ld
  1323. %sub = OpAtomicISub %int %var %device %none %ld
  1324. %smin = OpAtomicSMin %int %var %device %none %ld
  1325. %smax = OpAtomicSMax %int %var %device %none %ld
  1326. %umin = OpAtomicUMin %int %var %device %none %ld
  1327. %umax = OpAtomicUMax %int %var %device %none %ld
  1328. %and = OpAtomicAnd %int %var %device %none %ld
  1329. %or = OpAtomicOr %int %var %device %none %ld
  1330. %xor = OpAtomicXor %int %var %device %none %ld
  1331. OpReturn
  1332. OpFunctionEnd
  1333. )";
  1334. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1335. }
  1336. TEST_F(UpgradeMemoryModelTest, UpgradeModfNoFlags) {
  1337. const std::string text = R"(
  1338. ; CHECK: [[float:%\w+]] = OpTypeFloat 32
  1339. ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
  1340. ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[float]]
  1341. ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
  1342. ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[float]]
  1343. ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
  1344. ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
  1345. ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
  1346. ; CHECK: OpStore [[var]] [[ex1]]
  1347. ; CHECK-NOT: NonPrivatePointer
  1348. ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
  1349. OpCapability Shader
  1350. OpMemoryModel Logical GLSL450
  1351. %import = OpExtInstImport "GLSL.std.450"
  1352. OpEntryPoint GLCompute %func "func"
  1353. %void = OpTypeVoid
  1354. %float = OpTypeFloat 32
  1355. %float_0 = OpConstant %float 0
  1356. %ptr_ssbo_float = OpTypePointer StorageBuffer %float
  1357. %ssbo_var = OpVariable %ptr_ssbo_float StorageBuffer
  1358. %func_ty = OpTypeFunction %void
  1359. %func = OpFunction %void None %func_ty
  1360. %1 = OpLabel
  1361. %2 = OpExtInst %float %import Modf %float_0 %ssbo_var
  1362. %3 = OpFAdd %float %float_0 %2
  1363. OpReturn
  1364. OpFunctionEnd
  1365. )";
  1366. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1367. }
  1368. TEST_F(UpgradeMemoryModelTest, UpgradeModfWorkgroupCoherent) {
  1369. const std::string text = R"(
  1370. ; CHECK: [[float:%\w+]] = OpTypeFloat 32
  1371. ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
  1372. ; CHECK: [[ptr:%\w+]] = OpTypePointer Workgroup [[float]]
  1373. ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] Workgroup
  1374. ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[float]]
  1375. ; CHECK: [[wg_scope:%\w+]] = OpConstant {{%\w+}} 2
  1376. ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
  1377. ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
  1378. ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
  1379. ; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[wg_scope]]
  1380. ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
  1381. OpCapability Shader
  1382. OpMemoryModel Logical GLSL450
  1383. %import = OpExtInstImport "GLSL.std.450"
  1384. OpEntryPoint GLCompute %func "func"
  1385. OpDecorate %wg_var Coherent
  1386. %void = OpTypeVoid
  1387. %float = OpTypeFloat 32
  1388. %float_0 = OpConstant %float 0
  1389. %ptr_wg_float = OpTypePointer Workgroup %float
  1390. %wg_var = OpVariable %ptr_wg_float Workgroup
  1391. %func_ty = OpTypeFunction %void
  1392. %func = OpFunction %void None %func_ty
  1393. %1 = OpLabel
  1394. %2 = OpExtInst %float %import Modf %float_0 %wg_var
  1395. %3 = OpFAdd %float %float_0 %2
  1396. OpReturn
  1397. OpFunctionEnd
  1398. )";
  1399. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1400. }
  1401. TEST_F(UpgradeMemoryModelTest, UpgradeModfSSBOCoherent) {
  1402. const std::string text = R"(
  1403. ; CHECK: [[float:%\w+]] = OpTypeFloat 32
  1404. ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
  1405. ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[float]]
  1406. ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
  1407. ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[float]]
  1408. ; CHECK: [[qf_scope:%\w+]] = OpConstant {{%\w+}} 5
  1409. ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
  1410. ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
  1411. ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
  1412. ; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[qf_scope]]
  1413. ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
  1414. OpCapability Shader
  1415. OpMemoryModel Logical GLSL450
  1416. %import = OpExtInstImport "GLSL.std.450"
  1417. OpEntryPoint GLCompute %func "func"
  1418. OpDecorate %ssbo_var Coherent
  1419. %void = OpTypeVoid
  1420. %float = OpTypeFloat 32
  1421. %float_0 = OpConstant %float 0
  1422. %ptr_ssbo_float = OpTypePointer StorageBuffer %float
  1423. %ssbo_var = OpVariable %ptr_ssbo_float StorageBuffer
  1424. %func_ty = OpTypeFunction %void
  1425. %func = OpFunction %void None %func_ty
  1426. %1 = OpLabel
  1427. %2 = OpExtInst %float %import Modf %float_0 %ssbo_var
  1428. %3 = OpFAdd %float %float_0 %2
  1429. OpReturn
  1430. OpFunctionEnd
  1431. )";
  1432. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1433. }
  1434. TEST_F(UpgradeMemoryModelTest, UpgradeModfSSBOVolatile) {
  1435. const std::string text = R"(
  1436. ; CHECK: [[float:%\w+]] = OpTypeFloat 32
  1437. ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
  1438. ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[float]]
  1439. ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
  1440. ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[float]]
  1441. ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
  1442. ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
  1443. ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
  1444. ; CHECK: OpStore [[var]] [[ex1]] Volatile
  1445. ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
  1446. OpCapability Shader
  1447. OpMemoryModel Logical GLSL450
  1448. %import = OpExtInstImport "GLSL.std.450"
  1449. OpEntryPoint GLCompute %func "func"
  1450. OpDecorate %wg_var Volatile
  1451. %void = OpTypeVoid
  1452. %float = OpTypeFloat 32
  1453. %float_0 = OpConstant %float 0
  1454. %ptr_ssbo_float = OpTypePointer StorageBuffer %float
  1455. %wg_var = OpVariable %ptr_ssbo_float StorageBuffer
  1456. %func_ty = OpTypeFunction %void
  1457. %func = OpFunction %void None %func_ty
  1458. %1 = OpLabel
  1459. %2 = OpExtInst %float %import Modf %float_0 %wg_var
  1460. %3 = OpFAdd %float %float_0 %2
  1461. OpReturn
  1462. OpFunctionEnd
  1463. )";
  1464. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1465. }
  1466. TEST_F(UpgradeMemoryModelTest, UpgradeFrexpNoFlags) {
  1467. const std::string text = R"(
  1468. ; CHECK: [[float:%\w+]] = OpTypeFloat 32
  1469. ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
  1470. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  1471. ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[int]]
  1472. ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
  1473. ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[int]]
  1474. ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
  1475. ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
  1476. ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
  1477. ; CHECK: OpStore [[var]] [[ex1]]
  1478. ; CHECK-NOT: NonPrivatePointer
  1479. ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
  1480. OpCapability Shader
  1481. OpMemoryModel Logical GLSL450
  1482. %import = OpExtInstImport "GLSL.std.450"
  1483. OpEntryPoint GLCompute %func "func"
  1484. %void = OpTypeVoid
  1485. %float = OpTypeFloat 32
  1486. %float_0 = OpConstant %float 0
  1487. %int = OpTypeInt 32 0
  1488. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1489. %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
  1490. %func_ty = OpTypeFunction %void
  1491. %func = OpFunction %void None %func_ty
  1492. %1 = OpLabel
  1493. %2 = OpExtInst %float %import Frexp %float_0 %ssbo_var
  1494. %3 = OpFAdd %float %float_0 %2
  1495. OpReturn
  1496. OpFunctionEnd
  1497. )";
  1498. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1499. }
  1500. TEST_F(UpgradeMemoryModelTest, UpgradeFrexpWorkgroupCoherent) {
  1501. const std::string text = R"(
  1502. ; CHECK: [[float:%\w+]] = OpTypeFloat 32
  1503. ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
  1504. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  1505. ; CHECK: [[ptr:%\w+]] = OpTypePointer Workgroup [[int]]
  1506. ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] Workgroup
  1507. ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[int]]
  1508. ; CHECK: [[wg_scope:%\w+]] = OpConstant {{%\w+}} 2
  1509. ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
  1510. ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
  1511. ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
  1512. ; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[wg_scope]]
  1513. ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
  1514. OpCapability Shader
  1515. OpMemoryModel Logical GLSL450
  1516. %import = OpExtInstImport "GLSL.std.450"
  1517. OpEntryPoint GLCompute %func "func"
  1518. OpDecorate %wg_var Coherent
  1519. %void = OpTypeVoid
  1520. %float = OpTypeFloat 32
  1521. %float_0 = OpConstant %float 0
  1522. %int = OpTypeInt 32 0
  1523. %ptr_wg_int = OpTypePointer Workgroup %int
  1524. %wg_var = OpVariable %ptr_wg_int Workgroup
  1525. %func_ty = OpTypeFunction %void
  1526. %func = OpFunction %void None %func_ty
  1527. %1 = OpLabel
  1528. %2 = OpExtInst %float %import Frexp %float_0 %wg_var
  1529. %3 = OpFAdd %float %float_0 %2
  1530. OpReturn
  1531. OpFunctionEnd
  1532. )";
  1533. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1534. }
  1535. TEST_F(UpgradeMemoryModelTest, UpgradeFrexpSSBOCoherent) {
  1536. const std::string text = R"(
  1537. ; CHECK: [[float:%\w+]] = OpTypeFloat 32
  1538. ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
  1539. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  1540. ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[int]]
  1541. ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
  1542. ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[int]]
  1543. ; CHECK: [[qf_scope:%\w+]] = OpConstant {{%\w+}} 5
  1544. ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
  1545. ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
  1546. ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
  1547. ; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[qf_scope]]
  1548. ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
  1549. OpCapability Shader
  1550. OpMemoryModel Logical GLSL450
  1551. %import = OpExtInstImport "GLSL.std.450"
  1552. OpEntryPoint GLCompute %func "func"
  1553. OpDecorate %ssbo_var Coherent
  1554. %void = OpTypeVoid
  1555. %float = OpTypeFloat 32
  1556. %float_0 = OpConstant %float 0
  1557. %int = OpTypeInt 32 0
  1558. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1559. %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
  1560. %func_ty = OpTypeFunction %void
  1561. %func = OpFunction %void None %func_ty
  1562. %1 = OpLabel
  1563. %2 = OpExtInst %float %import Frexp %float_0 %ssbo_var
  1564. %3 = OpFAdd %float %float_0 %2
  1565. OpReturn
  1566. OpFunctionEnd
  1567. )";
  1568. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1569. }
  1570. TEST_F(UpgradeMemoryModelTest, UpgradeFrexpSSBOVolatile) {
  1571. const std::string text = R"(
  1572. ; CHECK: [[float:%\w+]] = OpTypeFloat 32
  1573. ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
  1574. ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
  1575. ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[int]]
  1576. ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
  1577. ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[int]]
  1578. ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
  1579. ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
  1580. ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
  1581. ; CHECK: OpStore [[var]] [[ex1]] Volatile
  1582. ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
  1583. OpCapability Shader
  1584. OpMemoryModel Logical GLSL450
  1585. %import = OpExtInstImport "GLSL.std.450"
  1586. OpEntryPoint GLCompute %func "func"
  1587. OpDecorate %wg_var Volatile
  1588. %void = OpTypeVoid
  1589. %float = OpTypeFloat 32
  1590. %float_0 = OpConstant %float 0
  1591. %int = OpTypeInt 32 0
  1592. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1593. %wg_var = OpVariable %ptr_ssbo_int StorageBuffer
  1594. %func_ty = OpTypeFunction %void
  1595. %func = OpFunction %void None %func_ty
  1596. %1 = OpLabel
  1597. %2 = OpExtInst %float %import Frexp %float_0 %wg_var
  1598. %3 = OpFAdd %float %float_0 %2
  1599. OpReturn
  1600. OpFunctionEnd
  1601. )";
  1602. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1603. }
  1604. TEST_F(UpgradeMemoryModelTest, SPV14NormalizeCopyMemoryAddOperands) {
  1605. const std::string text = R"(
  1606. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} None None
  1607. OpCapability Shader
  1608. OpMemoryModel Logical GLSL450
  1609. OpEntryPoint GLCompute %func "func" %src %dst
  1610. %void = OpTypeVoid
  1611. %int = OpTypeInt 32 0
  1612. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1613. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1614. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1615. %void_fn = OpTypeFunction %void
  1616. %func = OpFunction %void None %void_fn
  1617. %entry = OpLabel
  1618. OpCopyMemory %dst %src
  1619. OpReturn
  1620. OpFunctionEnd
  1621. )";
  1622. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1623. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1624. }
  1625. TEST_F(UpgradeMemoryModelTest, SPV14NormalizeCopyMemoryDuplicateOperand) {
  1626. const std::string text = R"(
  1627. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Nontemporal Nontemporal
  1628. OpCapability Shader
  1629. OpMemoryModel Logical GLSL450
  1630. OpEntryPoint GLCompute %func "func" %src %dst
  1631. %void = OpTypeVoid
  1632. %int = OpTypeInt 32 0
  1633. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1634. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1635. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1636. %void_fn = OpTypeFunction %void
  1637. %func = OpFunction %void None %void_fn
  1638. %entry = OpLabel
  1639. OpCopyMemory %dst %src Nontemporal
  1640. OpReturn
  1641. OpFunctionEnd
  1642. )";
  1643. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1644. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1645. }
  1646. TEST_F(UpgradeMemoryModelTest, SPV14NormalizeCopyMemoryDuplicateOperands) {
  1647. const std::string text = R"(
  1648. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned 4 Aligned 4
  1649. OpCapability Shader
  1650. OpMemoryModel Logical GLSL450
  1651. OpEntryPoint GLCompute %func "func" %src %dst
  1652. %void = OpTypeVoid
  1653. %int = OpTypeInt 32 0
  1654. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1655. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1656. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1657. %void_fn = OpTypeFunction %void
  1658. %func = OpFunction %void None %void_fn
  1659. %entry = OpLabel
  1660. OpCopyMemory %dst %src Aligned 4
  1661. OpReturn
  1662. OpFunctionEnd
  1663. )";
  1664. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1665. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1666. }
  1667. TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryDstCoherent) {
  1668. const std::string text = R"(
  1669. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  1670. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]] None
  1671. OpCapability Shader
  1672. OpMemoryModel Logical GLSL450
  1673. OpEntryPoint GLCompute %func "func" %src %dst
  1674. OpDecorate %dst Coherent
  1675. %void = OpTypeVoid
  1676. %int = OpTypeInt 32 0
  1677. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1678. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1679. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1680. %void_fn = OpTypeFunction %void
  1681. %func = OpFunction %void None %void_fn
  1682. %entry = OpLabel
  1683. OpCopyMemory %dst %src
  1684. OpReturn
  1685. OpFunctionEnd
  1686. )";
  1687. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1688. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1689. }
  1690. TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryDstCoherentPreviousArgs) {
  1691. const std::string text = R"(
  1692. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  1693. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailable|NonPrivatePointer 4 [[scope]] Aligned 4
  1694. OpCapability Shader
  1695. OpMemoryModel Logical GLSL450
  1696. OpEntryPoint GLCompute %func "func" %src %dst
  1697. OpDecorate %dst Coherent
  1698. %void = OpTypeVoid
  1699. %int = OpTypeInt 32 0
  1700. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1701. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1702. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1703. %void_fn = OpTypeFunction %void
  1704. %func = OpFunction %void None %void_fn
  1705. %entry = OpLabel
  1706. OpCopyMemory %dst %src Aligned 4
  1707. OpReturn
  1708. OpFunctionEnd
  1709. )";
  1710. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1711. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1712. }
  1713. TEST_F(UpgradeMemoryModelTest, SPV14CopyMemorySrcCoherent) {
  1714. const std::string text = R"(
  1715. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  1716. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} None MakePointerVisible|NonPrivatePointer [[scope]]
  1717. OpCapability Shader
  1718. OpMemoryModel Logical GLSL450
  1719. OpEntryPoint GLCompute %func "func" %src %dst
  1720. OpDecorate %src Coherent
  1721. %void = OpTypeVoid
  1722. %int = OpTypeInt 32 0
  1723. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1724. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1725. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1726. %void_fn = OpTypeFunction %void
  1727. %func = OpFunction %void None %void_fn
  1728. %entry = OpLabel
  1729. OpCopyMemory %dst %src
  1730. OpReturn
  1731. OpFunctionEnd
  1732. )";
  1733. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1734. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1735. }
  1736. TEST_F(UpgradeMemoryModelTest, SPV14CopyMemorySrcCoherentPreviousArgs) {
  1737. const std::string text = R"(
  1738. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  1739. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned 4 Aligned|MakePointerVisible|NonPrivatePointer 4 [[scope]]
  1740. OpCapability Shader
  1741. OpMemoryModel Logical GLSL450
  1742. OpEntryPoint GLCompute %func "func" %src %dst
  1743. OpDecorate %src Coherent
  1744. %void = OpTypeVoid
  1745. %int = OpTypeInt 32 0
  1746. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1747. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1748. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1749. %void_fn = OpTypeFunction %void
  1750. %func = OpFunction %void None %void_fn
  1751. %entry = OpLabel
  1752. OpCopyMemory %dst %src Aligned 4
  1753. OpReturn
  1754. OpFunctionEnd
  1755. )";
  1756. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1757. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1758. }
  1759. TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothCoherent) {
  1760. const std::string text = R"(
  1761. ; CHECK-DAG: [[queue:%\w+]] = OpConstant {{%\w+}} 5
  1762. ; CHECK-DAG: [[wg:%\w+]] = OpConstant {{%\w+}} 2
  1763. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[wg]] MakePointerVisible|NonPrivatePointer [[queue]]
  1764. OpCapability Shader
  1765. OpMemoryModel Logical GLSL450
  1766. OpEntryPoint GLCompute %func "func" %src %dst
  1767. OpDecorate %src Coherent
  1768. %void = OpTypeVoid
  1769. %int = OpTypeInt 32 0
  1770. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1771. %ptr_wg_int = OpTypePointer Workgroup %int
  1772. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1773. %dst = OpVariable %ptr_wg_int Workgroup
  1774. %void_fn = OpTypeFunction %void
  1775. %func = OpFunction %void None %void_fn
  1776. %entry = OpLabel
  1777. OpCopyMemory %dst %src
  1778. OpReturn
  1779. OpFunctionEnd
  1780. )";
  1781. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1782. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1783. }
  1784. TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothCoherentPreviousArgs) {
  1785. const std::string text = R"(
  1786. ; CHECK-DAG: [[queue:%\w+]] = OpConstant {{%\w+}} 5
  1787. ; CHECK-DAG: [[wg:%\w+]] = OpConstant {{%\w+}} 2
  1788. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailable|NonPrivatePointer 4 [[queue]] Aligned|MakePointerVisible|NonPrivatePointer 4 [[wg]]
  1789. OpCapability Shader
  1790. OpMemoryModel Logical GLSL450
  1791. OpEntryPoint GLCompute %func "func" %src %dst
  1792. OpDecorate %dst Coherent
  1793. %void = OpTypeVoid
  1794. %int = OpTypeInt 32 0
  1795. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1796. %ptr_wg_int = OpTypePointer Workgroup %int
  1797. %src = OpVariable %ptr_wg_int Workgroup
  1798. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1799. %void_fn = OpTypeFunction %void
  1800. %func = OpFunction %void None %void_fn
  1801. %entry = OpLabel
  1802. OpCopyMemory %dst %src Aligned 4
  1803. OpReturn
  1804. OpFunctionEnd
  1805. )";
  1806. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1807. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1808. }
  1809. TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothVolatile) {
  1810. const std::string text = R"(
  1811. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Volatile Volatile
  1812. OpCapability Shader
  1813. OpMemoryModel Logical GLSL450
  1814. OpEntryPoint GLCompute %func "func" %src %dst
  1815. OpDecorate %src Volatile
  1816. OpDecorate %dst Volatile
  1817. %void = OpTypeVoid
  1818. %int = OpTypeInt 32 0
  1819. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1820. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1821. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1822. %void_fn = OpTypeFunction %void
  1823. %func = OpFunction %void None %void_fn
  1824. %entry = OpLabel
  1825. OpCopyMemory %dst %src
  1826. OpReturn
  1827. OpFunctionEnd
  1828. )";
  1829. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1830. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1831. }
  1832. TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothVolatilePreviousArgs) {
  1833. const std::string text = R"(
  1834. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Volatile|Aligned 4 Volatile|Aligned 4
  1835. OpCapability Shader
  1836. OpMemoryModel Logical GLSL450
  1837. OpEntryPoint GLCompute %func "func" %src %dst
  1838. OpDecorate %src Volatile
  1839. OpDecorate %dst Volatile
  1840. %void = OpTypeVoid
  1841. %int = OpTypeInt 32 0
  1842. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1843. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1844. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1845. %void_fn = OpTypeFunction %void
  1846. %func = OpFunction %void None %void_fn
  1847. %entry = OpLabel
  1848. OpCopyMemory %dst %src Aligned 4
  1849. OpReturn
  1850. OpFunctionEnd
  1851. )";
  1852. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1853. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1854. }
  1855. TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryDstCoherentTwoOperands) {
  1856. const std::string text = R"(
  1857. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  1858. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]] None
  1859. OpCapability Shader
  1860. OpMemoryModel Logical GLSL450
  1861. OpEntryPoint GLCompute %func "func" %src %dst
  1862. OpDecorate %dst Coherent
  1863. %void = OpTypeVoid
  1864. %int = OpTypeInt 32 0
  1865. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1866. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1867. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1868. %void_fn = OpTypeFunction %void
  1869. %func = OpFunction %void None %void_fn
  1870. %entry = OpLabel
  1871. OpCopyMemory %dst %src None None
  1872. OpReturn
  1873. OpFunctionEnd
  1874. )";
  1875. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1876. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1877. }
  1878. TEST_F(UpgradeMemoryModelTest,
  1879. SPV14CopyMemoryDstCoherentPreviousArgsTwoOperands) {
  1880. const std::string text = R"(
  1881. ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
  1882. ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailable|NonPrivatePointer 4 [[scope]] Aligned 8
  1883. OpCapability Shader
  1884. OpMemoryModel Logical GLSL450
  1885. OpEntryPoint GLCompute %func "func" %src %dst
  1886. OpDecorate %dst Coherent
  1887. %void = OpTypeVoid
  1888. %int = OpTypeInt 32 0
  1889. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1890. %src = OpVariable %ptr_ssbo_int StorageBuffer
  1891. %dst = OpVariable %ptr_ssbo_int StorageBuffer
  1892. %void_fn = OpTypeFunction %void
  1893. %func = OpFunction %void None %void_fn
  1894. %entry = OpLabel
  1895. OpCopyMemory %dst %src Aligned 4 Aligned 8
  1896. OpReturn
  1897. OpFunctionEnd
  1898. )";
  1899. SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
  1900. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1901. }
  1902. TEST_F(UpgradeMemoryModelTest, VolatileAtomicLoad) {
  1903. const std::string text = R"(
  1904. ; CHECK-NOT: OpDecorate {{.*}} Volatile
  1905. ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32768
  1906. ; CHECK: OpAtomicLoad [[int]] {{.*}} {{.*}} [[volatile]]
  1907. OpCapability Shader
  1908. OpCapability Linkage
  1909. OpMemoryModel Logical GLSL450
  1910. OpDecorate %ssbo_var Volatile
  1911. %void = OpTypeVoid
  1912. %int = OpTypeInt 32 0
  1913. %device = OpConstant %int 1
  1914. %relaxed = OpConstant %int 0
  1915. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1916. %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
  1917. %void_fn = OpTypeFunction %void
  1918. %func = OpFunction %void None %void_fn
  1919. %entry = OpLabel
  1920. %ld = OpAtomicLoad %int %ssbo_var %device %relaxed
  1921. OpReturn
  1922. OpFunctionEnd
  1923. )";
  1924. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1925. }
  1926. TEST_F(UpgradeMemoryModelTest, VolatileAtomicLoadPreviousFlags) {
  1927. const std::string text = R"(
  1928. ; CHECK-NOT: OpDecorate {{.*}} Volatile
  1929. ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32834
  1930. ; CHECK: OpAtomicLoad [[int]] {{.*}} {{.*}} [[volatile]]
  1931. OpCapability Shader
  1932. OpCapability Linkage
  1933. OpMemoryModel Logical GLSL450
  1934. OpDecorate %ssbo_var Volatile
  1935. %void = OpTypeVoid
  1936. %int = OpTypeInt 32 0
  1937. %device = OpConstant %int 1
  1938. %acquire_ssbo = OpConstant %int 66
  1939. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1940. %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
  1941. %void_fn = OpTypeFunction %void
  1942. %func = OpFunction %void None %void_fn
  1943. %entry = OpLabel
  1944. %ld = OpAtomicLoad %int %ssbo_var %device %acquire_ssbo
  1945. OpReturn
  1946. OpFunctionEnd
  1947. )";
  1948. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1949. }
  1950. TEST_F(UpgradeMemoryModelTest, VolatileAtomicStore) {
  1951. const std::string text = R"(
  1952. ; CHECK-NOT: OpDecorate {{.*}} Volatile
  1953. ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant {{.*}} 32768
  1954. ; CHECK: OpAtomicStore {{.*}} {{.*}} [[volatile]]
  1955. OpCapability Shader
  1956. OpCapability Linkage
  1957. OpMemoryModel Logical GLSL450
  1958. OpDecorate %ssbo_var Volatile
  1959. %void = OpTypeVoid
  1960. %int = OpTypeInt 32 0
  1961. %int_0 = OpConstant %int 0
  1962. %device = OpConstant %int 1
  1963. %relaxed = OpConstant %int 0
  1964. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1965. %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
  1966. %void_fn = OpTypeFunction %void
  1967. %func = OpFunction %void None %void_fn
  1968. %entry = OpLabel
  1969. OpAtomicStore %ssbo_var %device %relaxed %int_0
  1970. OpReturn
  1971. OpFunctionEnd
  1972. )";
  1973. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1974. }
  1975. TEST_F(UpgradeMemoryModelTest, VolatileAtomicStorePreviousFlags) {
  1976. const std::string text = R"(
  1977. ; CHECK-NOT: OpDecorate {{.*}} Volatile
  1978. ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant {{.*}} 32836
  1979. ; CHECK: OpAtomicStore {{.*}} {{.*}} [[volatile]]
  1980. OpCapability Shader
  1981. OpCapability Linkage
  1982. OpMemoryModel Logical GLSL450
  1983. OpDecorate %ssbo_var Volatile
  1984. %void = OpTypeVoid
  1985. %int = OpTypeInt 32 0
  1986. %int_0 = OpConstant %int 0
  1987. %device = OpConstant %int 1
  1988. %release_ssbo = OpConstant %int 68
  1989. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  1990. %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
  1991. %void_fn = OpTypeFunction %void
  1992. %func = OpFunction %void None %void_fn
  1993. %entry = OpLabel
  1994. OpAtomicStore %ssbo_var %device %release_ssbo %int_0
  1995. OpReturn
  1996. OpFunctionEnd
  1997. )";
  1998. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  1999. }
  2000. TEST_F(UpgradeMemoryModelTest, VolatileAtomicCompareExchange) {
  2001. const std::string text = R"(
  2002. ; CHECK-NOT: OpDecorate {{.*}} Volatile
  2003. ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32768
  2004. ; CHECK: OpAtomicCompareExchange [[int]] {{.*}} {{.*}} [[volatile]] [[volatile]]
  2005. OpCapability Shader
  2006. OpCapability Linkage
  2007. OpMemoryModel Logical GLSL450
  2008. OpDecorate %ssbo_var Volatile
  2009. %void = OpTypeVoid
  2010. %int = OpTypeInt 32 0
  2011. %int_0 = OpConstant %int 0
  2012. %int_1 = OpConstant %int 1
  2013. %device = OpConstant %int 1
  2014. %relaxed = OpConstant %int 0
  2015. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  2016. %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
  2017. %void_fn = OpTypeFunction %void
  2018. %func = OpFunction %void None %void_fn
  2019. %entry = OpLabel
  2020. %ld = OpAtomicCompareExchange %int %ssbo_var %device %relaxed %relaxed %int_0 %int_1
  2021. OpReturn
  2022. OpFunctionEnd
  2023. )";
  2024. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  2025. }
  2026. TEST_F(UpgradeMemoryModelTest, VolatileAtomicCompareExchangePreviousFlags) {
  2027. const std::string text = R"(
  2028. ; CHECK-NOT: OpDecorate {{.*}} Volatile
  2029. ; CHECK: [[volatile_acq_rel:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32840
  2030. ; CHECK: [[volatile_acq:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32834
  2031. ; CHECK: OpAtomicCompareExchange [[int]] {{.*}} {{.*}} [[volatile_acq_rel]] [[volatile_acq]]
  2032. OpCapability Shader
  2033. OpCapability Linkage
  2034. OpMemoryModel Logical GLSL450
  2035. OpDecorate %ssbo_var Volatile
  2036. %void = OpTypeVoid
  2037. %int = OpTypeInt 32 0
  2038. %int_0 = OpConstant %int 0
  2039. %int_1 = OpConstant %int 1
  2040. %device = OpConstant %int 1
  2041. %acq_ssbo = OpConstant %int 66
  2042. %acq_rel_ssbo = OpConstant %int 72
  2043. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  2044. %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
  2045. %void_fn = OpTypeFunction %void
  2046. %func = OpFunction %void None %void_fn
  2047. %entry = OpLabel
  2048. %ld = OpAtomicCompareExchange %int %ssbo_var %device %acq_rel_ssbo %acq_ssbo %int_0 %int_1
  2049. OpReturn
  2050. OpFunctionEnd
  2051. )";
  2052. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  2053. }
  2054. TEST_F(UpgradeMemoryModelTest, VolatileAtomicLoadMemberDecoration) {
  2055. const std::string text = R"(
  2056. ; CHECK-NOT: OpMemberDecorate {{.*}} {{.*}} Volatile
  2057. ; CHECK: [[relaxed:%[a-zA-Z0-9_]+]] = OpConstant {{.*}} 0
  2058. ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32768
  2059. ; CHECK: OpAtomicLoad [[int]] {{.*}} {{.*}} [[relaxed]]
  2060. ; CHECK: OpAtomicLoad [[int]] {{.*}} {{.*}} [[volatile]]
  2061. OpCapability Shader
  2062. OpCapability Linkage
  2063. OpMemoryModel Logical GLSL450
  2064. OpMemberDecorate %struct 1 Volatile
  2065. %void = OpTypeVoid
  2066. %int = OpTypeInt 32 0
  2067. %device = OpConstant %int 1
  2068. %relaxed = OpConstant %int 0
  2069. %int_0 = OpConstant %int 0
  2070. %int_1 = OpConstant %int 1
  2071. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  2072. %struct = OpTypeStruct %int %int
  2073. %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
  2074. %ssbo_var = OpVariable %ptr_ssbo_struct StorageBuffer
  2075. %void_fn = OpTypeFunction %void
  2076. %func = OpFunction %void None %void_fn
  2077. %entry = OpLabel
  2078. %gep0 = OpAccessChain %ptr_ssbo_int %ssbo_var %int_0
  2079. %ld0 = OpAtomicLoad %int %gep0 %device %relaxed
  2080. %gep1 = OpAccessChain %ptr_ssbo_int %ssbo_var %int_1
  2081. %ld1 = OpAtomicLoad %int %gep1 %device %relaxed
  2082. OpReturn
  2083. OpFunctionEnd
  2084. )";
  2085. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  2086. }
  2087. TEST_F(UpgradeMemoryModelTest, CoherentStructMemberInArray) {
  2088. const std::string text = R"(
  2089. ; CHECK-NOT: OpMemberDecorate
  2090. ; CHECK: [[int:%[a-zA-Z0-9_]+]] = OpTypeInt 32 0
  2091. ; CHECK: [[device:%[a-zA-Z0-9_]+]] = OpConstant [[int]] 1
  2092. ; CHECK: OpLoad [[int]] {{.*}} MakePointerVisible|NonPrivatePointer
  2093. OpCapability Shader
  2094. OpCapability Linkage
  2095. OpMemoryModel Logical GLSL450
  2096. OpMemberDecorate %inner 1 Coherent
  2097. %void = OpTypeVoid
  2098. %int = OpTypeInt 32 0
  2099. %int_0 = OpConstant %int 0
  2100. %int_1 = OpConstant %int 1
  2101. %int_4 = OpConstant %int 4
  2102. %inner = OpTypeStruct %int %int
  2103. %array = OpTypeArray %inner %int_4
  2104. %struct = OpTypeStruct %array
  2105. %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
  2106. %ptr_ssbo_int = OpTypePointer StorageBuffer %int
  2107. %ssbo_var = OpVariable %ptr_ssbo_struct StorageBuffer
  2108. %void_fn = OpTypeFunction %void
  2109. %func = OpFunction %void None %void_fn
  2110. %entry = OpLabel
  2111. %gep = OpAccessChain %ptr_ssbo_int %ssbo_var %int_0 %int_0 %int_1
  2112. %ld = OpLoad %int %gep
  2113. OpReturn
  2114. OpFunctionEnd
  2115. )";
  2116. SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
  2117. }
  2118. } // namespace