local_single_block_elim.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557
  1. // Copyright (c) 2017 Valve Corporation
  2. // Copyright (c) 2017 LunarG Inc.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. #include <string>
  16. #include "test/opt/pass_fixture.h"
  17. #include "test/opt/pass_utils.h"
  18. namespace spvtools {
  19. namespace opt {
  20. namespace {
  21. using LocalSingleBlockLoadStoreElimTest = PassTest<::testing::Test>;
  22. TEST_F(LocalSingleBlockLoadStoreElimTest, SimpleStoreLoadElim) {
  23. // #version 140
  24. //
  25. // in vec4 BaseColor;
  26. //
  27. // void main()
  28. // {
  29. // vec4 v = BaseColor;
  30. // gl_FragColor = v;
  31. // }
  32. const std::string predefs_before =
  33. R"(OpCapability Shader
  34. %1 = OpExtInstImport "GLSL.std.450"
  35. OpMemoryModel Logical GLSL450
  36. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  37. OpExecutionMode %main OriginUpperLeft
  38. OpSource GLSL 140
  39. OpName %main "main"
  40. OpName %v "v"
  41. OpName %BaseColor "BaseColor"
  42. OpName %gl_FragColor "gl_FragColor"
  43. %void = OpTypeVoid
  44. %7 = OpTypeFunction %void
  45. %float = OpTypeFloat 32
  46. %v4float = OpTypeVector %float 4
  47. %_ptr_Function_v4float = OpTypePointer Function %v4float
  48. %_ptr_Input_v4float = OpTypePointer Input %v4float
  49. %BaseColor = OpVariable %_ptr_Input_v4float Input
  50. %_ptr_Output_v4float = OpTypePointer Output %v4float
  51. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  52. )";
  53. const std::string before =
  54. R"(%main = OpFunction %void None %7
  55. %13 = OpLabel
  56. %v = OpVariable %_ptr_Function_v4float Function
  57. %14 = OpLoad %v4float %BaseColor
  58. OpStore %v %14
  59. %15 = OpLoad %v4float %v
  60. OpStore %gl_FragColor %15
  61. OpReturn
  62. OpFunctionEnd
  63. )";
  64. const std::string after =
  65. R"(%main = OpFunction %void None %7
  66. %13 = OpLabel
  67. %v = OpVariable %_ptr_Function_v4float Function
  68. %14 = OpLoad %v4float %BaseColor
  69. OpStore %v %14
  70. OpStore %gl_FragColor %14
  71. OpReturn
  72. OpFunctionEnd
  73. )";
  74. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  75. predefs_before + before, predefs_before + after, true, true);
  76. }
  77. TEST_F(LocalSingleBlockLoadStoreElimTest, LSBElimForLinkage) {
  78. const std::string predefs_before =
  79. R"(OpCapability Shader
  80. OpCapability Linkage
  81. %1 = OpExtInstImport "GLSL.std.450"
  82. OpMemoryModel Logical GLSL450
  83. OpSource HLSL 630
  84. OpName %main "main"
  85. OpName %v "v"
  86. OpName %BaseColor "BaseColor"
  87. OpName %gl_FragColor "gl_FragColor"
  88. OpDecorate %main LinkageAttributes "main" Export
  89. %void = OpTypeVoid
  90. %7 = OpTypeFunction %void
  91. %float = OpTypeFloat 32
  92. %v4float = OpTypeVector %float 4
  93. %_ptr_Function_v4float = OpTypePointer Function %v4float
  94. %_ptr_Input_v4float = OpTypePointer Input %v4float
  95. %BaseColor = OpVariable %_ptr_Input_v4float Input
  96. %_ptr_Output_v4float = OpTypePointer Output %v4float
  97. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  98. )";
  99. const std::string before =
  100. R"(%main = OpFunction %void None %7
  101. %13 = OpLabel
  102. %v = OpVariable %_ptr_Function_v4float Function
  103. %14 = OpLoad %v4float %BaseColor
  104. OpStore %v %14
  105. %15 = OpLoad %v4float %v
  106. OpStore %gl_FragColor %15
  107. OpReturn
  108. OpFunctionEnd
  109. )";
  110. const std::string after =
  111. R"(%main = OpFunction %void None %7
  112. %13 = OpLabel
  113. %v = OpVariable %_ptr_Function_v4float Function
  114. %14 = OpLoad %v4float %BaseColor
  115. OpStore %v %14
  116. OpStore %gl_FragColor %14
  117. OpReturn
  118. OpFunctionEnd
  119. )";
  120. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  121. predefs_before + before, predefs_before + after, true, true);
  122. }
  123. TEST_F(LocalSingleBlockLoadStoreElimTest, SimpleLoadLoadElim) {
  124. // #version 140
  125. //
  126. // in vec4 BaseColor;
  127. // in float fi;
  128. //
  129. // void main()
  130. // {
  131. // vec4 v = BaseColor;
  132. // if (fi < 0)
  133. // v = vec4(0.0);
  134. // gl_FragData[0] = v;
  135. // gl_FragData[1] = v;
  136. // }
  137. const std::string predefs =
  138. R"(OpCapability Shader
  139. %1 = OpExtInstImport "GLSL.std.450"
  140. OpMemoryModel Logical GLSL450
  141. OpEntryPoint Fragment %main "main" %BaseColor %fi %gl_FragData
  142. OpExecutionMode %main OriginUpperLeft
  143. OpSource GLSL 140
  144. OpName %main "main"
  145. OpName %v "v"
  146. OpName %BaseColor "BaseColor"
  147. OpName %fi "fi"
  148. OpName %gl_FragData "gl_FragData"
  149. %void = OpTypeVoid
  150. %8 = OpTypeFunction %void
  151. %float = OpTypeFloat 32
  152. %v4float = OpTypeVector %float 4
  153. %_ptr_Function_v4float = OpTypePointer Function %v4float
  154. %_ptr_Input_v4float = OpTypePointer Input %v4float
  155. %BaseColor = OpVariable %_ptr_Input_v4float Input
  156. %_ptr_Input_float = OpTypePointer Input %float
  157. %fi = OpVariable %_ptr_Input_float Input
  158. %float_0 = OpConstant %float 0
  159. %bool = OpTypeBool
  160. %16 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  161. %uint = OpTypeInt 32 0
  162. %uint_32 = OpConstant %uint 32
  163. %_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32
  164. %_ptr_Output__arr_v4float_uint_32 = OpTypePointer Output %_arr_v4float_uint_32
  165. %gl_FragData = OpVariable %_ptr_Output__arr_v4float_uint_32 Output
  166. %int = OpTypeInt 32 1
  167. %int_0 = OpConstant %int 0
  168. %_ptr_Output_v4float = OpTypePointer Output %v4float
  169. %int_1 = OpConstant %int 1
  170. )";
  171. const std::string before =
  172. R"(%main = OpFunction %void None %8
  173. %25 = OpLabel
  174. %v = OpVariable %_ptr_Function_v4float Function
  175. %26 = OpLoad %v4float %BaseColor
  176. OpStore %v %26
  177. %27 = OpLoad %float %fi
  178. %28 = OpFOrdLessThan %bool %27 %float_0
  179. OpSelectionMerge %29 None
  180. OpBranchConditional %28 %30 %29
  181. %30 = OpLabel
  182. OpStore %v %16
  183. OpBranch %29
  184. %29 = OpLabel
  185. %31 = OpLoad %v4float %v
  186. %32 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
  187. OpStore %32 %31
  188. %33 = OpLoad %v4float %v
  189. %34 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
  190. OpStore %34 %33
  191. OpReturn
  192. OpFunctionEnd
  193. )";
  194. const std::string after =
  195. R"(%main = OpFunction %void None %8
  196. %25 = OpLabel
  197. %v = OpVariable %_ptr_Function_v4float Function
  198. %26 = OpLoad %v4float %BaseColor
  199. OpStore %v %26
  200. %27 = OpLoad %float %fi
  201. %28 = OpFOrdLessThan %bool %27 %float_0
  202. OpSelectionMerge %29 None
  203. OpBranchConditional %28 %30 %29
  204. %30 = OpLabel
  205. OpStore %v %16
  206. OpBranch %29
  207. %29 = OpLabel
  208. %31 = OpLoad %v4float %v
  209. %32 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
  210. OpStore %32 %31
  211. %34 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
  212. OpStore %34 %31
  213. OpReturn
  214. OpFunctionEnd
  215. )";
  216. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  217. predefs + before, predefs + after, true, true);
  218. }
  219. TEST_F(LocalSingleBlockLoadStoreElimTest, StoreStoreElim) {
  220. //
  221. // Note first store to v is eliminated
  222. //
  223. // #version 450
  224. //
  225. // layout(location = 0) in vec4 BaseColor;
  226. // layout(location = 0) out vec4 OutColor;
  227. //
  228. // void main()
  229. // {
  230. // vec4 v = BaseColor;
  231. // v = v * 0.5;
  232. // OutColor = v;
  233. // }
  234. const std::string predefs_before =
  235. R"(OpCapability Shader
  236. %1 = OpExtInstImport "GLSL.std.450"
  237. OpMemoryModel Logical GLSL450
  238. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  239. OpExecutionMode %main OriginUpperLeft
  240. OpSource GLSL 450
  241. OpName %main "main"
  242. OpName %v "v"
  243. OpName %BaseColor "BaseColor"
  244. OpName %OutColor "OutColor"
  245. OpDecorate %BaseColor Location 0
  246. OpDecorate %OutColor Location 0
  247. %void = OpTypeVoid
  248. %7 = OpTypeFunction %void
  249. %float = OpTypeFloat 32
  250. %v4float = OpTypeVector %float 4
  251. %_ptr_Function_v4float = OpTypePointer Function %v4float
  252. %_ptr_Input_v4float = OpTypePointer Input %v4float
  253. %BaseColor = OpVariable %_ptr_Input_v4float Input
  254. %float_0_5 = OpConstant %float 0.5
  255. %_ptr_Output_v4float = OpTypePointer Output %v4float
  256. %OutColor = OpVariable %_ptr_Output_v4float Output
  257. )";
  258. const std::string before =
  259. R"(%main = OpFunction %void None %7
  260. %14 = OpLabel
  261. %v = OpVariable %_ptr_Function_v4float Function
  262. %15 = OpLoad %v4float %BaseColor
  263. OpStore %v %15
  264. %16 = OpLoad %v4float %v
  265. %17 = OpVectorTimesScalar %v4float %16 %float_0_5
  266. OpStore %v %17
  267. %18 = OpLoad %v4float %v
  268. OpStore %OutColor %18
  269. OpReturn
  270. OpFunctionEnd
  271. )";
  272. const std::string after =
  273. R"(%main = OpFunction %void None %7
  274. %14 = OpLabel
  275. %v = OpVariable %_ptr_Function_v4float Function
  276. %15 = OpLoad %v4float %BaseColor
  277. %17 = OpVectorTimesScalar %v4float %15 %float_0_5
  278. OpStore %v %17
  279. OpStore %OutColor %17
  280. OpReturn
  281. OpFunctionEnd
  282. )";
  283. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  284. predefs_before + before, predefs_before + after, true, true);
  285. }
  286. TEST_F(LocalSingleBlockLoadStoreElimTest,
  287. NoStoreElimIfInterveningAccessChainLoad) {
  288. //
  289. // Note the first Store to %v is not eliminated due to the following access
  290. // chain reference.
  291. //
  292. // #version 450
  293. //
  294. // layout(location = 0) in vec4 BaseColor0;
  295. // layout(location = 1) in vec4 BaseColor1;
  296. // layout(location = 2) flat in int Idx;
  297. // layout(location = 0) out vec4 OutColor;
  298. //
  299. // void main()
  300. // {
  301. // vec4 v = BaseColor0;
  302. // float f = v[Idx];
  303. // v = BaseColor1 + vec4(0.1);
  304. // OutColor = v/f;
  305. // }
  306. const std::string predefs =
  307. R"(OpCapability Shader
  308. %1 = OpExtInstImport "GLSL.std.450"
  309. OpMemoryModel Logical GLSL450
  310. OpEntryPoint Fragment %main "main" %BaseColor0 %Idx %BaseColor1 %OutColor
  311. OpExecutionMode %main OriginUpperLeft
  312. OpSource GLSL 450
  313. OpName %main "main"
  314. OpName %v "v"
  315. OpName %BaseColor0 "BaseColor0"
  316. OpName %f "f"
  317. OpName %Idx "Idx"
  318. OpName %BaseColor1 "BaseColor1"
  319. OpName %OutColor "OutColor"
  320. OpDecorate %BaseColor0 Location 0
  321. OpDecorate %Idx Flat
  322. OpDecorate %Idx Location 2
  323. OpDecorate %BaseColor1 Location 1
  324. OpDecorate %OutColor Location 0
  325. %void = OpTypeVoid
  326. %10 = OpTypeFunction %void
  327. %float = OpTypeFloat 32
  328. %v4float = OpTypeVector %float 4
  329. %_ptr_Function_v4float = OpTypePointer Function %v4float
  330. %_ptr_Input_v4float = OpTypePointer Input %v4float
  331. %BaseColor0 = OpVariable %_ptr_Input_v4float Input
  332. %_ptr_Function_float = OpTypePointer Function %float
  333. %int = OpTypeInt 32 1
  334. %_ptr_Input_int = OpTypePointer Input %int
  335. %Idx = OpVariable %_ptr_Input_int Input
  336. %BaseColor1 = OpVariable %_ptr_Input_v4float Input
  337. %float_0_100000001 = OpConstant %float 0.100000001
  338. %19 = OpConstantComposite %v4float %float_0_100000001 %float_0_100000001 %float_0_100000001 %float_0_100000001
  339. %_ptr_Output_v4float = OpTypePointer Output %v4float
  340. %OutColor = OpVariable %_ptr_Output_v4float Output
  341. )";
  342. const std::string before =
  343. R"(%main = OpFunction %void None %10
  344. %21 = OpLabel
  345. %v = OpVariable %_ptr_Function_v4float Function
  346. %f = OpVariable %_ptr_Function_float Function
  347. %22 = OpLoad %v4float %BaseColor0
  348. OpStore %v %22
  349. %23 = OpLoad %int %Idx
  350. %24 = OpAccessChain %_ptr_Function_float %v %23
  351. %25 = OpLoad %float %24
  352. OpStore %f %25
  353. %26 = OpLoad %v4float %BaseColor1
  354. %27 = OpFAdd %v4float %26 %19
  355. OpStore %v %27
  356. %28 = OpLoad %v4float %v
  357. %29 = OpLoad %float %f
  358. %30 = OpCompositeConstruct %v4float %29 %29 %29 %29
  359. %31 = OpFDiv %v4float %28 %30
  360. OpStore %OutColor %31
  361. OpReturn
  362. OpFunctionEnd
  363. )";
  364. const std::string after =
  365. R"(%main = OpFunction %void None %10
  366. %21 = OpLabel
  367. %v = OpVariable %_ptr_Function_v4float Function
  368. %f = OpVariable %_ptr_Function_float Function
  369. %22 = OpLoad %v4float %BaseColor0
  370. OpStore %v %22
  371. %23 = OpLoad %int %Idx
  372. %24 = OpAccessChain %_ptr_Function_float %v %23
  373. %25 = OpLoad %float %24
  374. OpStore %f %25
  375. %26 = OpLoad %v4float %BaseColor1
  376. %27 = OpFAdd %v4float %26 %19
  377. OpStore %v %27
  378. %30 = OpCompositeConstruct %v4float %25 %25 %25 %25
  379. %31 = OpFDiv %v4float %27 %30
  380. OpStore %OutColor %31
  381. OpReturn
  382. OpFunctionEnd
  383. )";
  384. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  385. predefs + before, predefs + after, true, true);
  386. }
  387. TEST_F(LocalSingleBlockLoadStoreElimTest, NoElimIfInterveningAccessChainStore) {
  388. // #version 140
  389. //
  390. // in vec4 BaseColor;
  391. // flat in int Idx;
  392. //
  393. // void main()
  394. // {
  395. // vec4 v = BaseColor;
  396. // v[Idx] = 0;
  397. // gl_FragColor = v;
  398. // }
  399. const std::string assembly =
  400. R"(OpCapability Shader
  401. %1 = OpExtInstImport "GLSL.std.450"
  402. OpMemoryModel Logical GLSL450
  403. OpEntryPoint Fragment %main "main" %BaseColor %Idx %gl_FragColor
  404. OpExecutionMode %main OriginUpperLeft
  405. OpSource GLSL 140
  406. OpName %main "main"
  407. OpName %v "v"
  408. OpName %BaseColor "BaseColor"
  409. OpName %Idx "Idx"
  410. OpName %gl_FragColor "gl_FragColor"
  411. OpDecorate %Idx Flat
  412. %void = OpTypeVoid
  413. %8 = OpTypeFunction %void
  414. %float = OpTypeFloat 32
  415. %v4float = OpTypeVector %float 4
  416. %_ptr_Function_v4float = OpTypePointer Function %v4float
  417. %_ptr_Input_v4float = OpTypePointer Input %v4float
  418. %BaseColor = OpVariable %_ptr_Input_v4float Input
  419. %int = OpTypeInt 32 1
  420. %_ptr_Input_int = OpTypePointer Input %int
  421. %Idx = OpVariable %_ptr_Input_int Input
  422. %float_0 = OpConstant %float 0
  423. %_ptr_Function_float = OpTypePointer Function %float
  424. %_ptr_Output_v4float = OpTypePointer Output %v4float
  425. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  426. %main = OpFunction %void None %8
  427. %18 = OpLabel
  428. %v = OpVariable %_ptr_Function_v4float Function
  429. %19 = OpLoad %v4float %BaseColor
  430. OpStore %v %19
  431. %20 = OpLoad %int %Idx
  432. %21 = OpAccessChain %_ptr_Function_float %v %20
  433. OpStore %21 %float_0
  434. %22 = OpLoad %v4float %v
  435. OpStore %gl_FragColor %22
  436. OpReturn
  437. OpFunctionEnd
  438. )";
  439. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(assembly, assembly,
  440. false, true);
  441. }
  442. TEST_F(LocalSingleBlockLoadStoreElimTest, NoElimIfInterveningFunctionCall) {
  443. // #version 140
  444. //
  445. // in vec4 BaseColor;
  446. //
  447. // void foo() {
  448. // }
  449. //
  450. // void main()
  451. // {
  452. // vec4 v = BaseColor;
  453. // foo();
  454. // gl_FragColor = v;
  455. // }
  456. const std::string assembly =
  457. R"(OpCapability Shader
  458. %1 = OpExtInstImport "GLSL.std.450"
  459. OpMemoryModel Logical GLSL450
  460. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  461. OpExecutionMode %main OriginUpperLeft
  462. OpSource GLSL 140
  463. OpName %main "main"
  464. OpName %foo_ "foo("
  465. OpName %v "v"
  466. OpName %BaseColor "BaseColor"
  467. OpName %gl_FragColor "gl_FragColor"
  468. %void = OpTypeVoid
  469. %8 = OpTypeFunction %void
  470. %float = OpTypeFloat 32
  471. %v4float = OpTypeVector %float 4
  472. %_ptr_Function_v4float = OpTypePointer Function %v4float
  473. %_ptr_Input_v4float = OpTypePointer Input %v4float
  474. %BaseColor = OpVariable %_ptr_Input_v4float Input
  475. %_ptr_Output_v4float = OpTypePointer Output %v4float
  476. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  477. %main = OpFunction %void None %8
  478. %14 = OpLabel
  479. %v = OpVariable %_ptr_Function_v4float Function
  480. %15 = OpLoad %v4float %BaseColor
  481. OpStore %v %15
  482. %16 = OpFunctionCall %void %foo_
  483. %17 = OpLoad %v4float %v
  484. OpStore %gl_FragColor %17
  485. OpReturn
  486. OpFunctionEnd
  487. %foo_ = OpFunction %void None %8
  488. %18 = OpLabel
  489. OpReturn
  490. OpFunctionEnd
  491. )";
  492. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(assembly, assembly,
  493. false, true);
  494. }
  495. TEST_F(LocalSingleBlockLoadStoreElimTest, ElimIfCopyObjectInFunction) {
  496. // Note: SPIR-V hand edited to insert CopyObject
  497. //
  498. // #version 140
  499. //
  500. // in vec4 BaseColor;
  501. //
  502. // void main()
  503. // {
  504. // vec4 v1 = BaseColor;
  505. // gl_FragData[0] = v1;
  506. // vec4 v2 = BaseColor * 0.5;
  507. // gl_FragData[1] = v2;
  508. // }
  509. const std::string predefs =
  510. R"(OpCapability Shader
  511. %1 = OpExtInstImport "GLSL.std.450"
  512. OpMemoryModel Logical GLSL450
  513. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragData
  514. OpExecutionMode %main OriginUpperLeft
  515. OpSource GLSL 140
  516. OpName %main "main"
  517. OpName %v1 "v1"
  518. OpName %BaseColor "BaseColor"
  519. OpName %gl_FragData "gl_FragData"
  520. OpName %v2 "v2"
  521. %void = OpTypeVoid
  522. %8 = OpTypeFunction %void
  523. %float = OpTypeFloat 32
  524. %v4float = OpTypeVector %float 4
  525. %_ptr_Function_v4float = OpTypePointer Function %v4float
  526. %_ptr_Input_v4float = OpTypePointer Input %v4float
  527. %BaseColor = OpVariable %_ptr_Input_v4float Input
  528. %uint = OpTypeInt 32 0
  529. %uint_32 = OpConstant %uint 32
  530. %_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32
  531. %_ptr_Output__arr_v4float_uint_32 = OpTypePointer Output %_arr_v4float_uint_32
  532. %gl_FragData = OpVariable %_ptr_Output__arr_v4float_uint_32 Output
  533. %int = OpTypeInt 32 1
  534. %int_0 = OpConstant %int 0
  535. %_ptr_Output_v4float = OpTypePointer Output %v4float
  536. %float_0_5 = OpConstant %float 0.5
  537. %int_1 = OpConstant %int 1
  538. )";
  539. const std::string before =
  540. R"(%main = OpFunction %void None %8
  541. %22 = OpLabel
  542. %v1 = OpVariable %_ptr_Function_v4float Function
  543. %v2 = OpVariable %_ptr_Function_v4float Function
  544. %23 = OpLoad %v4float %BaseColor
  545. OpStore %v1 %23
  546. %24 = OpLoad %v4float %v1
  547. %25 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
  548. OpStore %25 %24
  549. %26 = OpLoad %v4float %BaseColor
  550. %27 = OpVectorTimesScalar %v4float %26 %float_0_5
  551. %28 = OpCopyObject %_ptr_Function_v4float %v2
  552. OpStore %28 %27
  553. %29 = OpLoad %v4float %28
  554. %30 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
  555. OpStore %30 %29
  556. OpReturn
  557. OpFunctionEnd
  558. )";
  559. const std::string after =
  560. R"(%main = OpFunction %void None %8
  561. %22 = OpLabel
  562. %v1 = OpVariable %_ptr_Function_v4float Function
  563. %v2 = OpVariable %_ptr_Function_v4float Function
  564. %23 = OpLoad %v4float %BaseColor
  565. OpStore %v1 %23
  566. %25 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
  567. OpStore %25 %23
  568. %26 = OpLoad %v4float %BaseColor
  569. %27 = OpVectorTimesScalar %v4float %26 %float_0_5
  570. %28 = OpCopyObject %_ptr_Function_v4float %v2
  571. OpStore %28 %27
  572. %30 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
  573. OpStore %30 %27
  574. OpReturn
  575. OpFunctionEnd
  576. )";
  577. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  578. predefs + before, predefs + after, true, true);
  579. }
  580. TEST_F(LocalSingleBlockLoadStoreElimTest, ElimOpaque) {
  581. // SPIR-V not representable in GLSL; not generatable from HLSL
  582. // at the moment
  583. const std::string predefs =
  584. R"(OpCapability Shader
  585. %1 = OpExtInstImport "GLSL.std.450"
  586. OpMemoryModel Logical GLSL450
  587. OpEntryPoint Fragment %main "main" %outColor %texCoords
  588. OpExecutionMode %main OriginUpperLeft
  589. OpSource GLSL 140
  590. OpName %main "main"
  591. OpName %S_t "S_t"
  592. OpMemberName %S_t 0 "v0"
  593. OpMemberName %S_t 1 "v1"
  594. OpMemberName %S_t 2 "smp"
  595. OpName %outColor "outColor"
  596. OpName %sampler15 "sampler15"
  597. OpName %s0 "s0"
  598. OpName %texCoords "texCoords"
  599. OpName %param "param"
  600. OpDecorate %sampler15 DescriptorSet 0
  601. %void = OpTypeVoid
  602. %12 = OpTypeFunction %void
  603. %float = OpTypeFloat 32
  604. %v2float = OpTypeVector %float 2
  605. %v4float = OpTypeVector %float 4
  606. %_ptr_Output_v4float = OpTypePointer Output %v4float
  607. %outColor = OpVariable %_ptr_Output_v4float Output
  608. %17 = OpTypeImage %float 2D 0 0 0 1 Unknown
  609. %18 = OpTypeSampledImage %17
  610. %S_t = OpTypeStruct %v2float %v2float %18
  611. %_ptr_Function_S_t = OpTypePointer Function %S_t
  612. %20 = OpTypeFunction %void %_ptr_Function_S_t
  613. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  614. %_ptr_Function_18 = OpTypePointer Function %18
  615. %sampler15 = OpVariable %_ptr_UniformConstant_18 UniformConstant
  616. %int = OpTypeInt 32 1
  617. %int_0 = OpConstant %int 0
  618. %int_2 = OpConstant %int 2
  619. %_ptr_Function_v2float = OpTypePointer Function %v2float
  620. %_ptr_Input_v2float = OpTypePointer Input %v2float
  621. %texCoords = OpVariable %_ptr_Input_v2float Input
  622. )";
  623. const std::string before =
  624. R"(%main = OpFunction %void None %12
  625. %28 = OpLabel
  626. %s0 = OpVariable %_ptr_Function_S_t Function
  627. %param = OpVariable %_ptr_Function_S_t Function
  628. %29 = OpLoad %v2float %texCoords
  629. %30 = OpLoad %S_t %s0
  630. %31 = OpCompositeInsert %S_t %29 %30 0
  631. OpStore %s0 %31
  632. %32 = OpLoad %18 %sampler15
  633. %33 = OpLoad %S_t %s0
  634. %34 = OpCompositeInsert %S_t %32 %33 2
  635. OpStore %s0 %34
  636. %35 = OpLoad %S_t %s0
  637. OpStore %param %35
  638. %36 = OpLoad %S_t %param
  639. %37 = OpCompositeExtract %18 %36 2
  640. %38 = OpLoad %S_t %param
  641. %39 = OpCompositeExtract %v2float %38 0
  642. %40 = OpImageSampleImplicitLod %v4float %37 %39
  643. OpStore %outColor %40
  644. OpReturn
  645. OpFunctionEnd
  646. )";
  647. const std::string after =
  648. R"(%main = OpFunction %void None %12
  649. %28 = OpLabel
  650. %s0 = OpVariable %_ptr_Function_S_t Function
  651. %param = OpVariable %_ptr_Function_S_t Function
  652. %29 = OpLoad %v2float %texCoords
  653. %30 = OpLoad %S_t %s0
  654. %31 = OpCompositeInsert %S_t %29 %30 0
  655. %32 = OpLoad %18 %sampler15
  656. %34 = OpCompositeInsert %S_t %32 %31 2
  657. OpStore %s0 %34
  658. OpStore %param %34
  659. %37 = OpCompositeExtract %18 %34 2
  660. %39 = OpCompositeExtract %v2float %34 0
  661. %40 = OpImageSampleImplicitLod %v4float %37 %39
  662. OpStore %outColor %40
  663. OpReturn
  664. OpFunctionEnd
  665. )";
  666. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  667. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  668. predefs + before, predefs + after, true, true);
  669. }
  670. TEST_F(LocalSingleBlockLoadStoreElimTest, PositiveAndNegativeCallTree) {
  671. // Note that the call tree function bar is optimized, but foo is not
  672. //
  673. // #version 140
  674. //
  675. // in vec4 BaseColor;
  676. //
  677. // vec4 foo(vec4 v1)
  678. // {
  679. // vec4 t = v1;
  680. // return t;
  681. // }
  682. //
  683. // vec4 bar(vec4 v1)
  684. // {
  685. // vec4 t = v1;
  686. // return t;
  687. // }
  688. //
  689. // void main()
  690. // {
  691. // gl_FragColor = bar(BaseColor);
  692. // }
  693. const std::string predefs =
  694. R"(OpCapability Shader
  695. %1 = OpExtInstImport "GLSL.std.450"
  696. OpMemoryModel Logical GLSL450
  697. OpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor
  698. OpExecutionMode %main OriginUpperLeft
  699. OpSource GLSL 140
  700. OpName %main "main"
  701. OpName %foo_vf4_ "foo(vf4;"
  702. OpName %v1 "v1"
  703. OpName %bar_vf4_ "bar(vf4;"
  704. OpName %v1_0 "v1"
  705. OpName %t "t"
  706. OpName %t_0 "t"
  707. OpName %gl_FragColor "gl_FragColor"
  708. OpName %BaseColor "BaseColor"
  709. OpName %param "param"
  710. %void = OpTypeVoid
  711. %13 = OpTypeFunction %void
  712. %float = OpTypeFloat 32
  713. %v4float = OpTypeVector %float 4
  714. %_ptr_Function_v4float = OpTypePointer Function %v4float
  715. %17 = OpTypeFunction %v4float %_ptr_Function_v4float
  716. %_ptr_Output_v4float = OpTypePointer Output %v4float
  717. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  718. %_ptr_Input_v4float = OpTypePointer Input %v4float
  719. %BaseColor = OpVariable %_ptr_Input_v4float Input
  720. %main = OpFunction %void None %13
  721. %20 = OpLabel
  722. %param = OpVariable %_ptr_Function_v4float Function
  723. %21 = OpLoad %v4float %BaseColor
  724. OpStore %param %21
  725. %22 = OpFunctionCall %v4float %bar_vf4_ %param
  726. OpStore %gl_FragColor %22
  727. OpReturn
  728. OpFunctionEnd
  729. )";
  730. const std::string before =
  731. R"(%foo_vf4_ = OpFunction %v4float None %17
  732. %v1 = OpFunctionParameter %_ptr_Function_v4float
  733. %23 = OpLabel
  734. %t = OpVariable %_ptr_Function_v4float Function
  735. %24 = OpLoad %v4float %v1
  736. OpStore %t %24
  737. %25 = OpLoad %v4float %t
  738. OpReturnValue %25
  739. OpFunctionEnd
  740. %bar_vf4_ = OpFunction %v4float None %17
  741. %v1_0 = OpFunctionParameter %_ptr_Function_v4float
  742. %26 = OpLabel
  743. %t_0 = OpVariable %_ptr_Function_v4float Function
  744. %27 = OpLoad %v4float %v1_0
  745. OpStore %t_0 %27
  746. %28 = OpLoad %v4float %t_0
  747. OpReturnValue %28
  748. OpFunctionEnd
  749. )";
  750. const std::string after =
  751. R"(%foo_vf4_ = OpFunction %v4float None %17
  752. %v1 = OpFunctionParameter %_ptr_Function_v4float
  753. %23 = OpLabel
  754. %t = OpVariable %_ptr_Function_v4float Function
  755. %24 = OpLoad %v4float %v1
  756. OpStore %t %24
  757. %25 = OpLoad %v4float %t
  758. OpReturnValue %25
  759. OpFunctionEnd
  760. %bar_vf4_ = OpFunction %v4float None %17
  761. %v1_0 = OpFunctionParameter %_ptr_Function_v4float
  762. %26 = OpLabel
  763. %t_0 = OpVariable %_ptr_Function_v4float Function
  764. %27 = OpLoad %v4float %v1_0
  765. OpStore %t_0 %27
  766. OpReturnValue %27
  767. OpFunctionEnd
  768. )";
  769. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  770. predefs + before, predefs + after, true, true);
  771. }
  772. TEST_F(LocalSingleBlockLoadStoreElimTest, PointerVariable) {
  773. // Test that checks if a pointer variable is removed.
  774. const std::string before =
  775. R"(OpCapability Shader
  776. OpMemoryModel Logical GLSL450
  777. OpEntryPoint Fragment %1 "main" %2
  778. OpExecutionMode %1 OriginUpperLeft
  779. OpMemberDecorate %_struct_3 0 Offset 0
  780. OpDecorate %_runtimearr__struct_3 ArrayStride 16
  781. OpMemberDecorate %_struct_5 0 Offset 0
  782. OpDecorate %_struct_5 BufferBlock
  783. OpMemberDecorate %_struct_6 0 Offset 0
  784. OpDecorate %_struct_6 BufferBlock
  785. OpDecorate %2 Location 0
  786. OpDecorate %7 DescriptorSet 0
  787. OpDecorate %7 Binding 0
  788. %void = OpTypeVoid
  789. %10 = OpTypeFunction %void
  790. %int = OpTypeInt 32 1
  791. %uint = OpTypeInt 32 0
  792. %float = OpTypeFloat 32
  793. %v4float = OpTypeVector %float 4
  794. %_ptr_Output_v4float = OpTypePointer Output %v4float
  795. %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
  796. %_struct_3 = OpTypeStruct %v4float
  797. %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
  798. %_struct_5 = OpTypeStruct %_runtimearr__struct_3
  799. %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
  800. %_struct_6 = OpTypeStruct %int
  801. %_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
  802. %_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
  803. %_ptr_Function__ptr_Uniform__struct_6 = OpTypePointer Function %_ptr_Uniform__struct_6
  804. %int_0 = OpConstant %int 0
  805. %uint_0 = OpConstant %uint 0
  806. %2 = OpVariable %_ptr_Output_v4float Output
  807. %7 = OpVariable %_ptr_Uniform__struct_5 Uniform
  808. %1 = OpFunction %void None %10
  809. %23 = OpLabel
  810. %24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
  811. OpStore %24 %7
  812. %26 = OpLoad %_ptr_Uniform__struct_5 %24
  813. %27 = OpAccessChain %_ptr_Uniform_v4float %26 %int_0 %uint_0 %int_0
  814. %28 = OpLoad %v4float %27
  815. %29 = OpCopyObject %v4float %28
  816. OpStore %2 %28
  817. OpReturn
  818. OpFunctionEnd
  819. )";
  820. const std::string after =
  821. R"(OpCapability Shader
  822. OpMemoryModel Logical GLSL450
  823. OpEntryPoint Fragment %1 "main" %2
  824. OpExecutionMode %1 OriginUpperLeft
  825. OpMemberDecorate %_struct_3 0 Offset 0
  826. OpDecorate %_runtimearr__struct_3 ArrayStride 16
  827. OpMemberDecorate %_struct_5 0 Offset 0
  828. OpDecorate %_struct_5 BufferBlock
  829. OpMemberDecorate %_struct_6 0 Offset 0
  830. OpDecorate %_struct_6 BufferBlock
  831. OpDecorate %2 Location 0
  832. OpDecorate %7 DescriptorSet 0
  833. OpDecorate %7 Binding 0
  834. %void = OpTypeVoid
  835. %10 = OpTypeFunction %void
  836. %int = OpTypeInt 32 1
  837. %uint = OpTypeInt 32 0
  838. %float = OpTypeFloat 32
  839. %v4float = OpTypeVector %float 4
  840. %_ptr_Output_v4float = OpTypePointer Output %v4float
  841. %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
  842. %_struct_3 = OpTypeStruct %v4float
  843. %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
  844. %_struct_5 = OpTypeStruct %_runtimearr__struct_3
  845. %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
  846. %_struct_6 = OpTypeStruct %int
  847. %_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
  848. %_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
  849. %_ptr_Function__ptr_Uniform__struct_6 = OpTypePointer Function %_ptr_Uniform__struct_6
  850. %int_0 = OpConstant %int 0
  851. %uint_0 = OpConstant %uint 0
  852. %2 = OpVariable %_ptr_Output_v4float Output
  853. %7 = OpVariable %_ptr_Uniform__struct_5 Uniform
  854. %1 = OpFunction %void None %10
  855. %23 = OpLabel
  856. %24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
  857. OpStore %24 %7
  858. %27 = OpAccessChain %_ptr_Uniform_v4float %7 %int_0 %uint_0 %int_0
  859. %28 = OpLoad %v4float %27
  860. %29 = OpCopyObject %v4float %28
  861. OpStore %2 %28
  862. OpReturn
  863. OpFunctionEnd
  864. )";
  865. // Relax logical pointers to allow pointer allocations.
  866. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  867. ValidatorOptions()->relax_logical_pointer = true;
  868. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(before, after, true,
  869. true);
  870. }
  871. TEST_F(LocalSingleBlockLoadStoreElimTest, RedundantStore) {
  872. // Test that checks if a pointer variable is removed.
  873. const std::string predefs_before =
  874. R"(OpCapability Shader
  875. %1 = OpExtInstImport "GLSL.std.450"
  876. OpMemoryModel Logical GLSL450
  877. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  878. OpExecutionMode %main OriginUpperLeft
  879. OpSource GLSL 140
  880. OpName %main "main"
  881. OpName %v "v"
  882. OpName %BaseColor "BaseColor"
  883. OpName %gl_FragColor "gl_FragColor"
  884. %void = OpTypeVoid
  885. %7 = OpTypeFunction %void
  886. %float = OpTypeFloat 32
  887. %v4float = OpTypeVector %float 4
  888. %_ptr_Function_v4float = OpTypePointer Function %v4float
  889. %_ptr_Input_v4float = OpTypePointer Input %v4float
  890. %BaseColor = OpVariable %_ptr_Input_v4float Input
  891. %_ptr_Output_v4float = OpTypePointer Output %v4float
  892. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  893. )";
  894. const std::string before =
  895. R"(%main = OpFunction %void None %7
  896. %13 = OpLabel
  897. %v = OpVariable %_ptr_Function_v4float Function
  898. %14 = OpLoad %v4float %BaseColor
  899. OpStore %v %14
  900. OpBranch %16
  901. %16 = OpLabel
  902. %15 = OpLoad %v4float %v
  903. OpStore %v %15
  904. OpReturn
  905. OpFunctionEnd
  906. )";
  907. const std::string after =
  908. R"(%main = OpFunction %void None %7
  909. %13 = OpLabel
  910. %v = OpVariable %_ptr_Function_v4float Function
  911. %14 = OpLoad %v4float %BaseColor
  912. OpStore %v %14
  913. OpBranch %16
  914. %16 = OpLabel
  915. %15 = OpLoad %v4float %v
  916. OpReturn
  917. OpFunctionEnd
  918. )";
  919. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  920. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  921. predefs_before + before, predefs_before + after, true, true);
  922. }
  923. TEST_F(LocalSingleBlockLoadStoreElimTest, RedundantStore2) {
  924. // Test that checks if a pointer variable is removed.
  925. const std::string predefs_before =
  926. R"(OpCapability Shader
  927. %1 = OpExtInstImport "GLSL.std.450"
  928. OpMemoryModel Logical GLSL450
  929. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  930. OpExecutionMode %main OriginUpperLeft
  931. OpSource GLSL 140
  932. OpName %main "main"
  933. OpName %v "v"
  934. OpName %BaseColor "BaseColor"
  935. OpName %gl_FragColor "gl_FragColor"
  936. %void = OpTypeVoid
  937. %7 = OpTypeFunction %void
  938. %float = OpTypeFloat 32
  939. %v4float = OpTypeVector %float 4
  940. %_ptr_Function_v4float = OpTypePointer Function %v4float
  941. %_ptr_Input_v4float = OpTypePointer Input %v4float
  942. %BaseColor = OpVariable %_ptr_Input_v4float Input
  943. %_ptr_Output_v4float = OpTypePointer Output %v4float
  944. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  945. )";
  946. const std::string before =
  947. R"(%main = OpFunction %void None %7
  948. %13 = OpLabel
  949. %v = OpVariable %_ptr_Function_v4float Function
  950. %14 = OpLoad %v4float %BaseColor
  951. OpStore %v %14
  952. OpBranch %16
  953. %16 = OpLabel
  954. %15 = OpLoad %v4float %v
  955. OpStore %v %15
  956. %17 = OpLoad %v4float %v
  957. OpStore %v %17
  958. OpReturn
  959. OpFunctionEnd
  960. )";
  961. const std::string after =
  962. R"(%main = OpFunction %void None %7
  963. %13 = OpLabel
  964. %v = OpVariable %_ptr_Function_v4float Function
  965. %14 = OpLoad %v4float %BaseColor
  966. OpStore %v %14
  967. OpBranch %16
  968. %16 = OpLabel
  969. %15 = OpLoad %v4float %v
  970. OpReturn
  971. OpFunctionEnd
  972. )";
  973. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  974. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  975. predefs_before + before, predefs_before + after, true, true);
  976. }
  977. // Test that that an unused OpAccessChain between two store does does not
  978. // hinders the removal of the first store. We need to check this because
  979. // local-access-chain-convert does always remove the OpAccessChain instructions
  980. // that become dead.
  981. TEST_F(LocalSingleBlockLoadStoreElimTest,
  982. StoreElimIfInterveningUnusedAccessChain) {
  983. const std::string predefs =
  984. R"(OpCapability Shader
  985. %1 = OpExtInstImport "GLSL.std.450"
  986. OpMemoryModel Logical GLSL450
  987. OpEntryPoint Fragment %main "main" %BaseColor0 %Idx %BaseColor1 %OutColor
  988. OpExecutionMode %main OriginUpperLeft
  989. OpSource GLSL 450
  990. OpName %main "main"
  991. OpName %v "v"
  992. OpName %BaseColor0 "BaseColor0"
  993. OpName %Idx "Idx"
  994. OpName %BaseColor1 "BaseColor1"
  995. OpName %OutColor "OutColor"
  996. OpDecorate %BaseColor0 Location 0
  997. OpDecorate %Idx Flat
  998. OpDecorate %Idx Location 2
  999. OpDecorate %BaseColor1 Location 1
  1000. OpDecorate %OutColor Location 0
  1001. %void = OpTypeVoid
  1002. %10 = OpTypeFunction %void
  1003. %float = OpTypeFloat 32
  1004. %v4float = OpTypeVector %float 4
  1005. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1006. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1007. %BaseColor0 = OpVariable %_ptr_Input_v4float Input
  1008. %_ptr_Function_float = OpTypePointer Function %float
  1009. %int = OpTypeInt 32 1
  1010. %_ptr_Input_int = OpTypePointer Input %int
  1011. %Idx = OpVariable %_ptr_Input_int Input
  1012. %BaseColor1 = OpVariable %_ptr_Input_v4float Input
  1013. %float_0_100000001 = OpConstant %float 0.100000001
  1014. %19 = OpConstantComposite %v4float %float_0_100000001 %float_0_100000001 %float_0_100000001 %float_0_100000001
  1015. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1016. %OutColor = OpVariable %_ptr_Output_v4float Output
  1017. )";
  1018. const std::string before =
  1019. R"(%main = OpFunction %void None %10
  1020. %21 = OpLabel
  1021. %v = OpVariable %_ptr_Function_v4float Function
  1022. %22 = OpLoad %v4float %BaseColor0
  1023. OpStore %v %22
  1024. %23 = OpLoad %int %Idx
  1025. %24 = OpAccessChain %_ptr_Function_float %v %23
  1026. %26 = OpLoad %v4float %BaseColor1
  1027. %27 = OpFAdd %v4float %26 %19
  1028. OpStore %v %27
  1029. OpReturn
  1030. OpFunctionEnd
  1031. )";
  1032. const std::string after =
  1033. R"(%main = OpFunction %void None %10
  1034. %21 = OpLabel
  1035. %v = OpVariable %_ptr_Function_v4float Function
  1036. %22 = OpLoad %v4float %BaseColor0
  1037. %23 = OpLoad %int %Idx
  1038. %24 = OpAccessChain %_ptr_Function_float %v %23
  1039. %26 = OpLoad %v4float %BaseColor1
  1040. %27 = OpFAdd %v4float %26 %19
  1041. OpStore %v %27
  1042. OpReturn
  1043. OpFunctionEnd
  1044. )";
  1045. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1046. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  1047. predefs + before, predefs + after, true, true);
  1048. }
  1049. TEST_F(LocalSingleBlockLoadStoreElimTest, VariablePointerTest) {
  1050. // Check that the load of the first variable is still used and that the load
  1051. // of the third variable is propagated. The first load has to remain because
  1052. // of the store to the variable pointer.
  1053. const std::string text = R"(
  1054. ; CHECK: [[v1:%\w+]] = OpVariable
  1055. ; CHECK: [[v2:%\w+]] = OpVariable
  1056. ; CHECK: [[v3:%\w+]] = OpVariable
  1057. ; CHECK: [[phi:%\w+]] = OpPhi
  1058. ; CHECK: [[ld1:%\w+]] = OpLoad %int [[v1]]
  1059. ; CHECK: OpIAdd %int [[ld1]] %int_0
  1060. OpCapability Shader
  1061. OpCapability VariablePointers
  1062. %1 = OpExtInstImport "GLSL.std.450"
  1063. OpMemoryModel Logical GLSL450
  1064. OpEntryPoint GLCompute %2 "main"
  1065. OpExecutionMode %2 LocalSize 1 1 1
  1066. OpSource GLSL 450
  1067. OpMemberDecorate %_struct_3 0 Offset 0
  1068. OpMemberDecorate %_struct_3 1 Offset 4
  1069. %void = OpTypeVoid
  1070. %5 = OpTypeFunction %void
  1071. %int = OpTypeInt 32 1
  1072. %bool = OpTypeBool
  1073. %_struct_3 = OpTypeStruct %int %int
  1074. %_ptr_Function__struct_3 = OpTypePointer Function %_struct_3
  1075. %_ptr_Function_int = OpTypePointer Function %int
  1076. %true = OpConstantTrue %bool
  1077. %int_0 = OpConstant %int 0
  1078. %int_1 = OpConstant %int 1
  1079. %13 = OpConstantNull %_struct_3
  1080. %2 = OpFunction %void None %5
  1081. %14 = OpLabel
  1082. %15 = OpVariable %_ptr_Function_int Function
  1083. %16 = OpVariable %_ptr_Function_int Function
  1084. %17 = OpVariable %_ptr_Function_int Function
  1085. OpSelectionMerge %18 None
  1086. OpBranchConditional %true %19 %20
  1087. %19 = OpLabel
  1088. OpBranch %18
  1089. %20 = OpLabel
  1090. OpBranch %18
  1091. %18 = OpLabel
  1092. %21 = OpPhi %_ptr_Function_int %15 %19 %16 %20
  1093. OpStore %15 %int_1
  1094. OpStore %21 %int_0
  1095. %22 = OpLoad %int %15
  1096. OpStore %17 %int_0
  1097. %23 = OpLoad %int %17
  1098. %24 = OpIAdd %int %22 %23
  1099. OpReturn
  1100. OpFunctionEnd
  1101. )";
  1102. SinglePassRunAndMatch<LocalSingleBlockLoadStoreElimPass>(text, false);
  1103. }
  1104. TEST_F(LocalSingleBlockLoadStoreElimTest, DebugDeclareTest) {
  1105. // If OpenCL.DebugInfo.100 enabled, check that store/load is still
  1106. // optimized, but stores are not deleted for store/store.
  1107. //
  1108. // struct PS_INPUT {
  1109. // float4 c0 : COLOR0;
  1110. // float4 c1 : COLOR1;
  1111. // };
  1112. //
  1113. // struct PS_OUTPUT {
  1114. // float4 vColor : SV_Target0;
  1115. // };
  1116. //
  1117. // PS_OUTPUT MainPs(PS_INPUT i) {
  1118. // PS_OUTPUT ps_output;
  1119. // float4 c;
  1120. // c = i.c0;
  1121. // c += i.c1;
  1122. // c /= 2.0;
  1123. // ps_output.vColor = c;
  1124. // return ps_output;
  1125. // }
  1126. const std::string text = R"(
  1127. OpCapability Shader
  1128. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  1129. OpMemoryModel Logical GLSL450
  1130. OpEntryPoint Fragment %MainPs "MainPs" %in_var_COLOR0 %in_var_COLOR1 %out_var_SV_Target0
  1131. OpExecutionMode %MainPs OriginUpperLeft
  1132. %6 = OpString "foo3.frag"
  1133. %7 = OpString "PS_OUTPUT"
  1134. %8 = OpString "float"
  1135. %9 = OpString "vColor"
  1136. %10 = OpString "PS_INPUT"
  1137. %11 = OpString "c1"
  1138. %12 = OpString "c0"
  1139. %13 = OpString "src.MainPs"
  1140. %14 = OpString "c"
  1141. %15 = OpString "ps_output"
  1142. %16 = OpString "i"
  1143. OpName %in_var_COLOR0 "in.var.COLOR0"
  1144. OpName %in_var_COLOR1 "in.var.COLOR1"
  1145. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  1146. OpName %MainPs "MainPs"
  1147. OpName %PS_INPUT "PS_INPUT"
  1148. OpMemberName %PS_INPUT 0 "c0"
  1149. OpMemberName %PS_INPUT 1 "c1"
  1150. OpName %param_var_i "param.var.i"
  1151. OpName %PS_OUTPUT "PS_OUTPUT"
  1152. OpMemberName %PS_OUTPUT 0 "vColor"
  1153. OpName %src_MainPs "src.MainPs"
  1154. OpName %i "i"
  1155. OpName %bb_entry "bb.entry"
  1156. OpName %ps_output "ps_output"
  1157. OpName %c "c"
  1158. OpDecorate %in_var_COLOR0 Location 0
  1159. OpDecorate %in_var_COLOR1 Location 1
  1160. OpDecorate %out_var_SV_Target0 Location 0
  1161. %int = OpTypeInt 32 1
  1162. %int_0 = OpConstant %int 0
  1163. %int_1 = OpConstant %int 1
  1164. %float = OpTypeFloat 32
  1165. %float_2 = OpConstant %float 2
  1166. %v4float = OpTypeVector %float 4
  1167. %31 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
  1168. %uint = OpTypeInt 32 0
  1169. %uint_32 = OpConstant %uint 32
  1170. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1171. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1172. %void = OpTypeVoid
  1173. %uint_128 = OpConstant %uint 128
  1174. %uint_0 = OpConstant %uint 0
  1175. %uint_256 = OpConstant %uint 256
  1176. %40 = OpTypeFunction %void
  1177. %PS_INPUT = OpTypeStruct %v4float %v4float
  1178. %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
  1179. %PS_OUTPUT = OpTypeStruct %v4float
  1180. %42 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
  1181. %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
  1182. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1183. %in_var_COLOR0 = OpVariable %_ptr_Input_v4float Input
  1184. %in_var_COLOR1 = OpVariable %_ptr_Input_v4float Input
  1185. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  1186. %45 = OpExtInst %void %1 DebugSource %6
  1187. %46 = OpExtInst %void %1 DebugCompilationUnit 1 4 %45 HLSL
  1188. %47 = OpExtInst %void %1 DebugTypeComposite %7 Structure %45 8 1 %46 %7 %uint_128 FlagIsProtected|FlagIsPrivate %48
  1189. %49 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 Float
  1190. %50 = OpExtInst %void %1 DebugTypeVector %49 4
  1191. %48 = OpExtInst %void %1 DebugTypeMember %9 %50 %45 10 5 %47 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  1192. %51 = OpExtInst %void %1 DebugTypeComposite %10 Structure %45 2 1 %46 %10 %uint_256 FlagIsProtected|FlagIsPrivate %52 %53
  1193. %53 = OpExtInst %void %1 DebugTypeMember %11 %50 %45 5 5 %51 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
  1194. %52 = OpExtInst %void %1 DebugTypeMember %12 %50 %45 4 5 %51 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  1195. %54 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %47 %51
  1196. %55 = OpExtInst %void %1 DebugFunction %13 %54 %45 13 1 %46 %13 FlagIsProtected|FlagIsPrivate 14 %src_MainPs
  1197. %56 = OpExtInst %void %1 DebugLexicalBlock %45 14 1 %55
  1198. %57 = OpExtInst %void %1 DebugLocalVariable %14 %50 %45 16 12 %56 FlagIsLocal
  1199. %58 = OpExtInst %void %1 DebugLocalVariable %15 %47 %45 15 15 %56 FlagIsLocal
  1200. %59 = OpExtInst %void %1 DebugExpression
  1201. %60 = OpExtInst %void %1 DebugLocalVariable %16 %51 %45 13 29 %55 FlagIsLocal 1
  1202. %61 = OpExtInst %void %1 DebugLocalVariable %14 %50 %45 16 12 %55 FlagIsLocal 1
  1203. %MainPs = OpFunction %void None %40
  1204. %62 = OpLabel
  1205. %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
  1206. %63 = OpLoad %v4float %in_var_COLOR0
  1207. %64 = OpLoad %v4float %in_var_COLOR1
  1208. %65 = OpCompositeConstruct %PS_INPUT %63 %64
  1209. OpStore %param_var_i %65
  1210. %66 = OpFunctionCall %PS_OUTPUT %src_MainPs %param_var_i
  1211. %67 = OpCompositeExtract %v4float %66 0
  1212. OpStore %out_var_SV_Target0 %67
  1213. OpReturn
  1214. OpFunctionEnd
  1215. OpLine %6 13 1
  1216. %src_MainPs = OpFunction %PS_OUTPUT None %42
  1217. %83 = OpExtInst %void %1 DebugScope %55
  1218. OpLine %6 13 29
  1219. %i = OpFunctionParameter %_ptr_Function_PS_INPUT
  1220. %69 = OpExtInst %void %1 DebugDeclare %60 %i %59
  1221. %84 = OpExtInst %void %1 DebugNoScope
  1222. %bb_entry = OpLabel
  1223. %85 = OpExtInst %void %1 DebugScope %56
  1224. %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
  1225. %c = OpVariable %_ptr_Function_v4float Function
  1226. %71 = OpExtInst %void %1 DebugDeclare %61 %c %59
  1227. OpLine %6 18 9
  1228. %72 = OpAccessChain %_ptr_Function_v4float %i %int_0
  1229. OpLine %6 18 13
  1230. %73 = OpLoad %v4float %72
  1231. OpLine %6 18 5
  1232. OpStore %c %73
  1233. ;CHECK: OpStore %c %73
  1234. OpLine %6 19 10
  1235. %74 = OpAccessChain %_ptr_Function_v4float %i %int_1
  1236. OpLine %6 19 14
  1237. %75 = OpLoad %v4float %74
  1238. OpLine %6 19 5
  1239. %76 = OpLoad %v4float %c
  1240. ;CHECK-NOT: OpLine %6 19 5
  1241. ;CHECK-NOT: %76 = OpLoad %v4float %c
  1242. OpLine %6 19 7
  1243. %77 = OpFAdd %v4float %76 %75
  1244. ;CHECK-NOT: %77 = OpFAdd %v4float %76 %75
  1245. ;CHECK: %77 = OpFAdd %v4float %73 %75
  1246. OpLine %6 19 5
  1247. OpStore %c %77
  1248. ;CHECK: OpStore %c %77
  1249. OpLine %6 20 5
  1250. %78 = OpLoad %v4float %c
  1251. ;CHECK-NOT: OpLine %6 20 5
  1252. ;CHECK-NOT: %78 = OpLoad %v4float %c
  1253. OpLine %6 20 7
  1254. %79 = OpFDiv %v4float %78 %31
  1255. ;CHECK-NOT %79 = OpFDiv %v4float %78 %31
  1256. ;CHECK: %79 = OpFDiv %v4float %77 %31
  1257. OpLine %6 20 5
  1258. OpStore %c %79
  1259. ;CHECK: OpStore %c %79
  1260. OpLine %6 22 26
  1261. %80 = OpLoad %v4float %c
  1262. ;CHECK-NOT: OpLine %6 22 26
  1263. ;CHECK-NOT: %80 = OpLoad %v4float %c
  1264. OpLine %6 22 5
  1265. %81 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
  1266. OpStore %81 %80
  1267. ;CHECK-NOT: OpStore %81 %80
  1268. ;CHECK: OpStore %81 %79
  1269. OpLine %6 23 12
  1270. %82 = OpLoad %PS_OUTPUT %ps_output
  1271. OpLine %6 23 5
  1272. OpReturnValue %82
  1273. %86 = OpExtInst %void %1 DebugNoScope
  1274. OpFunctionEnd
  1275. )";
  1276. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1277. SinglePassRunAndMatch<LocalSingleBlockLoadStoreElimPass>(text, false);
  1278. }
  1279. TEST_F(LocalSingleBlockLoadStoreElimTest, DebugValueTest) {
  1280. // If OpenCL.DebugInfo.100 enabled, check that store/load is still
  1281. // optimized, but stores are not deleted for store/store.
  1282. // Same source as DebugDeclareTest; DebugDeclare replaced with
  1283. // equivalent DebugValue
  1284. const std::string text = R"(
  1285. OpCapability Shader
  1286. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  1287. OpMemoryModel Logical GLSL450
  1288. OpEntryPoint Fragment %MainPs "MainPs" %in_var_COLOR0 %in_var_COLOR1 %out_var_SV_Target0
  1289. OpExecutionMode %MainPs OriginUpperLeft
  1290. %6 = OpString "foo3.frag"
  1291. %7 = OpString "PS_OUTPUT"
  1292. %8 = OpString "float"
  1293. %9 = OpString "vColor"
  1294. %10 = OpString "PS_INPUT"
  1295. %11 = OpString "c1"
  1296. %12 = OpString "c0"
  1297. %13 = OpString "src.MainPs"
  1298. %14 = OpString "c"
  1299. %15 = OpString "ps_output"
  1300. %16 = OpString "i"
  1301. OpName %in_var_COLOR0 "in.var.COLOR0"
  1302. OpName %in_var_COLOR1 "in.var.COLOR1"
  1303. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  1304. OpName %MainPs "MainPs"
  1305. OpName %PS_INPUT "PS_INPUT"
  1306. OpMemberName %PS_INPUT 0 "c0"
  1307. OpMemberName %PS_INPUT 1 "c1"
  1308. OpName %param_var_i "param.var.i"
  1309. OpName %PS_OUTPUT "PS_OUTPUT"
  1310. OpMemberName %PS_OUTPUT 0 "vColor"
  1311. OpName %src_MainPs "src.MainPs"
  1312. OpName %i "i"
  1313. OpName %bb_entry "bb.entry"
  1314. OpName %ps_output "ps_output"
  1315. OpName %c "c"
  1316. OpDecorate %in_var_COLOR0 Location 0
  1317. OpDecorate %in_var_COLOR1 Location 1
  1318. OpDecorate %out_var_SV_Target0 Location 0
  1319. %int = OpTypeInt 32 1
  1320. %int_0 = OpConstant %int 0
  1321. %int_1 = OpConstant %int 1
  1322. %float = OpTypeFloat 32
  1323. %float_2 = OpConstant %float 2
  1324. %v4float = OpTypeVector %float 4
  1325. %31 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
  1326. %uint = OpTypeInt 32 0
  1327. %uint_32 = OpConstant %uint 32
  1328. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1329. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1330. %void = OpTypeVoid
  1331. %uint_128 = OpConstant %uint 128
  1332. %uint_0 = OpConstant %uint 0
  1333. %uint_256 = OpConstant %uint 256
  1334. %40 = OpTypeFunction %void
  1335. %PS_INPUT = OpTypeStruct %v4float %v4float
  1336. %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
  1337. %PS_OUTPUT = OpTypeStruct %v4float
  1338. %42 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
  1339. %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
  1340. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1341. %in_var_COLOR0 = OpVariable %_ptr_Input_v4float Input
  1342. %in_var_COLOR1 = OpVariable %_ptr_Input_v4float Input
  1343. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  1344. %45 = OpExtInst %void %1 DebugSource %6
  1345. %46 = OpExtInst %void %1 DebugCompilationUnit 1 4 %45 HLSL
  1346. %47 = OpExtInst %void %1 DebugTypeComposite %7 Structure %45 8 1 %46 %7 %uint_128 FlagIsProtected|FlagIsPrivate %48
  1347. %49 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 Float
  1348. %50 = OpExtInst %void %1 DebugTypeVector %49 4
  1349. %48 = OpExtInst %void %1 DebugTypeMember %9 %50 %45 10 5 %47 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  1350. %51 = OpExtInst %void %1 DebugTypeComposite %10 Structure %45 2 1 %46 %10 %uint_256 FlagIsProtected|FlagIsPrivate %52 %53
  1351. %53 = OpExtInst %void %1 DebugTypeMember %11 %50 %45 5 5 %51 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
  1352. %52 = OpExtInst %void %1 DebugTypeMember %12 %50 %45 4 5 %51 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  1353. %54 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %47 %51
  1354. %55 = OpExtInst %void %1 DebugFunction %13 %54 %45 13 1 %46 %13 FlagIsProtected|FlagIsPrivate 14 %src_MainPs
  1355. %56 = OpExtInst %void %1 DebugLexicalBlock %45 14 1 %55
  1356. %57 = OpExtInst %void %1 DebugLocalVariable %14 %50 %45 16 12 %56 FlagIsLocal
  1357. %58 = OpExtInst %void %1 DebugLocalVariable %15 %47 %45 15 15 %56 FlagIsLocal
  1358. %59 = OpExtInst %void %1 DebugExpression %60 = OpExtInst %void %1 DebugOperation Deref %61 = OpExtInst
  1359. %void %1 DebugExpression %60 %62 = OpExtInst %void %1 DebugLocalVariable %16 %51
  1360. %45 13 29 %55 FlagIsLocal 1 %63 = OpExtInst %void %1 DebugLocalVariable %14 %50
  1361. %45 16 12 %55 FlagIsLocal 1 %MainPs = OpFunction %void None %40 %64 = OpLabel
  1362. %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
  1363. %65 = OpLoad %v4float %in_var_COLOR0
  1364. %66 = OpLoad %v4float %in_var_COLOR1
  1365. %67 = OpCompositeConstruct %PS_INPUT %65 %66
  1366. OpStore %param_var_i %67
  1367. %68 = OpFunctionCall %PS_OUTPUT %src_MainPs %param_var_i
  1368. %69 = OpCompositeExtract %v4float %68 0
  1369. OpStore %out_var_SV_Target0 %69
  1370. OpReturn
  1371. OpFunctionEnd
  1372. OpLine %6 13 1
  1373. %src_MainPs = OpFunction %PS_OUTPUT None %42
  1374. %70 = OpExtInst %void %1 DebugScope %55
  1375. OpLine %6 13 29
  1376. %i = OpFunctionParameter %_ptr_Function_PS_INPUT
  1377. %71 = OpExtInst %void %1 DebugDeclare %62 %i %59
  1378. %72 = OpExtInst %void %1 DebugNoScope
  1379. %bb_entry = OpLabel
  1380. %73 = OpExtInst %void %1 DebugScope %56
  1381. %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
  1382. %c = OpVariable %_ptr_Function_v4float Function
  1383. %74 = OpExtInst %void %1 DebugValue %63 %c %61
  1384. OpLine %6 18 9
  1385. %75 = OpAccessChain %_ptr_Function_v4float %i %int_0
  1386. OpLine %6 18 13
  1387. %76 = OpLoad %v4float %75
  1388. OpLine %6 18 5
  1389. OpStore %c %76
  1390. ;CHECK: OpStore %c %76
  1391. OpLine %6 19 10
  1392. %77 = OpAccessChain %_ptr_Function_v4float %i %int_1
  1393. OpLine %6 19 14
  1394. %78 = OpLoad %v4float %77
  1395. OpLine %6 19 5
  1396. %79 = OpLoad %v4float %c
  1397. ;CHECK-NOT: OpLine %6 19 5
  1398. ;CHECK-NOT: %79 = OpLoad %v4float %c
  1399. OpLine %6 19 7
  1400. %80 = OpFAdd %v4float %79 %78
  1401. ;CHECK-NOT: %80 = OpFAdd %v4float %79 %78
  1402. ;CHECK: %80 = OpFAdd %v4float %76 %78
  1403. OpLine %6 19 5
  1404. OpStore %c %80
  1405. ;CHECK: OpStore %c %80
  1406. OpLine %6 20 5
  1407. %81 = OpLoad %v4float %c
  1408. ;CHECK-NOT: OpLine %6 20 5
  1409. ;CHECK-NOT: %81 = OpLoad %v4float %c
  1410. OpLine %6 20 7
  1411. %82 = OpFDiv %v4float %81 %31
  1412. ;CHECK-NOT: %82 = OpFDiv %v4float %81 %31
  1413. ;CHECK: %82 = OpFDiv %v4float %80 %31
  1414. OpLine %6 20 5
  1415. OpStore %c %82
  1416. ;CHECK: OpStore %c %82
  1417. OpLine %6 22 26
  1418. %83 = OpLoad %v4float %c
  1419. ;CHECK-NOT: OpLine %6 22 26
  1420. ;CHECK-NOT: %83 = OpLoad %v4float %c
  1421. OpLine %6 22 5
  1422. %84 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
  1423. OpStore %84 %83
  1424. ;CHECK-NOT: OpStore %84 %83
  1425. ;CHECK: OpStore %84 %82
  1426. OpLine %6 23 12
  1427. %85 = OpLoad %PS_OUTPUT %ps_output
  1428. OpLine %6 23 5
  1429. OpReturnValue %85
  1430. %86 = OpExtInst %void %1 DebugNoScope
  1431. OpFunctionEnd
  1432. )";
  1433. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1434. SinglePassRunAndMatch<LocalSingleBlockLoadStoreElimPass>(text, false);
  1435. }
  1436. TEST_F(LocalSingleBlockLoadStoreElimTest, VkMemoryModelTest) {
  1437. const std::string text =
  1438. R"(
  1439. ; CHECK: OpCapability Shader
  1440. ; CHECK: OpCapability VulkanMemoryModel
  1441. ; CHECK: OpExtension "SPV_KHR_vulkan_memory_model"
  1442. OpCapability Shader
  1443. OpCapability VulkanMemoryModel
  1444. OpExtension "SPV_KHR_vulkan_memory_model"
  1445. %1 = OpExtInstImport "GLSL.std.450"
  1446. OpMemoryModel Logical Vulkan
  1447. OpEntryPoint GLCompute %main "main"
  1448. OpExecutionMode %main LocalSize 1 1 1
  1449. OpSource GLSL 450
  1450. %void = OpTypeVoid
  1451. %3 = OpTypeFunction %void
  1452. %int = OpTypeInt 32 1
  1453. %_ptr_Function_int = OpTypePointer Function %int
  1454. %int_0 = OpConstant %int 0
  1455. %int_1 = OpConstant %int 1
  1456. %bool = OpTypeBool
  1457. %false = OpConstantFalse %bool
  1458. ; CHECK: OpFunction
  1459. ; CHECK-NEXT: OpLabel
  1460. ; CHECK-NEXT: [[a:%\w+]] = OpVariable
  1461. ; CHECK-NEXT: [[b:%\w+]] = OpVariable
  1462. ; CHECK: OpStore [[a]] [[v:%\w+]]
  1463. ; CHECK-NOT: OpLoad %int [[a]]
  1464. ; CHECK: OpStore [[b]] [[v]]
  1465. %main = OpFunction %void None %3
  1466. %5 = OpLabel
  1467. %a = OpVariable %_ptr_Function_int Function
  1468. %b = OpVariable %_ptr_Function_int Function
  1469. OpStore %a %int_0
  1470. %16 = OpLoad %int %a
  1471. OpStore %b %16
  1472. OpReturn
  1473. OpFunctionEnd
  1474. )";
  1475. SinglePassRunAndMatch<LocalSingleBlockLoadStoreElimPass>(text, false);
  1476. }
  1477. // TODO(greg-lunarg): Add tests to verify handling of these cases:
  1478. //
  1479. // Other target variable types
  1480. // InBounds Access Chains
  1481. // Check for correctness in the presence of function calls
  1482. // Others?
  1483. } // namespace
  1484. } // namespace opt
  1485. } // namespace spvtools