vector_dce_test.cpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  1. // Copyright (c) 2018 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <string>
  15. #include "test/opt/pass_fixture.h"
  16. #include "test/opt/pass_utils.h"
  17. namespace spvtools {
  18. namespace opt {
  19. namespace {
  20. using VectorDCETest = PassTest<::testing::Test>;
  21. TEST_F(VectorDCETest, InsertAfterInsertElim) {
  22. // With two insertions to the same offset, the first is dead.
  23. //
  24. // Note: The SPIR-V assembly has had store/load elimination
  25. // performed to allow the inserts and extracts to directly
  26. // reference each other.
  27. //
  28. // #version 450
  29. //
  30. // layout (location=0) in float In0;
  31. // layout (location=1) in float In1;
  32. // layout (location=2) in vec2 In2;
  33. // layout (location=0) out vec4 OutColor;
  34. //
  35. // void main()
  36. // {
  37. // vec2 v = In2;
  38. // v.x = In0 + In1; // dead
  39. // v.x = 0.0;
  40. // OutColor = v.xyxy;
  41. // }
  42. const std::string before_predefs =
  43. R"(OpCapability Shader
  44. %1 = OpExtInstImport "GLSL.std.450"
  45. OpMemoryModel Logical GLSL450
  46. OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
  47. OpExecutionMode %main OriginUpperLeft
  48. OpSource GLSL 450
  49. OpName %main "main"
  50. OpName %In2 "In2"
  51. OpName %In0 "In0"
  52. OpName %In1 "In1"
  53. OpName %OutColor "OutColor"
  54. OpName %_Globals_ "_Globals_"
  55. OpMemberName %_Globals_ 0 "g_b"
  56. OpMemberName %_Globals_ 1 "g_n"
  57. OpName %_ ""
  58. OpDecorate %In2 Location 2
  59. OpDecorate %In0 Location 0
  60. OpDecorate %In1 Location 1
  61. OpDecorate %OutColor Location 0
  62. OpMemberDecorate %_Globals_ 0 Offset 0
  63. OpMemberDecorate %_Globals_ 1 Offset 4
  64. OpDecorate %_Globals_ Block
  65. OpDecorate %_ DescriptorSet 0
  66. OpDecorate %_ Binding 0
  67. %void = OpTypeVoid
  68. %11 = OpTypeFunction %void
  69. %float = OpTypeFloat 32
  70. %v2float = OpTypeVector %float 2
  71. %_ptr_Function_v2float = OpTypePointer Function %v2float
  72. %_ptr_Input_v2float = OpTypePointer Input %v2float
  73. %In2 = OpVariable %_ptr_Input_v2float Input
  74. %_ptr_Input_float = OpTypePointer Input %float
  75. %In0 = OpVariable %_ptr_Input_float Input
  76. %In1 = OpVariable %_ptr_Input_float Input
  77. %uint = OpTypeInt 32 0
  78. %_ptr_Function_float = OpTypePointer Function %float
  79. %float_0 = OpConstant %float 0
  80. %v4float = OpTypeVector %float 4
  81. %_ptr_Output_v4float = OpTypePointer Output %v4float
  82. %OutColor = OpVariable %_ptr_Output_v4float Output
  83. %int = OpTypeInt 32 1
  84. %_Globals_ = OpTypeStruct %uint %int
  85. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  86. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  87. )";
  88. const std::string after_predefs =
  89. R"(OpCapability Shader
  90. %1 = OpExtInstImport "GLSL.std.450"
  91. OpMemoryModel Logical GLSL450
  92. OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
  93. OpExecutionMode %main OriginUpperLeft
  94. OpSource GLSL 450
  95. OpName %main "main"
  96. OpName %In2 "In2"
  97. OpName %In0 "In0"
  98. OpName %In1 "In1"
  99. OpName %OutColor "OutColor"
  100. OpName %_Globals_ "_Globals_"
  101. OpMemberName %_Globals_ 0 "g_b"
  102. OpMemberName %_Globals_ 1 "g_n"
  103. OpName %_ ""
  104. OpDecorate %In2 Location 2
  105. OpDecorate %In0 Location 0
  106. OpDecorate %In1 Location 1
  107. OpDecorate %OutColor Location 0
  108. OpMemberDecorate %_Globals_ 0 Offset 0
  109. OpMemberDecorate %_Globals_ 1 Offset 4
  110. OpDecorate %_Globals_ Block
  111. OpDecorate %_ DescriptorSet 0
  112. OpDecorate %_ Binding 0
  113. %void = OpTypeVoid
  114. %10 = OpTypeFunction %void
  115. %float = OpTypeFloat 32
  116. %v2float = OpTypeVector %float 2
  117. %_ptr_Function_v2float = OpTypePointer Function %v2float
  118. %_ptr_Input_v2float = OpTypePointer Input %v2float
  119. %In2 = OpVariable %_ptr_Input_v2float Input
  120. %_ptr_Input_float = OpTypePointer Input %float
  121. %In0 = OpVariable %_ptr_Input_float Input
  122. %In1 = OpVariable %_ptr_Input_float Input
  123. %uint = OpTypeInt 32 0
  124. %_ptr_Function_float = OpTypePointer Function %float
  125. %float_0 = OpConstant %float 0
  126. %v4float = OpTypeVector %float 4
  127. %_ptr_Output_v4float = OpTypePointer Output %v4float
  128. %OutColor = OpVariable %_ptr_Output_v4float Output
  129. %int = OpTypeInt 32 1
  130. %_Globals_ = OpTypeStruct %uint %int
  131. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  132. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  133. )";
  134. const std::string before =
  135. R"(%main = OpFunction %void None %11
  136. %25 = OpLabel
  137. %26 = OpLoad %v2float %In2
  138. %27 = OpLoad %float %In0
  139. %28 = OpLoad %float %In1
  140. %29 = OpFAdd %float %27 %28
  141. %35 = OpCompositeInsert %v2float %29 %26 0
  142. %37 = OpCompositeInsert %v2float %float_0 %35 0
  143. %33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
  144. OpStore %OutColor %33
  145. OpReturn
  146. OpFunctionEnd
  147. )";
  148. const std::string after =
  149. R"(%main = OpFunction %void None %10
  150. %23 = OpLabel
  151. %24 = OpLoad %v2float %In2
  152. %25 = OpLoad %float %In0
  153. %26 = OpLoad %float %In1
  154. %27 = OpFAdd %float %25 %26
  155. %28 = OpCompositeInsert %v2float %27 %24 0
  156. %29 = OpCompositeInsert %v2float %float_0 %24 0
  157. %30 = OpVectorShuffle %v4float %29 %29 0 1 0 1
  158. OpStore %OutColor %30
  159. OpReturn
  160. OpFunctionEnd
  161. )";
  162. SinglePassRunAndCheck<VectorDCE>(before_predefs + before,
  163. after_predefs + after, true, true);
  164. }
  165. TEST_F(VectorDCETest, DeadInsertInChainWithPhi) {
  166. // Dead insert eliminated with phi in insertion chain.
  167. //
  168. // Note: The SPIR-V assembly has had store/load elimination
  169. // performed to allow the inserts and extracts to directly
  170. // reference each other.
  171. //
  172. // #version 450
  173. //
  174. // layout (location=0) in vec4 In0;
  175. // layout (location=1) in float In1;
  176. // layout (location=2) in float In2;
  177. // layout (location=0) out vec4 OutColor;
  178. //
  179. // layout(std140, binding = 0 ) uniform _Globals_
  180. // {
  181. // bool g_b;
  182. // };
  183. //
  184. // void main()
  185. // {
  186. // vec4 v = In0;
  187. // v.z = In1 + In2;
  188. // if (g_b) v.w = 1.0;
  189. // OutColor = vec4(v.x,v.y,0.0,v.w);
  190. // }
  191. const std::string before_predefs =
  192. R"(OpCapability Shader
  193. %1 = OpExtInstImport "GLSL.std.450"
  194. OpMemoryModel Logical GLSL450
  195. OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
  196. OpExecutionMode %main OriginUpperLeft
  197. OpSource GLSL 450
  198. OpName %main "main"
  199. OpName %In0 "In0"
  200. OpName %In1 "In1"
  201. OpName %In2 "In2"
  202. OpName %_Globals_ "_Globals_"
  203. OpMemberName %_Globals_ 0 "g_b"
  204. OpName %_ ""
  205. OpName %OutColor "OutColor"
  206. OpDecorate %In0 Location 0
  207. OpDecorate %In1 Location 1
  208. OpDecorate %In2 Location 2
  209. OpMemberDecorate %_Globals_ 0 Offset 0
  210. OpDecorate %_Globals_ Block
  211. OpDecorate %_ DescriptorSet 0
  212. OpDecorate %_ Binding 0
  213. OpDecorate %OutColor Location 0
  214. %void = OpTypeVoid
  215. %11 = OpTypeFunction %void
  216. %float = OpTypeFloat 32
  217. %v4float = OpTypeVector %float 4
  218. %_ptr_Function_v4float = OpTypePointer Function %v4float
  219. %_ptr_Input_v4float = OpTypePointer Input %v4float
  220. %In0 = OpVariable %_ptr_Input_v4float Input
  221. %_ptr_Input_float = OpTypePointer Input %float
  222. %In1 = OpVariable %_ptr_Input_float Input
  223. %In2 = OpVariable %_ptr_Input_float Input
  224. %uint = OpTypeInt 32 0
  225. %_ptr_Function_float = OpTypePointer Function %float
  226. %_Globals_ = OpTypeStruct %uint
  227. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  228. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  229. %int = OpTypeInt 32 1
  230. %int_0 = OpConstant %int 0
  231. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  232. %bool = OpTypeBool
  233. %uint_0 = OpConstant %uint 0
  234. %float_1 = OpConstant %float 1
  235. %_ptr_Output_v4float = OpTypePointer Output %v4float
  236. %OutColor = OpVariable %_ptr_Output_v4float Output
  237. %float_0 = OpConstant %float 0
  238. )";
  239. const std::string after_predefs =
  240. R"(OpCapability Shader
  241. %1 = OpExtInstImport "GLSL.std.450"
  242. OpMemoryModel Logical GLSL450
  243. OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
  244. OpExecutionMode %main OriginUpperLeft
  245. OpSource GLSL 450
  246. OpName %main "main"
  247. OpName %In0 "In0"
  248. OpName %In1 "In1"
  249. OpName %In2 "In2"
  250. OpName %_Globals_ "_Globals_"
  251. OpMemberName %_Globals_ 0 "g_b"
  252. OpName %_ ""
  253. OpName %OutColor "OutColor"
  254. OpDecorate %In0 Location 0
  255. OpDecorate %In1 Location 1
  256. OpDecorate %In2 Location 2
  257. OpMemberDecorate %_Globals_ 0 Offset 0
  258. OpDecorate %_Globals_ Block
  259. OpDecorate %_ DescriptorSet 0
  260. OpDecorate %_ Binding 0
  261. OpDecorate %OutColor Location 0
  262. %void = OpTypeVoid
  263. %10 = OpTypeFunction %void
  264. %float = OpTypeFloat 32
  265. %v4float = OpTypeVector %float 4
  266. %_ptr_Function_v4float = OpTypePointer Function %v4float
  267. %_ptr_Input_v4float = OpTypePointer Input %v4float
  268. %In0 = OpVariable %_ptr_Input_v4float Input
  269. %_ptr_Input_float = OpTypePointer Input %float
  270. %In1 = OpVariable %_ptr_Input_float Input
  271. %In2 = OpVariable %_ptr_Input_float Input
  272. %uint = OpTypeInt 32 0
  273. %_ptr_Function_float = OpTypePointer Function %float
  274. %_Globals_ = OpTypeStruct %uint
  275. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  276. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  277. %int = OpTypeInt 32 1
  278. %int_0 = OpConstant %int 0
  279. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  280. %bool = OpTypeBool
  281. %uint_0 = OpConstant %uint 0
  282. %float_1 = OpConstant %float 1
  283. %_ptr_Output_v4float = OpTypePointer Output %v4float
  284. %OutColor = OpVariable %_ptr_Output_v4float Output
  285. %float_0 = OpConstant %float 0
  286. )";
  287. const std::string before =
  288. R"(%main = OpFunction %void None %11
  289. %31 = OpLabel
  290. %32 = OpLoad %v4float %In0
  291. %33 = OpLoad %float %In1
  292. %34 = OpLoad %float %In2
  293. %35 = OpFAdd %float %33 %34
  294. %51 = OpCompositeInsert %v4float %35 %32 2
  295. %37 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  296. %38 = OpLoad %uint %37
  297. %39 = OpINotEqual %bool %38 %uint_0
  298. OpSelectionMerge %40 None
  299. OpBranchConditional %39 %41 %40
  300. %41 = OpLabel
  301. %53 = OpCompositeInsert %v4float %float_1 %51 3
  302. OpBranch %40
  303. %40 = OpLabel
  304. %60 = OpPhi %v4float %51 %31 %53 %41
  305. %55 = OpCompositeExtract %float %60 0
  306. %57 = OpCompositeExtract %float %60 1
  307. %59 = OpCompositeExtract %float %60 3
  308. %49 = OpCompositeConstruct %v4float %55 %57 %float_0 %59
  309. OpStore %OutColor %49
  310. OpReturn
  311. OpFunctionEnd
  312. )";
  313. const std::string after =
  314. R"(%main = OpFunction %void None %10
  315. %27 = OpLabel
  316. %28 = OpLoad %v4float %In0
  317. %29 = OpLoad %float %In1
  318. %30 = OpLoad %float %In2
  319. %31 = OpFAdd %float %29 %30
  320. %32 = OpCompositeInsert %v4float %31 %28 2
  321. %33 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  322. %34 = OpLoad %uint %33
  323. %35 = OpINotEqual %bool %34 %uint_0
  324. OpSelectionMerge %36 None
  325. OpBranchConditional %35 %37 %36
  326. %37 = OpLabel
  327. %38 = OpCompositeInsert %v4float %float_1 %28 3
  328. OpBranch %36
  329. %36 = OpLabel
  330. %39 = OpPhi %v4float %28 %27 %38 %37
  331. %40 = OpCompositeExtract %float %39 0
  332. %41 = OpCompositeExtract %float %39 1
  333. %42 = OpCompositeExtract %float %39 3
  334. %43 = OpCompositeConstruct %v4float %40 %41 %float_0 %42
  335. OpStore %OutColor %43
  336. OpReturn
  337. OpFunctionEnd
  338. )";
  339. SinglePassRunAndCheck<VectorDCE>(before_predefs + before,
  340. after_predefs + after, true, true);
  341. }
  342. TEST_F(VectorDCETest, DeadInsertWithScalars) {
  343. // Dead insert which requires two passes to eliminate
  344. //
  345. // Note: The SPIR-V assembly has had store/load elimination
  346. // performed to allow the inserts and extracts to directly
  347. // reference each other.
  348. //
  349. // #version 450
  350. //
  351. // layout (location=0) in vec4 In0;
  352. // layout (location=1) in float In1;
  353. // layout (location=2) in float In2;
  354. // layout (location=0) out vec4 OutColor;
  355. //
  356. // layout(std140, binding = 0 ) uniform _Globals_
  357. // {
  358. // bool g_b;
  359. // bool g_b2;
  360. // };
  361. //
  362. // void main()
  363. // {
  364. // vec4 v1, v2;
  365. // v1 = In0;
  366. // v1.y = In1 + In2; // dead, second pass
  367. // if (g_b) v1.x = 1.0;
  368. // v2.x = v1.x;
  369. // v2.y = v1.y; // dead, first pass
  370. // if (g_b2) v2.x = 0.0;
  371. // OutColor = vec4(v2.x,v2.x,0.0,1.0);
  372. // }
  373. const std::string before_predefs =
  374. R"(OpCapability Shader
  375. %1 = OpExtInstImport "GLSL.std.450"
  376. OpMemoryModel Logical GLSL450
  377. OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
  378. OpExecutionMode %main OriginUpperLeft
  379. OpSource GLSL 450
  380. OpName %main "main"
  381. OpName %In0 "In0"
  382. OpName %In1 "In1"
  383. OpName %In2 "In2"
  384. OpName %_Globals_ "_Globals_"
  385. OpMemberName %_Globals_ 0 "g_b"
  386. OpMemberName %_Globals_ 1 "g_b2"
  387. OpName %_ ""
  388. OpName %OutColor "OutColor"
  389. OpDecorate %In0 Location 0
  390. OpDecorate %In1 Location 1
  391. OpDecorate %In2 Location 2
  392. OpMemberDecorate %_Globals_ 0 Offset 0
  393. OpMemberDecorate %_Globals_ 1 Offset 4
  394. OpDecorate %_Globals_ Block
  395. OpDecorate %_ DescriptorSet 0
  396. OpDecorate %_ Binding 0
  397. OpDecorate %OutColor Location 0
  398. %void = OpTypeVoid
  399. %10 = OpTypeFunction %void
  400. %float = OpTypeFloat 32
  401. %v4float = OpTypeVector %float 4
  402. %_ptr_Function_v4float = OpTypePointer Function %v4float
  403. %_ptr_Input_v4float = OpTypePointer Input %v4float
  404. %In0 = OpVariable %_ptr_Input_v4float Input
  405. %_ptr_Input_float = OpTypePointer Input %float
  406. %In1 = OpVariable %_ptr_Input_float Input
  407. %In2 = OpVariable %_ptr_Input_float Input
  408. %uint = OpTypeInt 32 0
  409. %_Globals_ = OpTypeStruct %uint %uint
  410. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  411. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  412. %int = OpTypeInt 32 1
  413. %int_0 = OpConstant %int 0
  414. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  415. %bool = OpTypeBool
  416. %uint_0 = OpConstant %uint 0
  417. %float_1 = OpConstant %float 1
  418. %int_1 = OpConstant %int 1
  419. %float_0 = OpConstant %float 0
  420. %_ptr_Output_v4float = OpTypePointer Output %v4float
  421. %OutColor = OpVariable %_ptr_Output_v4float Output
  422. %27 = OpUndef %v4float
  423. )";
  424. const std::string after_predefs =
  425. R"(OpCapability Shader
  426. %1 = OpExtInstImport "GLSL.std.450"
  427. OpMemoryModel Logical GLSL450
  428. OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
  429. OpExecutionMode %main OriginUpperLeft
  430. OpSource GLSL 450
  431. OpName %main "main"
  432. OpName %In0 "In0"
  433. OpName %In1 "In1"
  434. OpName %In2 "In2"
  435. OpName %_Globals_ "_Globals_"
  436. OpMemberName %_Globals_ 0 "g_b"
  437. OpMemberName %_Globals_ 1 "g_b2"
  438. OpName %_ ""
  439. OpName %OutColor "OutColor"
  440. OpDecorate %In0 Location 0
  441. OpDecorate %In1 Location 1
  442. OpDecorate %In2 Location 2
  443. OpMemberDecorate %_Globals_ 0 Offset 0
  444. OpMemberDecorate %_Globals_ 1 Offset 4
  445. OpDecorate %_Globals_ Block
  446. OpDecorate %_ DescriptorSet 0
  447. OpDecorate %_ Binding 0
  448. OpDecorate %OutColor Location 0
  449. %void = OpTypeVoid
  450. %10 = OpTypeFunction %void
  451. %float = OpTypeFloat 32
  452. %v4float = OpTypeVector %float 4
  453. %_ptr_Function_v4float = OpTypePointer Function %v4float
  454. %_ptr_Input_v4float = OpTypePointer Input %v4float
  455. %In0 = OpVariable %_ptr_Input_v4float Input
  456. %_ptr_Input_float = OpTypePointer Input %float
  457. %In1 = OpVariable %_ptr_Input_float Input
  458. %In2 = OpVariable %_ptr_Input_float Input
  459. %uint = OpTypeInt 32 0
  460. %_Globals_ = OpTypeStruct %uint %uint
  461. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  462. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  463. %int = OpTypeInt 32 1
  464. %int_0 = OpConstant %int 0
  465. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  466. %bool = OpTypeBool
  467. %uint_0 = OpConstant %uint 0
  468. %float_1 = OpConstant %float 1
  469. %int_1 = OpConstant %int 1
  470. %float_0 = OpConstant %float 0
  471. %_ptr_Output_v4float = OpTypePointer Output %v4float
  472. %OutColor = OpVariable %_ptr_Output_v4float Output
  473. %27 = OpUndef %v4float
  474. %55 = OpUndef %v4float
  475. )";
  476. const std::string before =
  477. R"(%main = OpFunction %void None %10
  478. %28 = OpLabel
  479. %29 = OpLoad %v4float %In0
  480. %30 = OpLoad %float %In1
  481. %31 = OpLoad %float %In2
  482. %32 = OpFAdd %float %30 %31
  483. %33 = OpCompositeInsert %v4float %32 %29 1
  484. %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  485. %35 = OpLoad %uint %34
  486. %36 = OpINotEqual %bool %35 %uint_0
  487. OpSelectionMerge %37 None
  488. OpBranchConditional %36 %38 %37
  489. %38 = OpLabel
  490. %39 = OpCompositeInsert %v4float %float_1 %33 0
  491. OpBranch %37
  492. %37 = OpLabel
  493. %40 = OpPhi %v4float %33 %28 %39 %38
  494. %41 = OpCompositeExtract %float %40 0
  495. %42 = OpCompositeInsert %v4float %41 %27 0
  496. %43 = OpCompositeExtract %float %40 1
  497. %44 = OpCompositeInsert %v4float %43 %42 1
  498. %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
  499. %46 = OpLoad %uint %45
  500. %47 = OpINotEqual %bool %46 %uint_0
  501. OpSelectionMerge %48 None
  502. OpBranchConditional %47 %49 %48
  503. %49 = OpLabel
  504. %50 = OpCompositeInsert %v4float %float_0 %44 0
  505. OpBranch %48
  506. %48 = OpLabel
  507. %51 = OpPhi %v4float %44 %37 %50 %49
  508. %52 = OpCompositeExtract %float %51 0
  509. %53 = OpCompositeExtract %float %51 0
  510. %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
  511. OpStore %OutColor %54
  512. OpReturn
  513. OpFunctionEnd
  514. )";
  515. const std::string after =
  516. R"(%main = OpFunction %void None %10
  517. %28 = OpLabel
  518. %29 = OpLoad %v4float %In0
  519. %30 = OpLoad %float %In1
  520. %31 = OpLoad %float %In2
  521. %32 = OpFAdd %float %30 %31
  522. %33 = OpCompositeInsert %v4float %32 %29 1
  523. %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  524. %35 = OpLoad %uint %34
  525. %36 = OpINotEqual %bool %35 %uint_0
  526. OpSelectionMerge %37 None
  527. OpBranchConditional %36 %38 %37
  528. %38 = OpLabel
  529. %39 = OpCompositeInsert %v4float %float_1 %55 0
  530. OpBranch %37
  531. %37 = OpLabel
  532. %40 = OpPhi %v4float %29 %28 %39 %38
  533. %41 = OpCompositeExtract %float %40 0
  534. %42 = OpCompositeInsert %v4float %41 %55 0
  535. %43 = OpCompositeExtract %float %40 1
  536. %44 = OpCompositeInsert %v4float %43 %42 1
  537. %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
  538. %46 = OpLoad %uint %45
  539. %47 = OpINotEqual %bool %46 %uint_0
  540. OpSelectionMerge %48 None
  541. OpBranchConditional %47 %49 %48
  542. %49 = OpLabel
  543. %50 = OpCompositeInsert %v4float %float_0 %55 0
  544. OpBranch %48
  545. %48 = OpLabel
  546. %51 = OpPhi %v4float %42 %37 %50 %49
  547. %52 = OpCompositeExtract %float %51 0
  548. %53 = OpCompositeExtract %float %51 0
  549. %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
  550. OpStore %OutColor %54
  551. OpReturn
  552. OpFunctionEnd
  553. )";
  554. SinglePassRunAndCheck<VectorDCE>(before_predefs + before,
  555. after_predefs + after, true, true);
  556. }
  557. TEST_F(VectorDCETest, InsertObjectLive) {
  558. // Make sure that the object being inserted in an OpCompositeInsert
  559. // is not removed when it is uses later on.
  560. const std::string before =
  561. R"(OpCapability Shader
  562. %1 = OpExtInstImport "GLSL.std.450"
  563. OpMemoryModel Logical GLSL450
  564. OpEntryPoint Fragment %main "main" %In0 %In1 %OutColor
  565. OpExecutionMode %main OriginUpperLeft
  566. OpSource GLSL 450
  567. OpName %main "main"
  568. OpName %In0 "In0"
  569. OpName %In1 "In1"
  570. OpName %OutColor "OutColor"
  571. OpDecorate %In0 Location 0
  572. OpDecorate %In1 Location 1
  573. OpDecorate %OutColor Location 0
  574. %void = OpTypeVoid
  575. %10 = OpTypeFunction %void
  576. %float = OpTypeFloat 32
  577. %v4float = OpTypeVector %float 4
  578. %_ptr_Input_v4float = OpTypePointer Input %v4float
  579. %In0 = OpVariable %_ptr_Input_v4float Input
  580. %_ptr_Input_float = OpTypePointer Input %float
  581. %In1 = OpVariable %_ptr_Input_float Input
  582. %_ptr_Output_v4float = OpTypePointer Output %v4float
  583. %OutColor = OpVariable %_ptr_Output_v4float Output
  584. %main = OpFunction %void None %10
  585. %28 = OpLabel
  586. %29 = OpLoad %v4float %In0
  587. %30 = OpLoad %float %In1
  588. %33 = OpCompositeInsert %v4float %30 %29 1
  589. OpStore %OutColor %33
  590. OpReturn
  591. OpFunctionEnd
  592. )";
  593. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  594. SinglePassRunAndCheck<VectorDCE>(before, before, true, true);
  595. }
  596. TEST_F(VectorDCETest, DeadInsertInCycle) {
  597. // Dead insert in chain with cycle. Demonstrates analysis can handle
  598. // cycles in chains going through scalars intermediate values.
  599. //
  600. // Note: The SPIR-V assembly has had store/load elimination
  601. // performed to allow the inserts and extracts to directly
  602. // reference each other.
  603. //
  604. // #version 450
  605. //
  606. // layout (location=0) in vec4 In0;
  607. // layout (location=1) in float In1;
  608. // layout (location=2) in float In2;
  609. // layout (location=0) out vec4 OutColor;
  610. //
  611. // layout(std140, binding = 0 ) uniform _Globals_
  612. // {
  613. // int g_n ;
  614. // };
  615. //
  616. // void main()
  617. // {
  618. // vec2 v = vec2(0.0, 1.0);
  619. // for (int i = 0; i < g_n; i++) {
  620. // v.x = v.x + 1;
  621. // v.y = v.y * 0.9; // dead
  622. // }
  623. // OutColor = vec4(v.x);
  624. // }
  625. const std::string assembly =
  626. R"(
  627. ; CHECK: [[init_val:%\w+]] = OpConstantComposite %v2float %float_0 %float_1
  628. ; CHECK: [[undef:%\w+]] = OpUndef %v2float
  629. ; CHECK: OpFunction
  630. ; CHECK: [[entry_lab:%\w+]] = OpLabel
  631. ; CHECK: [[loop_header:%\w+]] = OpLabel
  632. ; CHECK: OpPhi %v2float [[init_val]] [[entry_lab]] [[x_insert:%\w+]] {{%\w+}}
  633. ; CHECK: [[x_insert:%\w+]] = OpCompositeInsert %v2float %43 [[undef]] 0
  634. OpCapability Shader
  635. %1 = OpExtInstImport "GLSL.std.450"
  636. OpMemoryModel Logical GLSL450
  637. OpEntryPoint Fragment %main "main" %OutColor %In0 %In1 %In2
  638. OpExecutionMode %main OriginUpperLeft
  639. OpSource GLSL 450
  640. OpName %main "main"
  641. OpName %_Globals_ "_Globals_"
  642. OpMemberName %_Globals_ 0 "g_n"
  643. OpName %_ ""
  644. OpName %OutColor "OutColor"
  645. OpName %In0 "In0"
  646. OpName %In1 "In1"
  647. OpName %In2 "In2"
  648. OpMemberDecorate %_Globals_ 0 Offset 0
  649. OpDecorate %_Globals_ Block
  650. OpDecorate %_ DescriptorSet 0
  651. OpDecorate %_ Binding 0
  652. OpDecorate %OutColor Location 0
  653. OpDecorate %In0 Location 0
  654. OpDecorate %In1 Location 1
  655. OpDecorate %In2 Location 2
  656. %void = OpTypeVoid
  657. %10 = OpTypeFunction %void
  658. %float = OpTypeFloat 32
  659. %v2float = OpTypeVector %float 2
  660. %_ptr_Function_v2float = OpTypePointer Function %v2float
  661. %float_0 = OpConstant %float 0
  662. %float_1 = OpConstant %float 1
  663. %16 = OpConstantComposite %v2float %float_0 %float_1
  664. %int = OpTypeInt 32 1
  665. %_ptr_Function_int = OpTypePointer Function %int
  666. %int_0 = OpConstant %int 0
  667. %_Globals_ = OpTypeStruct %int
  668. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  669. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  670. %_ptr_Uniform_int = OpTypePointer Uniform %int
  671. %bool = OpTypeBool
  672. %float_0_75 = OpConstant %float 0.75
  673. %int_1 = OpConstant %int 1
  674. %v4float = OpTypeVector %float 4
  675. %_ptr_Output_v4float = OpTypePointer Output %v4float
  676. %OutColor = OpVariable %_ptr_Output_v4float Output
  677. %_ptr_Input_v4float = OpTypePointer Input %v4float
  678. %In0 = OpVariable %_ptr_Input_v4float Input
  679. %_ptr_Input_float = OpTypePointer Input %float
  680. %In1 = OpVariable %_ptr_Input_float Input
  681. %In2 = OpVariable %_ptr_Input_float Input
  682. %main = OpFunction %void None %10
  683. %29 = OpLabel
  684. OpBranch %30
  685. %30 = OpLabel
  686. %31 = OpPhi %v2float %16 %29 %32 %33
  687. %34 = OpPhi %int %int_0 %29 %35 %33
  688. OpLoopMerge %36 %33 None
  689. OpBranch %37
  690. %37 = OpLabel
  691. %38 = OpAccessChain %_ptr_Uniform_int %_ %int_0
  692. %39 = OpLoad %int %38
  693. %40 = OpSLessThan %bool %34 %39
  694. OpBranchConditional %40 %41 %36
  695. %41 = OpLabel
  696. %42 = OpCompositeExtract %float %31 0
  697. %43 = OpFAdd %float %42 %float_1
  698. %44 = OpCompositeInsert %v2float %43 %31 0
  699. %45 = OpCompositeExtract %float %44 1
  700. %46 = OpFMul %float %45 %float_0_75
  701. %32 = OpCompositeInsert %v2float %46 %44 1
  702. OpBranch %33
  703. %33 = OpLabel
  704. %35 = OpIAdd %int %34 %int_1
  705. OpBranch %30
  706. %36 = OpLabel
  707. %47 = OpCompositeExtract %float %31 0
  708. %48 = OpCompositeConstruct %v4float %47 %47 %47 %47
  709. OpStore %OutColor %48
  710. OpReturn
  711. OpFunctionEnd
  712. )";
  713. SinglePassRunAndMatch<VectorDCE>(assembly, true);
  714. }
  715. TEST_F(VectorDCETest, DeadLoadFeedingCompositeConstruct) {
  716. // Detach the loads feeding the CompositeConstruct for the unused elements.
  717. // TODO: Implement the rewrite for CompositeConstruct.
  718. const std::string assembly =
  719. R"(
  720. ; CHECK: [[undef:%\w+]] = OpUndef %float
  721. ; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Input_float %In0 %uint_2
  722. ; CHECK: [[load:%\w+]] = OpLoad %float [[ac]]
  723. ; CHECK: OpCompositeConstruct %v3float [[load]] [[undef]] [[undef]]
  724. OpCapability Shader
  725. %1 = OpExtInstImport "GLSL.std.450"
  726. OpMemoryModel Logical GLSL450
  727. OpEntryPoint Fragment %main "main" %In0 %OutColor
  728. OpExecutionMode %main OriginUpperLeft
  729. OpSource GLSL 450
  730. OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
  731. OpSourceExtension "GL_GOOGLE_include_directive"
  732. OpName %main "main"
  733. OpName %In0 "In0"
  734. OpName %OutColor "OutColor"
  735. OpDecorate %In0 Location 0
  736. OpDecorate %OutColor Location 0
  737. %void = OpTypeVoid
  738. %6 = OpTypeFunction %void
  739. %float = OpTypeFloat 32
  740. %v4float = OpTypeVector %float 4
  741. %_ptr_Input_v4float = OpTypePointer Input %v4float
  742. %In0 = OpVariable %_ptr_Input_v4float Input
  743. %uint = OpTypeInt 32 0
  744. %uint_0 = OpConstant %uint 0
  745. %_ptr_Input_float = OpTypePointer Input %float
  746. %uint_1 = OpConstant %uint 1
  747. %uint_2 = OpConstant %uint 2
  748. %v3float = OpTypeVector %float 3
  749. %int = OpTypeInt 32 1
  750. %int_0 = OpConstant %int 0
  751. %int_20 = OpConstant %int 20
  752. %bool = OpTypeBool
  753. %float_1 = OpConstant %float 1
  754. %int_1 = OpConstant %int 1
  755. %_ptr_Output_v4float = OpTypePointer Output %v4float
  756. %OutColor = OpVariable %_ptr_Output_v4float Output
  757. %23 = OpUndef %v3float
  758. %main = OpFunction %void None %6
  759. %24 = OpLabel
  760. %25 = OpAccessChain %_ptr_Input_float %In0 %uint_0
  761. %26 = OpLoad %float %25
  762. %27 = OpAccessChain %_ptr_Input_float %In0 %uint_1
  763. %28 = OpLoad %float %27
  764. %29 = OpAccessChain %_ptr_Input_float %In0 %uint_2
  765. %30 = OpLoad %float %29
  766. %31 = OpCompositeConstruct %v3float %30 %28 %26
  767. OpBranch %32
  768. %32 = OpLabel
  769. %33 = OpPhi %v3float %31 %24 %34 %35
  770. %36 = OpPhi %int %int_0 %24 %37 %35
  771. OpLoopMerge %38 %35 None
  772. OpBranch %39
  773. %39 = OpLabel
  774. %40 = OpSLessThan %bool %36 %int_20
  775. OpBranchConditional %40 %41 %38
  776. %41 = OpLabel
  777. %42 = OpCompositeExtract %float %33 0
  778. %43 = OpFAdd %float %42 %float_1
  779. %34 = OpCompositeInsert %v3float %43 %33 0
  780. OpBranch %35
  781. %35 = OpLabel
  782. %37 = OpIAdd %int %36 %int_1
  783. OpBranch %32
  784. %38 = OpLabel
  785. %44 = OpCompositeExtract %float %33 0
  786. %45 = OpCompositeConstruct %v4float %44 %44 %44 %44
  787. OpStore %OutColor %45
  788. OpReturn
  789. OpFunctionEnd
  790. )";
  791. SinglePassRunAndMatch<VectorDCE>(assembly, true);
  792. }
  793. TEST_F(VectorDCETest, DeadLoadFeedingVectorShuffle) {
  794. // Detach the loads feeding the CompositeConstruct for the unused elements.
  795. // TODO: Implement the rewrite for CompositeConstruct.
  796. const std::string assembly =
  797. R"(
  798. ; MemPass Type2Undef does not reuse and already existing undef.
  799. ; CHECK: {{%\w+}} = OpUndef %v3float
  800. ; CHECK: [[undef:%\w+]] = OpUndef %v3float
  801. ; CHECK: OpFunction
  802. ; CHECK: OpVectorShuffle %v3float {{%\w+}} [[undef]] 0 4 5
  803. OpCapability Shader
  804. %1 = OpExtInstImport "GLSL.std.450"
  805. OpMemoryModel Logical GLSL450
  806. OpEntryPoint Fragment %main "main" %In0 %OutColor
  807. OpExecutionMode %main OriginUpperLeft
  808. OpSource GLSL 450
  809. OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
  810. OpSourceExtension "GL_GOOGLE_include_directive"
  811. OpName %main "main"
  812. OpName %In0 "In0"
  813. OpName %OutColor "OutColor"
  814. OpDecorate %In0 Location 0
  815. OpDecorate %OutColor Location 0
  816. %void = OpTypeVoid
  817. %6 = OpTypeFunction %void
  818. %float = OpTypeFloat 32
  819. %v4float = OpTypeVector %float 4
  820. %_ptr_Input_v4float = OpTypePointer Input %v4float
  821. %In0 = OpVariable %_ptr_Input_v4float Input
  822. %uint = OpTypeInt 32 0
  823. %uint_0 = OpConstant %uint 0
  824. %_ptr_Input_float = OpTypePointer Input %float
  825. %uint_1 = OpConstant %uint 1
  826. %uint_2 = OpConstant %uint 2
  827. %v3float = OpTypeVector %float 3
  828. %int = OpTypeInt 32 1
  829. %int_0 = OpConstant %int 0
  830. %int_20 = OpConstant %int 20
  831. %bool = OpTypeBool
  832. %float_1 = OpConstant %float 1
  833. %vec_const = OpConstantComposite %v3float %float_1 %float_1 %float_1
  834. %int_1 = OpConstant %int 1
  835. %_ptr_Output_v4float = OpTypePointer Output %v4float
  836. %OutColor = OpVariable %_ptr_Output_v4float Output
  837. %23 = OpUndef %v3float
  838. %main = OpFunction %void None %6
  839. %24 = OpLabel
  840. %25 = OpAccessChain %_ptr_Input_float %In0 %uint_0
  841. %26 = OpLoad %float %25
  842. %27 = OpAccessChain %_ptr_Input_float %In0 %uint_1
  843. %28 = OpLoad %float %27
  844. %29 = OpAccessChain %_ptr_Input_float %In0 %uint_2
  845. %30 = OpLoad %float %29
  846. %31 = OpCompositeConstruct %v3float %30 %28 %26
  847. %sh = OpVectorShuffle %v3float %vec_const %31 0 4 5
  848. OpBranch %32
  849. %32 = OpLabel
  850. %33 = OpPhi %v3float %sh %24 %34 %35
  851. %36 = OpPhi %int %int_0 %24 %37 %35
  852. OpLoopMerge %38 %35 None
  853. OpBranch %39
  854. %39 = OpLabel
  855. %40 = OpSLessThan %bool %36 %int_20
  856. OpBranchConditional %40 %41 %38
  857. %41 = OpLabel
  858. %42 = OpCompositeExtract %float %33 0
  859. %43 = OpFAdd %float %42 %float_1
  860. %34 = OpCompositeInsert %v3float %43 %33 0
  861. OpBranch %35
  862. %35 = OpLabel
  863. %37 = OpIAdd %int %36 %int_1
  864. OpBranch %32
  865. %38 = OpLabel
  866. %44 = OpCompositeExtract %float %33 0
  867. %45 = OpCompositeConstruct %v4float %44 %44 %44 %44
  868. OpStore %OutColor %45
  869. OpReturn
  870. OpFunctionEnd
  871. )";
  872. SinglePassRunAndMatch<VectorDCE>(assembly, true);
  873. }
  874. TEST_F(VectorDCETest, DeadInstThroughShuffle) {
  875. // Dead insert in chain with cycle. Demonstrates analysis can handle
  876. // cycles in chains.
  877. //
  878. // Note: The SPIR-V assembly has had store/load elimination
  879. // performed to allow the inserts and extracts to directly
  880. // reference each other.
  881. //
  882. // #version 450
  883. //
  884. // layout (location=0) out vec4 OutColor;
  885. //
  886. // void main()
  887. // {
  888. // vec2 v;
  889. // v.x = 0.0;
  890. // v.y = 0.1; // dead
  891. // for (int i = 0; i < 20; i++) {
  892. // v.x = v.x + 1;
  893. // v = v * 0.9;
  894. // }
  895. // OutColor = vec4(v.x);
  896. // }
  897. const std::string assembly =
  898. R"(
  899. ; CHECK: OpFunction
  900. ; CHECK-NOT: OpCompositeInsert %v2float {{%\w+}} 1
  901. ; CHECK: OpFunctionEnd
  902. OpCapability Shader
  903. %1 = OpExtInstImport "GLSL.std.450"
  904. OpMemoryModel Logical GLSL450
  905. OpEntryPoint Fragment %main "main" %OutColor
  906. OpExecutionMode %main OriginUpperLeft
  907. OpSource GLSL 450
  908. OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
  909. OpSourceExtension "GL_GOOGLE_include_directive"
  910. OpName %main "main"
  911. OpName %OutColor "OutColor"
  912. OpDecorate %OutColor Location 0
  913. %void = OpTypeVoid
  914. %3 = OpTypeFunction %void
  915. %float = OpTypeFloat 32
  916. %v2float = OpTypeVector %float 2
  917. %float_0 = OpConstant %float 0
  918. %float_0_100000001 = OpConstant %float 0.100000001
  919. %int = OpTypeInt 32 1
  920. %int_0 = OpConstant %int 0
  921. %int_20 = OpConstant %int 20
  922. %bool = OpTypeBool
  923. %float_1 = OpConstant %float 1
  924. %float_0_899999976 = OpConstant %float 0.899999976
  925. %int_1 = OpConstant %int 1
  926. %v4float = OpTypeVector %float 4
  927. %_ptr_Output_v4float = OpTypePointer Output %v4float
  928. %OutColor = OpVariable %_ptr_Output_v4float Output
  929. %58 = OpUndef %v2float
  930. %main = OpFunction %void None %3
  931. %5 = OpLabel
  932. %49 = OpCompositeInsert %v2float %float_0 %58 0
  933. %51 = OpCompositeInsert %v2float %float_0_100000001 %49 1
  934. OpBranch %22
  935. %22 = OpLabel
  936. %60 = OpPhi %v2float %51 %5 %38 %25
  937. %59 = OpPhi %int %int_0 %5 %41 %25
  938. OpLoopMerge %24 %25 None
  939. OpBranch %26
  940. %26 = OpLabel
  941. %30 = OpSLessThan %bool %59 %int_20
  942. OpBranchConditional %30 %23 %24
  943. %23 = OpLabel
  944. %53 = OpCompositeExtract %float %60 0
  945. %34 = OpFAdd %float %53 %float_1
  946. %55 = OpCompositeInsert %v2float %34 %60 0
  947. %38 = OpVectorTimesScalar %v2float %55 %float_0_899999976
  948. OpBranch %25
  949. %25 = OpLabel
  950. %41 = OpIAdd %int %59 %int_1
  951. OpBranch %22
  952. %24 = OpLabel
  953. %57 = OpCompositeExtract %float %60 0
  954. %47 = OpCompositeConstruct %v4float %57 %57 %57 %57
  955. OpStore %OutColor %47
  956. OpReturn
  957. OpFunctionEnd
  958. )";
  959. SinglePassRunAndMatch<VectorDCE>(assembly, true);
  960. }
  961. TEST_F(VectorDCETest, DeadInsertThroughOtherInst) {
  962. // Dead insert in chain with cycle. Demonstrates analysis can handle
  963. // cycles in chains.
  964. //
  965. // Note: The SPIR-V assembly has had store/load elimination
  966. // performed to allow the inserts and extracts to directly
  967. // reference each other.
  968. //
  969. // #version 450
  970. //
  971. // layout (location=0) out vec4 OutColor;
  972. //
  973. // void main()
  974. // {
  975. // vec2 v;
  976. // v.x = 0.0;
  977. // v.y = 0.1; // dead
  978. // for (int i = 0; i < 20; i++) {
  979. // v.x = v.x + 1;
  980. // v = v * 0.9;
  981. // }
  982. // OutColor = vec4(v.x);
  983. // }
  984. const std::string assembly =
  985. R"(
  986. ; CHECK: OpFunction
  987. ; CHECK-NOT: OpCompositeInsert %v2float {{%\w+}} 1
  988. ; CHECK: OpFunctionEnd
  989. OpCapability Shader
  990. %1 = OpExtInstImport "GLSL.std.450"
  991. OpMemoryModel Logical GLSL450
  992. OpEntryPoint Fragment %main "main" %OutColor
  993. OpExecutionMode %main OriginUpperLeft
  994. OpSource GLSL 450
  995. OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
  996. OpSourceExtension "GL_GOOGLE_include_directive"
  997. OpName %main "main"
  998. OpName %OutColor "OutColor"
  999. OpDecorate %OutColor Location 0
  1000. %void = OpTypeVoid
  1001. %3 = OpTypeFunction %void
  1002. %float = OpTypeFloat 32
  1003. %v2float = OpTypeVector %float 2
  1004. %float_0 = OpConstant %float 0
  1005. %float_0_100000001 = OpConstant %float 0.100000001
  1006. %int = OpTypeInt 32 1
  1007. %int_0 = OpConstant %int 0
  1008. %int_20 = OpConstant %int 20
  1009. %bool = OpTypeBool
  1010. %float_1 = OpConstant %float 1
  1011. %float_0_899999976 = OpConstant %float 0.899999976
  1012. %int_1 = OpConstant %int 1
  1013. %v4float = OpTypeVector %float 4
  1014. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1015. %OutColor = OpVariable %_ptr_Output_v4float Output
  1016. %58 = OpUndef %v2float
  1017. %main = OpFunction %void None %3
  1018. %5 = OpLabel
  1019. %49 = OpCompositeInsert %v2float %float_0 %58 0
  1020. %51 = OpCompositeInsert %v2float %float_0_100000001 %49 1
  1021. OpBranch %22
  1022. %22 = OpLabel
  1023. %60 = OpPhi %v2float %51 %5 %38 %25
  1024. %59 = OpPhi %int %int_0 %5 %41 %25
  1025. OpLoopMerge %24 %25 None
  1026. OpBranch %26
  1027. %26 = OpLabel
  1028. %30 = OpSLessThan %bool %59 %int_20
  1029. OpBranchConditional %30 %23 %24
  1030. %23 = OpLabel
  1031. %53 = OpCompositeExtract %float %60 0
  1032. %34 = OpFAdd %float %53 %float_1
  1033. %55 = OpCompositeInsert %v2float %34 %60 0
  1034. %38 = OpVectorTimesScalar %v2float %55 %float_0_899999976
  1035. OpBranch %25
  1036. %25 = OpLabel
  1037. %41 = OpIAdd %int %59 %int_1
  1038. OpBranch %22
  1039. %24 = OpLabel
  1040. %57 = OpCompositeExtract %float %60 0
  1041. %47 = OpCompositeConstruct %v4float %57 %57 %57 %57
  1042. OpStore %OutColor %47
  1043. OpReturn
  1044. OpFunctionEnd
  1045. )";
  1046. SinglePassRunAndMatch<VectorDCE>(assembly, true);
  1047. }
  1048. TEST_F(VectorDCETest, VectorIntoCompositeConstruct) {
  1049. const std::string text = R"(OpCapability Linkage
  1050. OpCapability Shader
  1051. OpMemoryModel Logical GLSL450
  1052. OpEntryPoint Fragment %1 "EntryPoint_Main" %2 %3
  1053. OpExecutionMode %1 OriginUpperLeft
  1054. OpDecorate %2 Location 0
  1055. OpDecorate %_struct_4 Block
  1056. OpDecorate %3 Location 0
  1057. %float = OpTypeFloat 32
  1058. %v2float = OpTypeVector %float 2
  1059. %_ptr_Function_v2float = OpTypePointer Function %v2float
  1060. %v4float = OpTypeVector %float 4
  1061. %_ptr_Function_v4float = OpTypePointer Function %v4float
  1062. %mat4v4float = OpTypeMatrix %v4float 4
  1063. %_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
  1064. %v3float = OpTypeVector %float 3
  1065. %_ptr_Function_v3float = OpTypePointer Function %v3float
  1066. %_struct_14 = OpTypeStruct %v2float %mat4v4float %v3float %v2float %v4float
  1067. %_ptr_Function__struct_14 = OpTypePointer Function %_struct_14
  1068. %void = OpTypeVoid
  1069. %int = OpTypeInt 32 1
  1070. %int_2 = OpConstant %int 2
  1071. %int_1 = OpConstant %int 1
  1072. %int_4 = OpConstant %int 4
  1073. %int_0 = OpConstant %int 0
  1074. %int_3 = OpConstant %int 3
  1075. %float_0 = OpConstant %float 0
  1076. %float_1 = OpConstant %float 1
  1077. %_ptr_Input_v2float = OpTypePointer Input %v2float
  1078. %2 = OpVariable %_ptr_Input_v2float Input
  1079. %_ptr_Output_v2float = OpTypePointer Output %v2float
  1080. %_struct_4 = OpTypeStruct %v2float
  1081. %_ptr_Output__struct_4 = OpTypePointer Output %_struct_4
  1082. %3 = OpVariable %_ptr_Output__struct_4 Output
  1083. %28 = OpTypeFunction %void
  1084. %29 = OpConstantComposite %v2float %float_0 %float_0
  1085. %30 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
  1086. %31 = OpConstantComposite %mat4v4float %30 %30 %30 %30
  1087. %32 = OpConstantComposite %v3float %float_0 %float_0 %float_0
  1088. %1 = OpFunction %void None %28
  1089. %33 = OpLabel
  1090. %34 = OpVariable %_ptr_Function_v4float Function
  1091. %35 = OpVariable %_ptr_Function__struct_14 Function
  1092. %36 = OpAccessChain %_ptr_Function_v2float %35 %int_0
  1093. OpStore %36 %29
  1094. %37 = OpAccessChain %_ptr_Function_mat4v4float %35 %int_1
  1095. OpStore %37 %31
  1096. %38 = OpAccessChain %_ptr_Function_v3float %35 %int_2
  1097. OpStore %38 %32
  1098. %39 = OpAccessChain %_ptr_Function_v2float %35 %int_3
  1099. OpStore %39 %29
  1100. %40 = OpAccessChain %_ptr_Function_v4float %35 %int_4
  1101. OpStore %40 %30
  1102. %41 = OpLoad %v2float %2
  1103. OpStore %36 %41
  1104. %42 = OpLoad %v3float %38
  1105. %43 = OpCompositeConstruct %v4float %42 %float_1
  1106. %44 = OpLoad %mat4v4float %37
  1107. %45 = OpVectorTimesMatrix %v4float %43 %44
  1108. OpStore %34 %45
  1109. OpCopyMemory %40 %34
  1110. OpCopyMemory %36 %39
  1111. %46 = OpAccessChain %_ptr_Output_v2float %3 %int_0
  1112. %47 = OpLoad %v2float %36
  1113. OpStore %46 %47
  1114. OpReturn
  1115. OpFunctionEnd
  1116. )";
  1117. SinglePassRunAndCheck<VectorDCE>(text, text, true, true);
  1118. }
  1119. TEST_F(VectorDCETest, NotAffectedByDebugValue) {
  1120. // It tests that an OpenCL.DebugInfo.100 DebugValue instruction does
  1121. // not change the vector DCE pass result. If the composite used for
  1122. // the value of DebugValue is killed, the DebugValue must be killed as well.
  1123. const std::string text = R"(
  1124. OpCapability Shader
  1125. %1 = OpExtInstImport "GLSL.std.450"
  1126. %ext = OpExtInstImport "OpenCL.DebugInfo.100"
  1127. OpMemoryModel Logical GLSL450
  1128. OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
  1129. OpExecutionMode %main OriginUpperLeft
  1130. OpSource GLSL 450
  1131. %file_name = OpString "test"
  1132. %float_name = OpString "float"
  1133. %main_name = OpString "main"
  1134. %f_name = OpString "f"
  1135. OpName %main "main"
  1136. OpName %In2 "In2"
  1137. OpName %In0 "In0"
  1138. OpName %In1 "In1"
  1139. OpName %OutColor "OutColor"
  1140. OpName %_Globals_ "_Globals_"
  1141. OpMemberName %_Globals_ 0 "g_b"
  1142. OpMemberName %_Globals_ 1 "g_n"
  1143. OpName %_ ""
  1144. OpDecorate %In2 Location 2
  1145. OpDecorate %In0 Location 0
  1146. OpDecorate %In1 Location 1
  1147. OpDecorate %OutColor Location 0
  1148. OpMemberDecorate %_Globals_ 0 Offset 0
  1149. OpMemberDecorate %_Globals_ 1 Offset 4
  1150. OpDecorate %_Globals_ Block
  1151. OpDecorate %_ DescriptorSet 0
  1152. OpDecorate %_ Binding 0
  1153. %void = OpTypeVoid
  1154. %11 = OpTypeFunction %void
  1155. %float = OpTypeFloat 32
  1156. %v2float = OpTypeVector %float 2
  1157. %_ptr_Function_v2float = OpTypePointer Function %v2float
  1158. %_ptr_Input_v2float = OpTypePointer Input %v2float
  1159. %In2 = OpVariable %_ptr_Input_v2float Input
  1160. %_ptr_Input_float = OpTypePointer Input %float
  1161. %In0 = OpVariable %_ptr_Input_float Input
  1162. %In1 = OpVariable %_ptr_Input_float Input
  1163. %uint = OpTypeInt 32 0
  1164. %uint_32 = OpConstant %uint 32
  1165. %_ptr_Function_float = OpTypePointer Function %float
  1166. %float_0 = OpConstant %float 0
  1167. %v4float = OpTypeVector %float 4
  1168. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1169. %OutColor = OpVariable %_ptr_Output_v4float Output
  1170. %int = OpTypeInt 32 1
  1171. %_Globals_ = OpTypeStruct %uint %int
  1172. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  1173. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  1174. %null_expr = OpExtInst %void %ext DebugExpression
  1175. %src = OpExtInst %void %ext DebugSource %file_name
  1176. %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
  1177. %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
  1178. %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_tf
  1179. %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
  1180. %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
  1181. %main = OpFunction %void None %11
  1182. %25 = OpLabel
  1183. %s = OpExtInst %void %ext DebugScope %dbg_main
  1184. ; CHECK: [[in2:%\w+]] = OpLoad %v2float %In2
  1185. %26 = OpLoad %v2float %In2
  1186. %27 = OpLoad %float %In0
  1187. %28 = OpLoad %float %In1
  1188. %29 = OpFAdd %float %27 %28
  1189. ; CHECK: OpCompositeInsert %v2float {{%\w+}} [[in2]] 0
  1190. ; CHECK-NEXT: OpCompositeInsert %v2float {{%\w+}} [[in2]] 0
  1191. ; CHECK-NOT: DebugValue
  1192. %35 = OpCompositeInsert %v2float %29 %26 0
  1193. %value = OpExtInst %void %ext DebugValue %dbg_f %35 %null_expr
  1194. %37 = OpCompositeInsert %v2float %float_0 %35 0
  1195. %33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
  1196. OpStore %OutColor %33
  1197. OpReturn
  1198. OpFunctionEnd
  1199. )";
  1200. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1201. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1202. SinglePassRunAndMatch<VectorDCE>(text, true);
  1203. }
  1204. TEST_F(VectorDCETest, RemoveDebugValueUsesKilledInstr) {
  1205. // It tests that the vector DCE pass removes the OpenCL.DebugInfo.100
  1206. // DebugValue instruction using a killed instruction.
  1207. const std::string text = R"(
  1208. OpCapability Shader
  1209. %1 = OpExtInstImport "GLSL.std.450"
  1210. %ext = OpExtInstImport "OpenCL.DebugInfo.100"
  1211. OpMemoryModel Logical GLSL450
  1212. OpEntryPoint Fragment %main "main" %In0 %OutColor
  1213. OpExecutionMode %main OriginUpperLeft
  1214. OpSource GLSL 450
  1215. %file_name = OpString "test"
  1216. %float_name = OpString "float"
  1217. %main_name = OpString "main"
  1218. %f_name = OpString "f"
  1219. OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
  1220. OpSourceExtension "GL_GOOGLE_include_directive"
  1221. OpName %main "main"
  1222. OpName %In0 "In0"
  1223. OpName %OutColor "OutColor"
  1224. OpDecorate %In0 Location 0
  1225. OpDecorate %OutColor Location 0
  1226. %void = OpTypeVoid
  1227. %6 = OpTypeFunction %void
  1228. %float = OpTypeFloat 32
  1229. %v4float = OpTypeVector %float 4
  1230. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1231. %In0 = OpVariable %_ptr_Input_v4float Input
  1232. %uint = OpTypeInt 32 0
  1233. %uint_0 = OpConstant %uint 0
  1234. %uint_32 = OpConstant %uint 32
  1235. %_ptr_Input_float = OpTypePointer Input %float
  1236. %uint_1 = OpConstant %uint 1
  1237. %uint_2 = OpConstant %uint 2
  1238. %v3float = OpTypeVector %float 3
  1239. %int = OpTypeInt 32 1
  1240. %int_0 = OpConstant %int 0
  1241. %int_20 = OpConstant %int 20
  1242. %bool = OpTypeBool
  1243. %float_1 = OpConstant %float 1
  1244. %int_1 = OpConstant %int 1
  1245. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1246. %OutColor = OpVariable %_ptr_Output_v4float Output
  1247. %23 = OpUndef %v3float
  1248. %null_expr = OpExtInst %void %ext DebugExpression
  1249. %src = OpExtInst %void %ext DebugSource %file_name
  1250. %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
  1251. %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
  1252. %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_tf
  1253. %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
  1254. %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
  1255. %main = OpFunction %void None %6
  1256. %24 = OpLabel
  1257. %s0 = OpExtInst %void %ext DebugScope %dbg_main
  1258. %25 = OpAccessChain %_ptr_Input_float %In0 %uint_0
  1259. %26 = OpLoad %float %25
  1260. %27 = OpAccessChain %_ptr_Input_float %In0 %uint_1
  1261. %28 = OpLoad %float %27
  1262. ; CHECK: [[undef:%\w+]] = OpUndef %float
  1263. ; CHECK-NOT: DebugValue
  1264. %value = OpExtInst %void %ext DebugValue %dbg_f %28 %null_expr
  1265. %29 = OpAccessChain %_ptr_Input_float %In0 %uint_2
  1266. %30 = OpLoad %float %29
  1267. ; CHECK: [[composite:%\w+]] = OpCompositeConstruct %v3float {{%\w+}} [[undef]] [[undef]]
  1268. ; CHECK-NEXT: DebugValue {{%\w+}} [[composite]]
  1269. %31 = OpCompositeConstruct %v3float %30 %28 %26
  1270. %value_live = OpExtInst %void %ext DebugValue %dbg_f %31 %null_expr
  1271. OpBranch %32
  1272. %32 = OpLabel
  1273. %s1 = OpExtInst %void %ext DebugScope %dbg_main
  1274. %33 = OpPhi %v3float %31 %24 %34 %35
  1275. %36 = OpPhi %int %int_0 %24 %37 %35
  1276. OpLoopMerge %38 %35 None
  1277. OpBranch %39
  1278. %39 = OpLabel
  1279. %s2 = OpExtInst %void %ext DebugScope %dbg_main
  1280. %40 = OpSLessThan %bool %36 %int_20
  1281. OpBranchConditional %40 %41 %38
  1282. %41 = OpLabel
  1283. %s3 = OpExtInst %void %ext DebugScope %dbg_main
  1284. %42 = OpCompositeExtract %float %33 0
  1285. %43 = OpFAdd %float %42 %float_1
  1286. %34 = OpCompositeInsert %v3float %43 %33 0
  1287. OpBranch %35
  1288. %35 = OpLabel
  1289. %s4 = OpExtInst %void %ext DebugScope %dbg_main
  1290. %37 = OpIAdd %int %36 %int_1
  1291. OpBranch %32
  1292. %38 = OpLabel
  1293. %s5 = OpExtInst %void %ext DebugScope %dbg_main
  1294. %44 = OpCompositeExtract %float %33 0
  1295. %45 = OpCompositeConstruct %v4float %44 %44 %44 %44
  1296. OpStore %OutColor %45
  1297. OpReturn
  1298. OpFunctionEnd
  1299. )";
  1300. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1301. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1302. SinglePassRunAndMatch<VectorDCE>(text, true);
  1303. }
  1304. TEST_F(VectorDCETest, OutOfBoundsExtract) {
  1305. // It tests that the vector DCE pass is able to handle an extract with an
  1306. // index that is out of bounds.
  1307. const std::string text = R"(
  1308. ; CHECK: [[undef:%\w+]] = OpUndef %v4float
  1309. ; CHECK: OpCompositeExtract %float [[undef]] 8
  1310. OpCapability Shader
  1311. OpMemoryModel Logical GLSL450
  1312. OpEntryPoint Fragment %main "main" %OutColor
  1313. OpExecutionMode %main OriginUpperLeft
  1314. OpDecorate %OutColor Location 0
  1315. %void = OpTypeVoid
  1316. %10 = OpTypeFunction %void
  1317. %float = OpTypeFloat 32
  1318. %v4float = OpTypeVector %float 4
  1319. %_ptr_Output_float = OpTypePointer Output %float
  1320. %OutColor = OpVariable %_ptr_Output_float Output
  1321. %null = OpConstantNull %v4float
  1322. %float_1 = OpConstant %float 1
  1323. %main = OpFunction %void None %10
  1324. %28 = OpLabel
  1325. %33 = OpCompositeInsert %v4float %float_1 %null 1
  1326. %extract = OpCompositeExtract %float %33 8
  1327. OpStore %OutColor %extract
  1328. OpReturn
  1329. OpFunctionEnd
  1330. )";
  1331. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1332. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1333. SinglePassRunAndMatch<VectorDCE>(text, false);
  1334. }
  1335. TEST_F(VectorDCETest, OutOfBoundsShuffle) {
  1336. // It tests that the vector DCE pass is able to handle a shuffle with an
  1337. // index that is out of bounds.
  1338. const std::string text = R"(
  1339. ; CHECK: [[undef:%\w+]] = OpUndef %v4float
  1340. ; CHECK: OpVectorShuffle %v4float [[undef]] [[undef]] 9 10 11 12
  1341. OpCapability Shader
  1342. OpMemoryModel Logical GLSL450
  1343. OpEntryPoint Fragment %main "main" %OutColor
  1344. OpExecutionMode %main OriginUpperLeft
  1345. OpDecorate %OutColor Location 0
  1346. %void = OpTypeVoid
  1347. %10 = OpTypeFunction %void
  1348. %float = OpTypeFloat 32
  1349. %v4float = OpTypeVector %float 4
  1350. %_ptr_Output_v4float = OpTypePointer Output %v4float
  1351. %OutColor = OpVariable %_ptr_Output_v4float Output
  1352. %null = OpConstantNull %v4float
  1353. %float_1 = OpConstant %float 1
  1354. %main = OpFunction %void None %10
  1355. %28 = OpLabel
  1356. %33 = OpCompositeInsert %v4float %float_1 %null 1
  1357. %shuffle = OpVectorShuffle %v4float %33 %33 9 10 11 12
  1358. OpStore %OutColor %shuffle
  1359. OpReturn
  1360. OpFunctionEnd
  1361. )";
  1362. SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
  1363. SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  1364. SinglePassRunAndMatch<VectorDCE>(text, false);
  1365. }
  1366. } // namespace
  1367. } // namespace opt
  1368. } // namespace spvtools