local_single_block_elim.cpp 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  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, SimpleLoadLoadElim) {
  78. // #version 140
  79. //
  80. // in vec4 BaseColor;
  81. // in float fi;
  82. //
  83. // void main()
  84. // {
  85. // vec4 v = BaseColor;
  86. // if (fi < 0)
  87. // v = vec4(0.0);
  88. // gl_FragData[0] = v;
  89. // gl_FragData[1] = v;
  90. // }
  91. const std::string predefs =
  92. R"(OpCapability Shader
  93. %1 = OpExtInstImport "GLSL.std.450"
  94. OpMemoryModel Logical GLSL450
  95. OpEntryPoint Fragment %main "main" %BaseColor %fi %gl_FragData
  96. OpExecutionMode %main OriginUpperLeft
  97. OpSource GLSL 140
  98. OpName %main "main"
  99. OpName %v "v"
  100. OpName %BaseColor "BaseColor"
  101. OpName %fi "fi"
  102. OpName %gl_FragData "gl_FragData"
  103. %void = OpTypeVoid
  104. %8 = OpTypeFunction %void
  105. %float = OpTypeFloat 32
  106. %v4float = OpTypeVector %float 4
  107. %_ptr_Function_v4float = OpTypePointer Function %v4float
  108. %_ptr_Input_v4float = OpTypePointer Input %v4float
  109. %BaseColor = OpVariable %_ptr_Input_v4float Input
  110. %_ptr_Input_float = OpTypePointer Input %float
  111. %fi = OpVariable %_ptr_Input_float Input
  112. %float_0 = OpConstant %float 0
  113. %bool = OpTypeBool
  114. %16 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  115. %uint = OpTypeInt 32 0
  116. %uint_32 = OpConstant %uint 32
  117. %_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32
  118. %_ptr_Output__arr_v4float_uint_32 = OpTypePointer Output %_arr_v4float_uint_32
  119. %gl_FragData = OpVariable %_ptr_Output__arr_v4float_uint_32 Output
  120. %int = OpTypeInt 32 1
  121. %int_0 = OpConstant %int 0
  122. %_ptr_Output_v4float = OpTypePointer Output %v4float
  123. %int_1 = OpConstant %int 1
  124. )";
  125. const std::string before =
  126. R"(%main = OpFunction %void None %8
  127. %25 = OpLabel
  128. %v = OpVariable %_ptr_Function_v4float Function
  129. %26 = OpLoad %v4float %BaseColor
  130. OpStore %v %26
  131. %27 = OpLoad %float %fi
  132. %28 = OpFOrdLessThan %bool %27 %float_0
  133. OpSelectionMerge %29 None
  134. OpBranchConditional %28 %30 %29
  135. %30 = OpLabel
  136. OpStore %v %16
  137. OpBranch %29
  138. %29 = OpLabel
  139. %31 = OpLoad %v4float %v
  140. %32 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
  141. OpStore %32 %31
  142. %33 = OpLoad %v4float %v
  143. %34 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
  144. OpStore %34 %33
  145. OpReturn
  146. OpFunctionEnd
  147. )";
  148. const std::string after =
  149. R"(%main = OpFunction %void None %8
  150. %25 = OpLabel
  151. %v = OpVariable %_ptr_Function_v4float Function
  152. %26 = OpLoad %v4float %BaseColor
  153. OpStore %v %26
  154. %27 = OpLoad %float %fi
  155. %28 = OpFOrdLessThan %bool %27 %float_0
  156. OpSelectionMerge %29 None
  157. OpBranchConditional %28 %30 %29
  158. %30 = OpLabel
  159. OpStore %v %16
  160. OpBranch %29
  161. %29 = OpLabel
  162. %31 = OpLoad %v4float %v
  163. %32 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
  164. OpStore %32 %31
  165. %34 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
  166. OpStore %34 %31
  167. OpReturn
  168. OpFunctionEnd
  169. )";
  170. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  171. predefs + before, predefs + after, true, true);
  172. }
  173. TEST_F(LocalSingleBlockLoadStoreElimTest, StoreStoreElim) {
  174. //
  175. // Note first store to v is eliminated
  176. //
  177. // #version 450
  178. //
  179. // layout(location = 0) in vec4 BaseColor;
  180. // layout(location = 0) out vec4 OutColor;
  181. //
  182. // void main()
  183. // {
  184. // vec4 v = BaseColor;
  185. // v = v * 0.5;
  186. // OutColor = v;
  187. // }
  188. const std::string predefs_before =
  189. R"(OpCapability Shader
  190. %1 = OpExtInstImport "GLSL.std.450"
  191. OpMemoryModel Logical GLSL450
  192. OpEntryPoint Fragment %main "main" %BaseColor %OutColor
  193. OpExecutionMode %main OriginUpperLeft
  194. OpSource GLSL 450
  195. OpName %main "main"
  196. OpName %v "v"
  197. OpName %BaseColor "BaseColor"
  198. OpName %OutColor "OutColor"
  199. OpDecorate %BaseColor Location 0
  200. OpDecorate %OutColor Location 0
  201. %void = OpTypeVoid
  202. %7 = OpTypeFunction %void
  203. %float = OpTypeFloat 32
  204. %v4float = OpTypeVector %float 4
  205. %_ptr_Function_v4float = OpTypePointer Function %v4float
  206. %_ptr_Input_v4float = OpTypePointer Input %v4float
  207. %BaseColor = OpVariable %_ptr_Input_v4float Input
  208. %float_0_5 = OpConstant %float 0.5
  209. %_ptr_Output_v4float = OpTypePointer Output %v4float
  210. %OutColor = OpVariable %_ptr_Output_v4float Output
  211. )";
  212. const std::string before =
  213. R"(%main = OpFunction %void None %7
  214. %14 = OpLabel
  215. %v = OpVariable %_ptr_Function_v4float Function
  216. %15 = OpLoad %v4float %BaseColor
  217. OpStore %v %15
  218. %16 = OpLoad %v4float %v
  219. %17 = OpVectorTimesScalar %v4float %16 %float_0_5
  220. OpStore %v %17
  221. %18 = OpLoad %v4float %v
  222. OpStore %OutColor %18
  223. OpReturn
  224. OpFunctionEnd
  225. )";
  226. const std::string after =
  227. R"(%main = OpFunction %void None %7
  228. %14 = OpLabel
  229. %v = OpVariable %_ptr_Function_v4float Function
  230. %15 = OpLoad %v4float %BaseColor
  231. %17 = OpVectorTimesScalar %v4float %15 %float_0_5
  232. OpStore %v %17
  233. OpStore %OutColor %17
  234. OpReturn
  235. OpFunctionEnd
  236. )";
  237. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  238. predefs_before + before, predefs_before + after, true, true);
  239. }
  240. TEST_F(LocalSingleBlockLoadStoreElimTest,
  241. NoStoreElimIfInterveningAccessChainLoad) {
  242. //
  243. // Note the first Store to %v is not eliminated due to the following access
  244. // chain reference.
  245. //
  246. // #version 450
  247. //
  248. // layout(location = 0) in vec4 BaseColor0;
  249. // layout(location = 1) in vec4 BaseColor1;
  250. // layout(location = 2) flat in int Idx;
  251. // layout(location = 0) out vec4 OutColor;
  252. //
  253. // void main()
  254. // {
  255. // vec4 v = BaseColor0;
  256. // float f = v[Idx];
  257. // v = BaseColor1 + vec4(0.1);
  258. // OutColor = v/f;
  259. // }
  260. const std::string predefs =
  261. R"(OpCapability Shader
  262. %1 = OpExtInstImport "GLSL.std.450"
  263. OpMemoryModel Logical GLSL450
  264. OpEntryPoint Fragment %main "main" %BaseColor0 %Idx %BaseColor1 %OutColor
  265. OpExecutionMode %main OriginUpperLeft
  266. OpSource GLSL 450
  267. OpName %main "main"
  268. OpName %v "v"
  269. OpName %BaseColor0 "BaseColor0"
  270. OpName %f "f"
  271. OpName %Idx "Idx"
  272. OpName %BaseColor1 "BaseColor1"
  273. OpName %OutColor "OutColor"
  274. OpDecorate %BaseColor0 Location 0
  275. OpDecorate %Idx Flat
  276. OpDecorate %Idx Location 2
  277. OpDecorate %BaseColor1 Location 1
  278. OpDecorate %OutColor Location 0
  279. %void = OpTypeVoid
  280. %10 = OpTypeFunction %void
  281. %float = OpTypeFloat 32
  282. %v4float = OpTypeVector %float 4
  283. %_ptr_Function_v4float = OpTypePointer Function %v4float
  284. %_ptr_Input_v4float = OpTypePointer Input %v4float
  285. %BaseColor0 = OpVariable %_ptr_Input_v4float Input
  286. %_ptr_Function_float = OpTypePointer Function %float
  287. %int = OpTypeInt 32 1
  288. %_ptr_Input_int = OpTypePointer Input %int
  289. %Idx = OpVariable %_ptr_Input_int Input
  290. %BaseColor1 = OpVariable %_ptr_Input_v4float Input
  291. %float_0_100000001 = OpConstant %float 0.100000001
  292. %19 = OpConstantComposite %v4float %float_0_100000001 %float_0_100000001 %float_0_100000001 %float_0_100000001
  293. %_ptr_Output_v4float = OpTypePointer Output %v4float
  294. %OutColor = OpVariable %_ptr_Output_v4float Output
  295. )";
  296. const std::string before =
  297. R"(%main = OpFunction %void None %10
  298. %21 = OpLabel
  299. %v = OpVariable %_ptr_Function_v4float Function
  300. %f = OpVariable %_ptr_Function_float Function
  301. %22 = OpLoad %v4float %BaseColor0
  302. OpStore %v %22
  303. %23 = OpLoad %int %Idx
  304. %24 = OpAccessChain %_ptr_Function_float %v %23
  305. %25 = OpLoad %float %24
  306. OpStore %f %25
  307. %26 = OpLoad %v4float %BaseColor1
  308. %27 = OpFAdd %v4float %26 %19
  309. OpStore %v %27
  310. %28 = OpLoad %v4float %v
  311. %29 = OpLoad %float %f
  312. %30 = OpCompositeConstruct %v4float %29 %29 %29 %29
  313. %31 = OpFDiv %v4float %28 %30
  314. OpStore %OutColor %31
  315. OpReturn
  316. OpFunctionEnd
  317. )";
  318. const std::string after =
  319. R"(%main = OpFunction %void None %10
  320. %21 = OpLabel
  321. %v = OpVariable %_ptr_Function_v4float Function
  322. %f = OpVariable %_ptr_Function_float Function
  323. %22 = OpLoad %v4float %BaseColor0
  324. OpStore %v %22
  325. %23 = OpLoad %int %Idx
  326. %24 = OpAccessChain %_ptr_Function_float %v %23
  327. %25 = OpLoad %float %24
  328. OpStore %f %25
  329. %26 = OpLoad %v4float %BaseColor1
  330. %27 = OpFAdd %v4float %26 %19
  331. OpStore %v %27
  332. %30 = OpCompositeConstruct %v4float %25 %25 %25 %25
  333. %31 = OpFDiv %v4float %27 %30
  334. OpStore %OutColor %31
  335. OpReturn
  336. OpFunctionEnd
  337. )";
  338. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  339. predefs + before, predefs + after, true, true);
  340. }
  341. TEST_F(LocalSingleBlockLoadStoreElimTest, NoElimIfInterveningAccessChainStore) {
  342. // #version 140
  343. //
  344. // in vec4 BaseColor;
  345. // flat in int Idx;
  346. //
  347. // void main()
  348. // {
  349. // vec4 v = BaseColor;
  350. // v[Idx] = 0;
  351. // gl_FragColor = v;
  352. // }
  353. const std::string assembly =
  354. R"(OpCapability Shader
  355. %1 = OpExtInstImport "GLSL.std.450"
  356. OpMemoryModel Logical GLSL450
  357. OpEntryPoint Fragment %main "main" %BaseColor %Idx %gl_FragColor
  358. OpExecutionMode %main OriginUpperLeft
  359. OpSource GLSL 140
  360. OpName %main "main"
  361. OpName %v "v"
  362. OpName %BaseColor "BaseColor"
  363. OpName %Idx "Idx"
  364. OpName %gl_FragColor "gl_FragColor"
  365. OpDecorate %Idx Flat
  366. %void = OpTypeVoid
  367. %8 = OpTypeFunction %void
  368. %float = OpTypeFloat 32
  369. %v4float = OpTypeVector %float 4
  370. %_ptr_Function_v4float = OpTypePointer Function %v4float
  371. %_ptr_Input_v4float = OpTypePointer Input %v4float
  372. %BaseColor = OpVariable %_ptr_Input_v4float Input
  373. %int = OpTypeInt 32 1
  374. %_ptr_Input_int = OpTypePointer Input %int
  375. %Idx = OpVariable %_ptr_Input_int Input
  376. %float_0 = OpConstant %float 0
  377. %_ptr_Function_float = OpTypePointer Function %float
  378. %_ptr_Output_v4float = OpTypePointer Output %v4float
  379. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  380. %main = OpFunction %void None %8
  381. %18 = OpLabel
  382. %v = OpVariable %_ptr_Function_v4float Function
  383. %19 = OpLoad %v4float %BaseColor
  384. OpStore %v %19
  385. %20 = OpLoad %int %Idx
  386. %21 = OpAccessChain %_ptr_Function_float %v %20
  387. OpStore %21 %float_0
  388. %22 = OpLoad %v4float %v
  389. OpStore %gl_FragColor %22
  390. OpReturn
  391. OpFunctionEnd
  392. )";
  393. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(assembly, assembly,
  394. false, true);
  395. }
  396. TEST_F(LocalSingleBlockLoadStoreElimTest, NoElimIfInterveningFunctionCall) {
  397. // #version 140
  398. //
  399. // in vec4 BaseColor;
  400. //
  401. // void foo() {
  402. // }
  403. //
  404. // void main()
  405. // {
  406. // vec4 v = BaseColor;
  407. // foo();
  408. // gl_FragColor = v;
  409. // }
  410. const std::string assembly =
  411. R"(OpCapability Shader
  412. %1 = OpExtInstImport "GLSL.std.450"
  413. OpMemoryModel Logical GLSL450
  414. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  415. OpExecutionMode %main OriginUpperLeft
  416. OpSource GLSL 140
  417. OpName %main "main"
  418. OpName %foo_ "foo("
  419. OpName %v "v"
  420. OpName %BaseColor "BaseColor"
  421. OpName %gl_FragColor "gl_FragColor"
  422. %void = OpTypeVoid
  423. %8 = OpTypeFunction %void
  424. %float = OpTypeFloat 32
  425. %v4float = OpTypeVector %float 4
  426. %_ptr_Function_v4float = OpTypePointer Function %v4float
  427. %_ptr_Input_v4float = OpTypePointer Input %v4float
  428. %BaseColor = OpVariable %_ptr_Input_v4float Input
  429. %_ptr_Output_v4float = OpTypePointer Output %v4float
  430. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  431. %main = OpFunction %void None %8
  432. %14 = OpLabel
  433. %v = OpVariable %_ptr_Function_v4float Function
  434. %15 = OpLoad %v4float %BaseColor
  435. OpStore %v %15
  436. %16 = OpFunctionCall %void %foo_
  437. %17 = OpLoad %v4float %v
  438. OpStore %gl_FragColor %17
  439. OpReturn
  440. OpFunctionEnd
  441. %foo_ = OpFunction %void None %8
  442. %18 = OpLabel
  443. OpReturn
  444. OpFunctionEnd
  445. )";
  446. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(assembly, assembly,
  447. false, true);
  448. }
  449. TEST_F(LocalSingleBlockLoadStoreElimTest, ElimIfCopyObjectInFunction) {
  450. // Note: SPIR-V hand edited to insert CopyObject
  451. //
  452. // #version 140
  453. //
  454. // in vec4 BaseColor;
  455. //
  456. // void main()
  457. // {
  458. // vec4 v1 = BaseColor;
  459. // gl_FragData[0] = v1;
  460. // vec4 v2 = BaseColor * 0.5;
  461. // gl_FragData[1] = v2;
  462. // }
  463. const std::string predefs =
  464. R"(OpCapability Shader
  465. %1 = OpExtInstImport "GLSL.std.450"
  466. OpMemoryModel Logical GLSL450
  467. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragData
  468. OpExecutionMode %main OriginUpperLeft
  469. OpSource GLSL 140
  470. OpName %main "main"
  471. OpName %v1 "v1"
  472. OpName %BaseColor "BaseColor"
  473. OpName %gl_FragData "gl_FragData"
  474. OpName %v2 "v2"
  475. %void = OpTypeVoid
  476. %8 = OpTypeFunction %void
  477. %float = OpTypeFloat 32
  478. %v4float = OpTypeVector %float 4
  479. %_ptr_Function_v4float = OpTypePointer Function %v4float
  480. %_ptr_Input_v4float = OpTypePointer Input %v4float
  481. %BaseColor = OpVariable %_ptr_Input_v4float Input
  482. %uint = OpTypeInt 32 0
  483. %uint_32 = OpConstant %uint 32
  484. %_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32
  485. %_ptr_Output__arr_v4float_uint_32 = OpTypePointer Output %_arr_v4float_uint_32
  486. %gl_FragData = OpVariable %_ptr_Output__arr_v4float_uint_32 Output
  487. %int = OpTypeInt 32 1
  488. %int_0 = OpConstant %int 0
  489. %_ptr_Output_v4float = OpTypePointer Output %v4float
  490. %float_0_5 = OpConstant %float 0.5
  491. %int_1 = OpConstant %int 1
  492. )";
  493. const std::string before =
  494. R"(%main = OpFunction %void None %8
  495. %22 = OpLabel
  496. %v1 = OpVariable %_ptr_Function_v4float Function
  497. %v2 = OpVariable %_ptr_Function_v4float Function
  498. %23 = OpLoad %v4float %BaseColor
  499. OpStore %v1 %23
  500. %24 = OpLoad %v4float %v1
  501. %25 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
  502. OpStore %25 %24
  503. %26 = OpLoad %v4float %BaseColor
  504. %27 = OpVectorTimesScalar %v4float %26 %float_0_5
  505. %28 = OpCopyObject %_ptr_Function_v4float %v2
  506. OpStore %28 %27
  507. %29 = OpLoad %v4float %28
  508. %30 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
  509. OpStore %30 %29
  510. OpReturn
  511. OpFunctionEnd
  512. )";
  513. const std::string after =
  514. R"(%main = OpFunction %void None %8
  515. %22 = OpLabel
  516. %v1 = OpVariable %_ptr_Function_v4float Function
  517. %v2 = OpVariable %_ptr_Function_v4float Function
  518. %23 = OpLoad %v4float %BaseColor
  519. OpStore %v1 %23
  520. %25 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
  521. OpStore %25 %23
  522. %26 = OpLoad %v4float %BaseColor
  523. %27 = OpVectorTimesScalar %v4float %26 %float_0_5
  524. %28 = OpCopyObject %_ptr_Function_v4float %v2
  525. OpStore %28 %27
  526. %30 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
  527. OpStore %30 %27
  528. OpReturn
  529. OpFunctionEnd
  530. )";
  531. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  532. predefs + before, predefs + after, true, true);
  533. }
  534. TEST_F(LocalSingleBlockLoadStoreElimTest, ElimOpaque) {
  535. // SPIR-V not representable in GLSL; not generatable from HLSL
  536. // at the moment
  537. const std::string predefs =
  538. R"(OpCapability Shader
  539. %1 = OpExtInstImport "GLSL.std.450"
  540. OpMemoryModel Logical GLSL450
  541. OpEntryPoint Fragment %main "main" %outColor %texCoords
  542. OpExecutionMode %main OriginUpperLeft
  543. OpSource GLSL 140
  544. OpName %main "main"
  545. OpName %S_t "S_t"
  546. OpMemberName %S_t 0 "v0"
  547. OpMemberName %S_t 1 "v1"
  548. OpMemberName %S_t 2 "smp"
  549. OpName %outColor "outColor"
  550. OpName %sampler15 "sampler15"
  551. OpName %s0 "s0"
  552. OpName %texCoords "texCoords"
  553. OpName %param "param"
  554. OpDecorate %sampler15 DescriptorSet 0
  555. %void = OpTypeVoid
  556. %12 = OpTypeFunction %void
  557. %float = OpTypeFloat 32
  558. %v2float = OpTypeVector %float 2
  559. %v4float = OpTypeVector %float 4
  560. %_ptr_Output_v4float = OpTypePointer Output %v4float
  561. %outColor = OpVariable %_ptr_Output_v4float Output
  562. %17 = OpTypeImage %float 2D 0 0 0 1 Unknown
  563. %18 = OpTypeSampledImage %17
  564. %S_t = OpTypeStruct %v2float %v2float %18
  565. %_ptr_Function_S_t = OpTypePointer Function %S_t
  566. %20 = OpTypeFunction %void %_ptr_Function_S_t
  567. %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
  568. %_ptr_Function_18 = OpTypePointer Function %18
  569. %sampler15 = OpVariable %_ptr_UniformConstant_18 UniformConstant
  570. %int = OpTypeInt 32 1
  571. %int_0 = OpConstant %int 0
  572. %int_2 = OpConstant %int 2
  573. %_ptr_Function_v2float = OpTypePointer Function %v2float
  574. %_ptr_Input_v2float = OpTypePointer Input %v2float
  575. %texCoords = OpVariable %_ptr_Input_v2float Input
  576. )";
  577. const std::string before =
  578. R"(%main = OpFunction %void None %12
  579. %28 = OpLabel
  580. %s0 = OpVariable %_ptr_Function_S_t Function
  581. %param = OpVariable %_ptr_Function_S_t Function
  582. %29 = OpLoad %v2float %texCoords
  583. %30 = OpLoad %S_t %s0
  584. %31 = OpCompositeInsert %S_t %29 %30 0
  585. OpStore %s0 %31
  586. %32 = OpLoad %18 %sampler15
  587. %33 = OpLoad %S_t %s0
  588. %34 = OpCompositeInsert %S_t %32 %33 2
  589. OpStore %s0 %34
  590. %35 = OpLoad %S_t %s0
  591. OpStore %param %35
  592. %36 = OpLoad %S_t %param
  593. %37 = OpCompositeExtract %18 %36 2
  594. %38 = OpLoad %S_t %param
  595. %39 = OpCompositeExtract %v2float %38 0
  596. %40 = OpImageSampleImplicitLod %v4float %37 %39
  597. OpStore %outColor %40
  598. OpReturn
  599. OpFunctionEnd
  600. )";
  601. const std::string after =
  602. R"(%main = OpFunction %void None %12
  603. %28 = OpLabel
  604. %s0 = OpVariable %_ptr_Function_S_t Function
  605. %param = OpVariable %_ptr_Function_S_t Function
  606. %29 = OpLoad %v2float %texCoords
  607. %30 = OpLoad %S_t %s0
  608. %31 = OpCompositeInsert %S_t %29 %30 0
  609. %32 = OpLoad %18 %sampler15
  610. %34 = OpCompositeInsert %S_t %32 %31 2
  611. OpStore %s0 %34
  612. OpStore %param %34
  613. %37 = OpCompositeExtract %18 %34 2
  614. %39 = OpCompositeExtract %v2float %34 0
  615. %40 = OpImageSampleImplicitLod %v4float %37 %39
  616. OpStore %outColor %40
  617. OpReturn
  618. OpFunctionEnd
  619. )";
  620. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  621. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  622. predefs + before, predefs + after, true, true);
  623. }
  624. TEST_F(LocalSingleBlockLoadStoreElimTest, PositiveAndNegativeCallTree) {
  625. // Note that the call tree function bar is optimized, but foo is not
  626. //
  627. // #version 140
  628. //
  629. // in vec4 BaseColor;
  630. //
  631. // vec4 foo(vec4 v1)
  632. // {
  633. // vec4 t = v1;
  634. // return t;
  635. // }
  636. //
  637. // vec4 bar(vec4 v1)
  638. // {
  639. // vec4 t = v1;
  640. // return t;
  641. // }
  642. //
  643. // void main()
  644. // {
  645. // gl_FragColor = bar(BaseColor);
  646. // }
  647. const std::string predefs =
  648. R"(OpCapability Shader
  649. %1 = OpExtInstImport "GLSL.std.450"
  650. OpMemoryModel Logical GLSL450
  651. OpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor
  652. OpExecutionMode %main OriginUpperLeft
  653. OpSource GLSL 140
  654. OpName %main "main"
  655. OpName %foo_vf4_ "foo(vf4;"
  656. OpName %v1 "v1"
  657. OpName %bar_vf4_ "bar(vf4;"
  658. OpName %v1_0 "v1"
  659. OpName %t "t"
  660. OpName %t_0 "t"
  661. OpName %gl_FragColor "gl_FragColor"
  662. OpName %BaseColor "BaseColor"
  663. OpName %param "param"
  664. %void = OpTypeVoid
  665. %13 = OpTypeFunction %void
  666. %float = OpTypeFloat 32
  667. %v4float = OpTypeVector %float 4
  668. %_ptr_Function_v4float = OpTypePointer Function %v4float
  669. %17 = OpTypeFunction %v4float %_ptr_Function_v4float
  670. %_ptr_Output_v4float = OpTypePointer Output %v4float
  671. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  672. %_ptr_Input_v4float = OpTypePointer Input %v4float
  673. %BaseColor = OpVariable %_ptr_Input_v4float Input
  674. %main = OpFunction %void None %13
  675. %20 = OpLabel
  676. %param = OpVariable %_ptr_Function_v4float Function
  677. %21 = OpLoad %v4float %BaseColor
  678. OpStore %param %21
  679. %22 = OpFunctionCall %v4float %bar_vf4_ %param
  680. OpStore %gl_FragColor %22
  681. OpReturn
  682. OpFunctionEnd
  683. )";
  684. const std::string before =
  685. R"(%foo_vf4_ = OpFunction %v4float None %17
  686. %v1 = OpFunctionParameter %_ptr_Function_v4float
  687. %23 = OpLabel
  688. %t = OpVariable %_ptr_Function_v4float Function
  689. %24 = OpLoad %v4float %v1
  690. OpStore %t %24
  691. %25 = OpLoad %v4float %t
  692. OpReturnValue %25
  693. OpFunctionEnd
  694. %bar_vf4_ = OpFunction %v4float None %17
  695. %v1_0 = OpFunctionParameter %_ptr_Function_v4float
  696. %26 = OpLabel
  697. %t_0 = OpVariable %_ptr_Function_v4float Function
  698. %27 = OpLoad %v4float %v1_0
  699. OpStore %t_0 %27
  700. %28 = OpLoad %v4float %t_0
  701. OpReturnValue %28
  702. OpFunctionEnd
  703. )";
  704. const std::string after =
  705. R"(%foo_vf4_ = OpFunction %v4float None %17
  706. %v1 = OpFunctionParameter %_ptr_Function_v4float
  707. %23 = OpLabel
  708. %t = OpVariable %_ptr_Function_v4float Function
  709. %24 = OpLoad %v4float %v1
  710. OpStore %t %24
  711. %25 = OpLoad %v4float %t
  712. OpReturnValue %25
  713. OpFunctionEnd
  714. %bar_vf4_ = OpFunction %v4float None %17
  715. %v1_0 = OpFunctionParameter %_ptr_Function_v4float
  716. %26 = OpLabel
  717. %t_0 = OpVariable %_ptr_Function_v4float Function
  718. %27 = OpLoad %v4float %v1_0
  719. OpStore %t_0 %27
  720. OpReturnValue %27
  721. OpFunctionEnd
  722. )";
  723. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  724. predefs + before, predefs + after, true, true);
  725. }
  726. TEST_F(LocalSingleBlockLoadStoreElimTest, PointerVariable) {
  727. // Test that checks if a pointer variable is removed.
  728. const std::string before =
  729. R"(OpCapability Shader
  730. OpMemoryModel Logical GLSL450
  731. OpEntryPoint Fragment %1 "main" %2
  732. OpExecutionMode %1 OriginUpperLeft
  733. OpMemberDecorate %_struct_3 0 Offset 0
  734. OpDecorate %_runtimearr__struct_3 ArrayStride 16
  735. OpMemberDecorate %_struct_5 0 Offset 0
  736. OpDecorate %_struct_5 BufferBlock
  737. OpMemberDecorate %_struct_6 0 Offset 0
  738. OpDecorate %_struct_6 BufferBlock
  739. OpDecorate %2 Location 0
  740. OpDecorate %7 DescriptorSet 0
  741. OpDecorate %7 Binding 0
  742. %void = OpTypeVoid
  743. %10 = OpTypeFunction %void
  744. %int = OpTypeInt 32 1
  745. %uint = OpTypeInt 32 0
  746. %float = OpTypeFloat 32
  747. %v4float = OpTypeVector %float 4
  748. %_ptr_Output_v4float = OpTypePointer Output %v4float
  749. %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
  750. %_struct_3 = OpTypeStruct %v4float
  751. %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
  752. %_struct_5 = OpTypeStruct %_runtimearr__struct_3
  753. %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
  754. %_struct_6 = OpTypeStruct %int
  755. %_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
  756. %_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
  757. %_ptr_Function__ptr_Uniform__struct_6 = OpTypePointer Function %_ptr_Uniform__struct_6
  758. %int_0 = OpConstant %int 0
  759. %uint_0 = OpConstant %uint 0
  760. %2 = OpVariable %_ptr_Output_v4float Output
  761. %7 = OpVariable %_ptr_Uniform__struct_5 Uniform
  762. %1 = OpFunction %void None %10
  763. %23 = OpLabel
  764. %24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
  765. OpStore %24 %7
  766. %26 = OpLoad %_ptr_Uniform__struct_5 %24
  767. %27 = OpAccessChain %_ptr_Uniform_v4float %26 %int_0 %uint_0 %int_0
  768. %28 = OpLoad %v4float %27
  769. %29 = OpCopyObject %v4float %28
  770. OpStore %2 %28
  771. OpReturn
  772. OpFunctionEnd
  773. )";
  774. const std::string after =
  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. %27 = OpAccessChain %_ptr_Uniform_v4float %7 %int_0 %uint_0 %int_0
  813. %28 = OpLoad %v4float %27
  814. %29 = OpCopyObject %v4float %28
  815. OpStore %2 %28
  816. OpReturn
  817. OpFunctionEnd
  818. )";
  819. // Relax logical pointers to allow pointer allocations.
  820. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  821. ValidatorOptions()->relax_logical_pointer = true;
  822. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(before, after, true,
  823. true);
  824. }
  825. TEST_F(LocalSingleBlockLoadStoreElimTest, RedundantStore) {
  826. // Test that checks if a pointer variable is removed.
  827. const std::string predefs_before =
  828. R"(OpCapability Shader
  829. %1 = OpExtInstImport "GLSL.std.450"
  830. OpMemoryModel Logical GLSL450
  831. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  832. OpExecutionMode %main OriginUpperLeft
  833. OpSource GLSL 140
  834. OpName %main "main"
  835. OpName %v "v"
  836. OpName %BaseColor "BaseColor"
  837. OpName %gl_FragColor "gl_FragColor"
  838. %void = OpTypeVoid
  839. %7 = OpTypeFunction %void
  840. %float = OpTypeFloat 32
  841. %v4float = OpTypeVector %float 4
  842. %_ptr_Function_v4float = OpTypePointer Function %v4float
  843. %_ptr_Input_v4float = OpTypePointer Input %v4float
  844. %BaseColor = OpVariable %_ptr_Input_v4float Input
  845. %_ptr_Output_v4float = OpTypePointer Output %v4float
  846. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  847. )";
  848. const std::string before =
  849. R"(%main = OpFunction %void None %7
  850. %13 = OpLabel
  851. %v = OpVariable %_ptr_Function_v4float Function
  852. %14 = OpLoad %v4float %BaseColor
  853. OpStore %v %14
  854. OpBranch %16
  855. %16 = OpLabel
  856. %15 = OpLoad %v4float %v
  857. OpStore %v %15
  858. OpReturn
  859. OpFunctionEnd
  860. )";
  861. const std::string after =
  862. R"(%main = OpFunction %void None %7
  863. %13 = OpLabel
  864. %v = OpVariable %_ptr_Function_v4float Function
  865. %14 = OpLoad %v4float %BaseColor
  866. OpStore %v %14
  867. OpBranch %16
  868. %16 = OpLabel
  869. %15 = OpLoad %v4float %v
  870. OpReturn
  871. OpFunctionEnd
  872. )";
  873. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  874. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  875. predefs_before + before, predefs_before + after, true, true);
  876. }
  877. TEST_F(LocalSingleBlockLoadStoreElimTest, RedundantStore2) {
  878. // Test that checks if a pointer variable is removed.
  879. const std::string predefs_before =
  880. R"(OpCapability Shader
  881. %1 = OpExtInstImport "GLSL.std.450"
  882. OpMemoryModel Logical GLSL450
  883. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  884. OpExecutionMode %main OriginUpperLeft
  885. OpSource GLSL 140
  886. OpName %main "main"
  887. OpName %v "v"
  888. OpName %BaseColor "BaseColor"
  889. OpName %gl_FragColor "gl_FragColor"
  890. %void = OpTypeVoid
  891. %7 = OpTypeFunction %void
  892. %float = OpTypeFloat 32
  893. %v4float = OpTypeVector %float 4
  894. %_ptr_Function_v4float = OpTypePointer Function %v4float
  895. %_ptr_Input_v4float = OpTypePointer Input %v4float
  896. %BaseColor = OpVariable %_ptr_Input_v4float Input
  897. %_ptr_Output_v4float = OpTypePointer Output %v4float
  898. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  899. )";
  900. const std::string before =
  901. R"(%main = OpFunction %void None %7
  902. %13 = OpLabel
  903. %v = OpVariable %_ptr_Function_v4float Function
  904. %14 = OpLoad %v4float %BaseColor
  905. OpStore %v %14
  906. OpBranch %16
  907. %16 = OpLabel
  908. %15 = OpLoad %v4float %v
  909. OpStore %v %15
  910. %17 = OpLoad %v4float %v
  911. OpStore %v %17
  912. OpReturn
  913. OpFunctionEnd
  914. )";
  915. const std::string after =
  916. R"(%main = OpFunction %void None %7
  917. %13 = OpLabel
  918. %v = OpVariable %_ptr_Function_v4float Function
  919. %14 = OpLoad %v4float %BaseColor
  920. OpStore %v %14
  921. OpBranch %16
  922. %16 = OpLabel
  923. %15 = OpLoad %v4float %v
  924. OpReturn
  925. OpFunctionEnd
  926. )";
  927. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  928. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  929. predefs_before + before, predefs_before + after, true, true);
  930. }
  931. // Test that that an unused OpAccessChain between two store does does not
  932. // hinders the removal of the first store. We need to check this because
  933. // local-access-chain-convert does always remove the OpAccessChain instructions
  934. // that become dead.
  935. TEST_F(LocalSingleBlockLoadStoreElimTest,
  936. StoreElimIfInterveningUnusedAccessChain) {
  937. const std::string predefs =
  938. R"(OpCapability Shader
  939. %1 = OpExtInstImport "GLSL.std.450"
  940. OpMemoryModel Logical GLSL450
  941. OpEntryPoint Fragment %main "main" %BaseColor0 %Idx %BaseColor1 %OutColor
  942. OpExecutionMode %main OriginUpperLeft
  943. OpSource GLSL 450
  944. OpName %main "main"
  945. OpName %v "v"
  946. OpName %BaseColor0 "BaseColor0"
  947. OpName %Idx "Idx"
  948. OpName %BaseColor1 "BaseColor1"
  949. OpName %OutColor "OutColor"
  950. OpDecorate %BaseColor0 Location 0
  951. OpDecorate %Idx Flat
  952. OpDecorate %Idx Location 2
  953. OpDecorate %BaseColor1 Location 1
  954. OpDecorate %OutColor Location 0
  955. %void = OpTypeVoid
  956. %10 = OpTypeFunction %void
  957. %float = OpTypeFloat 32
  958. %v4float = OpTypeVector %float 4
  959. %_ptr_Function_v4float = OpTypePointer Function %v4float
  960. %_ptr_Input_v4float = OpTypePointer Input %v4float
  961. %BaseColor0 = OpVariable %_ptr_Input_v4float Input
  962. %_ptr_Function_float = OpTypePointer Function %float
  963. %int = OpTypeInt 32 1
  964. %_ptr_Input_int = OpTypePointer Input %int
  965. %Idx = OpVariable %_ptr_Input_int Input
  966. %BaseColor1 = OpVariable %_ptr_Input_v4float Input
  967. %float_0_100000001 = OpConstant %float 0.100000001
  968. %19 = OpConstantComposite %v4float %float_0_100000001 %float_0_100000001 %float_0_100000001 %float_0_100000001
  969. %_ptr_Output_v4float = OpTypePointer Output %v4float
  970. %OutColor = OpVariable %_ptr_Output_v4float Output
  971. )";
  972. const std::string before =
  973. R"(%main = OpFunction %void None %10
  974. %21 = OpLabel
  975. %v = OpVariable %_ptr_Function_v4float Function
  976. %22 = OpLoad %v4float %BaseColor0
  977. OpStore %v %22
  978. %23 = OpLoad %int %Idx
  979. %24 = OpAccessChain %_ptr_Function_float %v %23
  980. %26 = OpLoad %v4float %BaseColor1
  981. %27 = OpFAdd %v4float %26 %19
  982. OpStore %v %27
  983. OpReturn
  984. OpFunctionEnd
  985. )";
  986. const std::string after =
  987. R"(%main = OpFunction %void None %10
  988. %21 = OpLabel
  989. %v = OpVariable %_ptr_Function_v4float Function
  990. %22 = OpLoad %v4float %BaseColor0
  991. %23 = OpLoad %int %Idx
  992. %24 = OpAccessChain %_ptr_Function_float %v %23
  993. %26 = OpLoad %v4float %BaseColor1
  994. %27 = OpFAdd %v4float %26 %19
  995. OpStore %v %27
  996. OpReturn
  997. OpFunctionEnd
  998. )";
  999. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1000. SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
  1001. predefs + before, predefs + after, true, true);
  1002. }
  1003. // TODO(greg-lunarg): Add tests to verify handling of these cases:
  1004. //
  1005. // Other target variable types
  1006. // InBounds Access Chains
  1007. // Check for correctness in the presence of function calls
  1008. // Others?
  1009. } // namespace
  1010. } // namespace opt
  1011. } // namespace spvtools