local_single_block_elim.cpp 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514
  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. // TODO(greg-lunarg): Add tests to verify handling of these cases:
  1437. //
  1438. // Other target variable types
  1439. // InBounds Access Chains
  1440. // Check for correctness in the presence of function calls
  1441. // Others?
  1442. } // namespace
  1443. } // namespace opt
  1444. } // namespace spvtools