dead_insert_elim_test.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  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 DeadInsertElimTest = PassTest<::testing::Test>;
  22. TEST_F(DeadInsertElimTest, InsertAfterInsertElim) {
  23. // With two insertions to the same offset, the first is dead.
  24. //
  25. // Note: The SPIR-V assembly has had store/load elimination
  26. // performed to allow the inserts and extracts to directly
  27. // reference each other.
  28. //
  29. // #version 450
  30. //
  31. // layout (location=0) in float In0;
  32. // layout (location=1) in float In1;
  33. // layout (location=2) in vec2 In2;
  34. // layout (location=0) out vec4 OutColor;
  35. //
  36. // void main()
  37. // {
  38. // vec2 v = In2;
  39. // v.x = In0 + In1; // dead
  40. // v.x = 0.0;
  41. // OutColor = v.xyxy;
  42. // }
  43. const std::string before_predefs =
  44. R"(OpCapability Shader
  45. %1 = OpExtInstImport "GLSL.std.450"
  46. OpMemoryModel Logical GLSL450
  47. OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
  48. OpExecutionMode %main OriginUpperLeft
  49. OpSource GLSL 450
  50. OpName %main "main"
  51. OpName %In2 "In2"
  52. OpName %In0 "In0"
  53. OpName %In1 "In1"
  54. OpName %OutColor "OutColor"
  55. OpName %_Globals_ "_Globals_"
  56. OpMemberName %_Globals_ 0 "g_b"
  57. OpMemberName %_Globals_ 1 "g_n"
  58. OpName %_ ""
  59. OpDecorate %In2 Location 2
  60. OpDecorate %In0 Location 0
  61. OpDecorate %In1 Location 1
  62. OpDecorate %OutColor Location 0
  63. OpMemberDecorate %_Globals_ 0 Offset 0
  64. OpMemberDecorate %_Globals_ 1 Offset 4
  65. OpDecorate %_Globals_ Block
  66. OpDecorate %_ DescriptorSet 0
  67. OpDecorate %_ Binding 0
  68. %void = OpTypeVoid
  69. %11 = OpTypeFunction %void
  70. %float = OpTypeFloat 32
  71. %v2float = OpTypeVector %float 2
  72. %_ptr_Function_v2float = OpTypePointer Function %v2float
  73. %_ptr_Input_v2float = OpTypePointer Input %v2float
  74. %In2 = OpVariable %_ptr_Input_v2float Input
  75. %_ptr_Input_float = OpTypePointer Input %float
  76. %In0 = OpVariable %_ptr_Input_float Input
  77. %In1 = OpVariable %_ptr_Input_float Input
  78. %uint = OpTypeInt 32 0
  79. %_ptr_Function_float = OpTypePointer Function %float
  80. %float_0 = OpConstant %float 0
  81. %v4float = OpTypeVector %float 4
  82. %_ptr_Output_v4float = OpTypePointer Output %v4float
  83. %OutColor = OpVariable %_ptr_Output_v4float Output
  84. %int = OpTypeInt 32 1
  85. %_Globals_ = OpTypeStruct %uint %int
  86. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  87. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  88. )";
  89. const std::string after_predefs =
  90. R"(OpCapability Shader
  91. %1 = OpExtInstImport "GLSL.std.450"
  92. OpMemoryModel Logical GLSL450
  93. OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
  94. OpExecutionMode %main OriginUpperLeft
  95. OpSource GLSL 450
  96. OpName %main "main"
  97. OpName %In2 "In2"
  98. OpName %In0 "In0"
  99. OpName %In1 "In1"
  100. OpName %OutColor "OutColor"
  101. OpName %_Globals_ "_Globals_"
  102. OpMemberName %_Globals_ 0 "g_b"
  103. OpMemberName %_Globals_ 1 "g_n"
  104. OpName %_ ""
  105. OpDecorate %In2 Location 2
  106. OpDecorate %In0 Location 0
  107. OpDecorate %In1 Location 1
  108. OpDecorate %OutColor Location 0
  109. OpMemberDecorate %_Globals_ 0 Offset 0
  110. OpMemberDecorate %_Globals_ 1 Offset 4
  111. OpDecorate %_Globals_ Block
  112. OpDecorate %_ DescriptorSet 0
  113. OpDecorate %_ Binding 0
  114. %void = OpTypeVoid
  115. %10 = OpTypeFunction %void
  116. %float = OpTypeFloat 32
  117. %v2float = OpTypeVector %float 2
  118. %_ptr_Function_v2float = OpTypePointer Function %v2float
  119. %_ptr_Input_v2float = OpTypePointer Input %v2float
  120. %In2 = OpVariable %_ptr_Input_v2float Input
  121. %_ptr_Input_float = OpTypePointer Input %float
  122. %In0 = OpVariable %_ptr_Input_float Input
  123. %In1 = OpVariable %_ptr_Input_float Input
  124. %uint = OpTypeInt 32 0
  125. %_ptr_Function_float = OpTypePointer Function %float
  126. %float_0 = OpConstant %float 0
  127. %v4float = OpTypeVector %float 4
  128. %_ptr_Output_v4float = OpTypePointer Output %v4float
  129. %OutColor = OpVariable %_ptr_Output_v4float Output
  130. %int = OpTypeInt 32 1
  131. %_Globals_ = OpTypeStruct %uint %int
  132. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  133. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  134. )";
  135. const std::string before =
  136. R"(%main = OpFunction %void None %11
  137. %25 = OpLabel
  138. %26 = OpLoad %v2float %In2
  139. %27 = OpLoad %float %In0
  140. %28 = OpLoad %float %In1
  141. %29 = OpFAdd %float %27 %28
  142. %35 = OpCompositeInsert %v2float %29 %26 0
  143. %37 = OpCompositeInsert %v2float %float_0 %35 0
  144. %33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
  145. OpStore %OutColor %33
  146. OpReturn
  147. OpFunctionEnd
  148. )";
  149. const std::string after =
  150. R"(%main = OpFunction %void None %10
  151. %23 = OpLabel
  152. %24 = OpLoad %v2float %In2
  153. %29 = OpCompositeInsert %v2float %float_0 %24 0
  154. %30 = OpVectorShuffle %v4float %29 %29 0 1 0 1
  155. OpStore %OutColor %30
  156. OpReturn
  157. OpFunctionEnd
  158. )";
  159. SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
  160. after_predefs + after, true, true);
  161. }
  162. TEST_F(DeadInsertElimTest, DeadInsertInChainWithPhi) {
  163. // Dead insert eliminated with phi in insertion chain.
  164. //
  165. // Note: The SPIR-V assembly has had store/load elimination
  166. // performed to allow the inserts and extracts to directly
  167. // reference each other.
  168. //
  169. // #version 450
  170. //
  171. // layout (location=0) in vec4 In0;
  172. // layout (location=1) in float In1;
  173. // layout (location=2) in float In2;
  174. // layout (location=0) out vec4 OutColor;
  175. //
  176. // layout(std140, binding = 0 ) uniform _Globals_
  177. // {
  178. // bool g_b;
  179. // };
  180. //
  181. // void main()
  182. // {
  183. // vec4 v = In0;
  184. // v.z = In1 + In2;
  185. // if (g_b) v.w = 1.0;
  186. // OutColor = vec4(v.x,v.y,0.0,v.w);
  187. // }
  188. const std::string before_predefs =
  189. R"(OpCapability Shader
  190. %1 = OpExtInstImport "GLSL.std.450"
  191. OpMemoryModel Logical GLSL450
  192. OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
  193. OpExecutionMode %main OriginUpperLeft
  194. OpSource GLSL 450
  195. OpName %main "main"
  196. OpName %In0 "In0"
  197. OpName %In1 "In1"
  198. OpName %In2 "In2"
  199. OpName %_Globals_ "_Globals_"
  200. OpMemberName %_Globals_ 0 "g_b"
  201. OpName %_ ""
  202. OpName %OutColor "OutColor"
  203. OpDecorate %In0 Location 0
  204. OpDecorate %In1 Location 1
  205. OpDecorate %In2 Location 2
  206. OpMemberDecorate %_Globals_ 0 Offset 0
  207. OpDecorate %_Globals_ Block
  208. OpDecorate %_ DescriptorSet 0
  209. OpDecorate %_ Binding 0
  210. OpDecorate %OutColor Location 0
  211. %void = OpTypeVoid
  212. %11 = OpTypeFunction %void
  213. %float = OpTypeFloat 32
  214. %v4float = OpTypeVector %float 4
  215. %_ptr_Function_v4float = OpTypePointer Function %v4float
  216. %_ptr_Input_v4float = OpTypePointer Input %v4float
  217. %In0 = OpVariable %_ptr_Input_v4float Input
  218. %_ptr_Input_float = OpTypePointer Input %float
  219. %In1 = OpVariable %_ptr_Input_float Input
  220. %In2 = OpVariable %_ptr_Input_float Input
  221. %uint = OpTypeInt 32 0
  222. %_ptr_Function_float = OpTypePointer Function %float
  223. %_Globals_ = OpTypeStruct %uint
  224. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  225. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  226. %int = OpTypeInt 32 1
  227. %int_0 = OpConstant %int 0
  228. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  229. %bool = OpTypeBool
  230. %uint_0 = OpConstant %uint 0
  231. %float_1 = OpConstant %float 1
  232. %_ptr_Output_v4float = OpTypePointer Output %v4float
  233. %OutColor = OpVariable %_ptr_Output_v4float Output
  234. %float_0 = OpConstant %float 0
  235. )";
  236. const std::string after_predefs =
  237. R"(OpCapability Shader
  238. %1 = OpExtInstImport "GLSL.std.450"
  239. OpMemoryModel Logical GLSL450
  240. OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
  241. OpExecutionMode %main OriginUpperLeft
  242. OpSource GLSL 450
  243. OpName %main "main"
  244. OpName %In0 "In0"
  245. OpName %In1 "In1"
  246. OpName %In2 "In2"
  247. OpName %_Globals_ "_Globals_"
  248. OpMemberName %_Globals_ 0 "g_b"
  249. OpName %_ ""
  250. OpName %OutColor "OutColor"
  251. OpDecorate %In0 Location 0
  252. OpDecorate %In1 Location 1
  253. OpDecorate %In2 Location 2
  254. OpMemberDecorate %_Globals_ 0 Offset 0
  255. OpDecorate %_Globals_ Block
  256. OpDecorate %_ DescriptorSet 0
  257. OpDecorate %_ Binding 0
  258. OpDecorate %OutColor Location 0
  259. %void = OpTypeVoid
  260. %10 = OpTypeFunction %void
  261. %float = OpTypeFloat 32
  262. %v4float = OpTypeVector %float 4
  263. %_ptr_Function_v4float = OpTypePointer Function %v4float
  264. %_ptr_Input_v4float = OpTypePointer Input %v4float
  265. %In0 = OpVariable %_ptr_Input_v4float Input
  266. %_ptr_Input_float = OpTypePointer Input %float
  267. %In1 = OpVariable %_ptr_Input_float Input
  268. %In2 = OpVariable %_ptr_Input_float Input
  269. %uint = OpTypeInt 32 0
  270. %_ptr_Function_float = OpTypePointer Function %float
  271. %_Globals_ = OpTypeStruct %uint
  272. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  273. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  274. %int = OpTypeInt 32 1
  275. %int_0 = OpConstant %int 0
  276. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  277. %bool = OpTypeBool
  278. %uint_0 = OpConstant %uint 0
  279. %float_1 = OpConstant %float 1
  280. %_ptr_Output_v4float = OpTypePointer Output %v4float
  281. %OutColor = OpVariable %_ptr_Output_v4float Output
  282. %float_0 = OpConstant %float 0
  283. )";
  284. const std::string before =
  285. R"(%main = OpFunction %void None %11
  286. %31 = OpLabel
  287. %32 = OpLoad %v4float %In0
  288. %33 = OpLoad %float %In1
  289. %34 = OpLoad %float %In2
  290. %35 = OpFAdd %float %33 %34
  291. %51 = OpCompositeInsert %v4float %35 %32 2
  292. %37 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  293. %38 = OpLoad %uint %37
  294. %39 = OpINotEqual %bool %38 %uint_0
  295. OpSelectionMerge %40 None
  296. OpBranchConditional %39 %41 %40
  297. %41 = OpLabel
  298. %53 = OpCompositeInsert %v4float %float_1 %51 3
  299. OpBranch %40
  300. %40 = OpLabel
  301. %60 = OpPhi %v4float %51 %31 %53 %41
  302. %55 = OpCompositeExtract %float %60 0
  303. %57 = OpCompositeExtract %float %60 1
  304. %59 = OpCompositeExtract %float %60 3
  305. %49 = OpCompositeConstruct %v4float %55 %57 %float_0 %59
  306. OpStore %OutColor %49
  307. OpReturn
  308. OpFunctionEnd
  309. )";
  310. const std::string after =
  311. R"(%main = OpFunction %void None %10
  312. %27 = OpLabel
  313. %28 = OpLoad %v4float %In0
  314. %33 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  315. %34 = OpLoad %uint %33
  316. %35 = OpINotEqual %bool %34 %uint_0
  317. OpSelectionMerge %36 None
  318. OpBranchConditional %35 %37 %36
  319. %37 = OpLabel
  320. %38 = OpCompositeInsert %v4float %float_1 %28 3
  321. OpBranch %36
  322. %36 = OpLabel
  323. %39 = OpPhi %v4float %28 %27 %38 %37
  324. %40 = OpCompositeExtract %float %39 0
  325. %41 = OpCompositeExtract %float %39 1
  326. %42 = OpCompositeExtract %float %39 3
  327. %43 = OpCompositeConstruct %v4float %40 %41 %float_0 %42
  328. OpStore %OutColor %43
  329. OpReturn
  330. OpFunctionEnd
  331. )";
  332. SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
  333. after_predefs + after, true, true);
  334. }
  335. TEST_F(DeadInsertElimTest, DeadInsertTwoPasses) {
  336. // Dead insert which requires two passes to eliminate
  337. //
  338. // Note: The SPIR-V assembly has had store/load elimination
  339. // performed to allow the inserts and extracts to directly
  340. // reference each other.
  341. //
  342. // #version 450
  343. //
  344. // layout (location=0) in vec4 In0;
  345. // layout (location=1) in float In1;
  346. // layout (location=2) in float In2;
  347. // layout (location=0) out vec4 OutColor;
  348. //
  349. // layout(std140, binding = 0 ) uniform _Globals_
  350. // {
  351. // bool g_b;
  352. // bool g_b2;
  353. // };
  354. //
  355. // void main()
  356. // {
  357. // vec4 v1, v2;
  358. // v1 = In0;
  359. // v1.y = In1 + In2; // dead, second pass
  360. // if (g_b) v1.x = 1.0;
  361. // v2.x = v1.x;
  362. // v2.y = v1.y; // dead, first pass
  363. // if (g_b2) v2.x = 0.0;
  364. // OutColor = vec4(v2.x,v2.x,0.0,1.0);
  365. // }
  366. const std::string before_predefs =
  367. R"(OpCapability Shader
  368. %1 = OpExtInstImport "GLSL.std.450"
  369. OpMemoryModel Logical GLSL450
  370. OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
  371. OpExecutionMode %main OriginUpperLeft
  372. OpSource GLSL 450
  373. OpName %main "main"
  374. OpName %In0 "In0"
  375. OpName %In1 "In1"
  376. OpName %In2 "In2"
  377. OpName %_Globals_ "_Globals_"
  378. OpMemberName %_Globals_ 0 "g_b"
  379. OpMemberName %_Globals_ 1 "g_b2"
  380. OpName %_ ""
  381. OpName %OutColor "OutColor"
  382. OpDecorate %In0 Location 0
  383. OpDecorate %In1 Location 1
  384. OpDecorate %In2 Location 2
  385. OpMemberDecorate %_Globals_ 0 Offset 0
  386. OpMemberDecorate %_Globals_ 1 Offset 4
  387. OpDecorate %_Globals_ Block
  388. OpDecorate %_ DescriptorSet 0
  389. OpDecorate %_ Binding 0
  390. OpDecorate %OutColor Location 0
  391. %void = OpTypeVoid
  392. %10 = OpTypeFunction %void
  393. %float = OpTypeFloat 32
  394. %v4float = OpTypeVector %float 4
  395. %_ptr_Function_v4float = OpTypePointer Function %v4float
  396. %_ptr_Input_v4float = OpTypePointer Input %v4float
  397. %In0 = OpVariable %_ptr_Input_v4float Input
  398. %_ptr_Input_float = OpTypePointer Input %float
  399. %In1 = OpVariable %_ptr_Input_float Input
  400. %In2 = OpVariable %_ptr_Input_float Input
  401. %uint = OpTypeInt 32 0
  402. %_Globals_ = OpTypeStruct %uint %uint
  403. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  404. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  405. %int = OpTypeInt 32 1
  406. %int_0 = OpConstant %int 0
  407. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  408. %bool = OpTypeBool
  409. %uint_0 = OpConstant %uint 0
  410. %float_1 = OpConstant %float 1
  411. %int_1 = OpConstant %int 1
  412. %float_0 = OpConstant %float 0
  413. %_ptr_Output_v4float = OpTypePointer Output %v4float
  414. %OutColor = OpVariable %_ptr_Output_v4float Output
  415. %27 = OpUndef %v4float
  416. )";
  417. const std::string after_predefs =
  418. R"(OpCapability Shader
  419. %1 = OpExtInstImport "GLSL.std.450"
  420. OpMemoryModel Logical GLSL450
  421. OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
  422. OpExecutionMode %main OriginUpperLeft
  423. OpSource GLSL 450
  424. OpName %main "main"
  425. OpName %In0 "In0"
  426. OpName %In1 "In1"
  427. OpName %In2 "In2"
  428. OpName %_Globals_ "_Globals_"
  429. OpMemberName %_Globals_ 0 "g_b"
  430. OpMemberName %_Globals_ 1 "g_b2"
  431. OpName %_ ""
  432. OpName %OutColor "OutColor"
  433. OpDecorate %In0 Location 0
  434. OpDecorate %In1 Location 1
  435. OpDecorate %In2 Location 2
  436. OpMemberDecorate %_Globals_ 0 Offset 0
  437. OpMemberDecorate %_Globals_ 1 Offset 4
  438. OpDecorate %_Globals_ Block
  439. OpDecorate %_ DescriptorSet 0
  440. OpDecorate %_ Binding 0
  441. OpDecorate %OutColor Location 0
  442. %void = OpTypeVoid
  443. %10 = OpTypeFunction %void
  444. %float = OpTypeFloat 32
  445. %v4float = OpTypeVector %float 4
  446. %_ptr_Function_v4float = OpTypePointer Function %v4float
  447. %_ptr_Input_v4float = OpTypePointer Input %v4float
  448. %In0 = OpVariable %_ptr_Input_v4float Input
  449. %_ptr_Input_float = OpTypePointer Input %float
  450. %In1 = OpVariable %_ptr_Input_float Input
  451. %In2 = OpVariable %_ptr_Input_float Input
  452. %uint = OpTypeInt 32 0
  453. %_Globals_ = OpTypeStruct %uint %uint
  454. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  455. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  456. %int = OpTypeInt 32 1
  457. %int_0 = OpConstant %int 0
  458. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  459. %bool = OpTypeBool
  460. %uint_0 = OpConstant %uint 0
  461. %float_1 = OpConstant %float 1
  462. %int_1 = OpConstant %int 1
  463. %float_0 = OpConstant %float 0
  464. %_ptr_Output_v4float = OpTypePointer Output %v4float
  465. %OutColor = OpVariable %_ptr_Output_v4float Output
  466. %27 = OpUndef %v4float
  467. )";
  468. const std::string before =
  469. R"(%main = OpFunction %void None %10
  470. %28 = OpLabel
  471. %29 = OpLoad %v4float %In0
  472. %30 = OpLoad %float %In1
  473. %31 = OpLoad %float %In2
  474. %32 = OpFAdd %float %30 %31
  475. %33 = OpCompositeInsert %v4float %32 %29 1
  476. %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  477. %35 = OpLoad %uint %34
  478. %36 = OpINotEqual %bool %35 %uint_0
  479. OpSelectionMerge %37 None
  480. OpBranchConditional %36 %38 %37
  481. %38 = OpLabel
  482. %39 = OpCompositeInsert %v4float %float_1 %33 0
  483. OpBranch %37
  484. %37 = OpLabel
  485. %40 = OpPhi %v4float %33 %28 %39 %38
  486. %41 = OpCompositeExtract %float %40 0
  487. %42 = OpCompositeInsert %v4float %41 %27 0
  488. %43 = OpCompositeExtract %float %40 1
  489. %44 = OpCompositeInsert %v4float %43 %42 1
  490. %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
  491. %46 = OpLoad %uint %45
  492. %47 = OpINotEqual %bool %46 %uint_0
  493. OpSelectionMerge %48 None
  494. OpBranchConditional %47 %49 %48
  495. %49 = OpLabel
  496. %50 = OpCompositeInsert %v4float %float_0 %44 0
  497. OpBranch %48
  498. %48 = OpLabel
  499. %51 = OpPhi %v4float %44 %37 %50 %49
  500. %52 = OpCompositeExtract %float %51 0
  501. %53 = OpCompositeExtract %float %51 0
  502. %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
  503. OpStore %OutColor %54
  504. OpReturn
  505. OpFunctionEnd
  506. )";
  507. const std::string after =
  508. R"(%main = OpFunction %void None %10
  509. %28 = OpLabel
  510. %29 = OpLoad %v4float %In0
  511. %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
  512. %35 = OpLoad %uint %34
  513. %36 = OpINotEqual %bool %35 %uint_0
  514. OpSelectionMerge %37 None
  515. OpBranchConditional %36 %38 %37
  516. %38 = OpLabel
  517. %39 = OpCompositeInsert %v4float %float_1 %29 0
  518. OpBranch %37
  519. %37 = OpLabel
  520. %40 = OpPhi %v4float %29 %28 %39 %38
  521. %41 = OpCompositeExtract %float %40 0
  522. %42 = OpCompositeInsert %v4float %41 %27 0
  523. %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
  524. %46 = OpLoad %uint %45
  525. %47 = OpINotEqual %bool %46 %uint_0
  526. OpSelectionMerge %48 None
  527. OpBranchConditional %47 %49 %48
  528. %49 = OpLabel
  529. %50 = OpCompositeInsert %v4float %float_0 %42 0
  530. OpBranch %48
  531. %48 = OpLabel
  532. %51 = OpPhi %v4float %42 %37 %50 %49
  533. %52 = OpCompositeExtract %float %51 0
  534. %53 = OpCompositeExtract %float %51 0
  535. %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
  536. OpStore %OutColor %54
  537. OpReturn
  538. OpFunctionEnd
  539. )";
  540. SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
  541. after_predefs + after, true, true);
  542. }
  543. TEST_F(DeadInsertElimTest, DebugInsertAfterInsertElim) {
  544. // With two insertions to the same offset, the first is dead.
  545. //
  546. // Note: The SPIR-V assembly has had store/load elimination
  547. // performed to allow the inserts and extracts to directly
  548. // reference each other.
  549. //
  550. // #version 450
  551. //
  552. // layout (location=0) in float In0;
  553. // layout (location=1) in float In1;
  554. // layout (location=2) in vec2 In2;
  555. // layout (location=0) out vec4 OutColor;
  556. //
  557. // void main()
  558. // {
  559. // vec2 v = In2;
  560. // v.x = In0 + In1; // dead
  561. // v.x = 0.0;
  562. // OutColor = v.xyxy;
  563. // }
  564. const std::string text =
  565. R"(OpCapability Shader
  566. %1 = OpExtInstImport "GLSL.std.450"
  567. %ext = OpExtInstImport "OpenCL.DebugInfo.100"
  568. OpMemoryModel Logical GLSL450
  569. OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
  570. OpExecutionMode %main OriginUpperLeft
  571. OpSource GLSL 450
  572. %file_name = OpString "test"
  573. %float_name = OpString "float"
  574. %main_name = OpString "main"
  575. %f_name = OpString "f"
  576. OpName %main "main"
  577. OpName %In2 "In2"
  578. OpName %In0 "In0"
  579. OpName %In1 "In1"
  580. OpName %OutColor "OutColor"
  581. OpName %_Globals_ "_Globals_"
  582. OpMemberName %_Globals_ 0 "g_b"
  583. OpMemberName %_Globals_ 1 "g_n"
  584. OpName %_ ""
  585. OpDecorate %In2 Location 2
  586. OpDecorate %In0 Location 0
  587. OpDecorate %In1 Location 1
  588. OpDecorate %OutColor Location 0
  589. OpMemberDecorate %_Globals_ 0 Offset 0
  590. OpMemberDecorate %_Globals_ 1 Offset 4
  591. OpDecorate %_Globals_ Block
  592. OpDecorate %_ DescriptorSet 0
  593. OpDecorate %_ Binding 0
  594. %void = OpTypeVoid
  595. %11 = OpTypeFunction %void
  596. %float = OpTypeFloat 32
  597. %v2float = OpTypeVector %float 2
  598. %_ptr_Function_v2float = OpTypePointer Function %v2float
  599. %_ptr_Input_v2float = OpTypePointer Input %v2float
  600. %In2 = OpVariable %_ptr_Input_v2float Input
  601. %_ptr_Input_float = OpTypePointer Input %float
  602. %In0 = OpVariable %_ptr_Input_float Input
  603. %In1 = OpVariable %_ptr_Input_float Input
  604. %uint = OpTypeInt 32 0
  605. %uint_32 = OpConstant %uint 32
  606. %_ptr_Function_float = OpTypePointer Function %float
  607. %float_0 = OpConstant %float 0
  608. %v4float = OpTypeVector %float 4
  609. %_ptr_Output_v4float = OpTypePointer Output %v4float
  610. %OutColor = OpVariable %_ptr_Output_v4float Output
  611. %int = OpTypeInt 32 1
  612. %_Globals_ = OpTypeStruct %uint %int
  613. %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
  614. %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
  615. %nullexpr = OpExtInst %void %ext DebugExpression
  616. %src = OpExtInst %void %ext DebugSource %file_name
  617. %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
  618. %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
  619. %dbg_v2f = OpExtInst %void %ext DebugTypeVector %dbg_tf 2
  620. %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void
  621. %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 0 %main
  622. %dbg_foo = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v2f %src 0 0 %dbg_main FlagIsLocal
  623. %main = OpFunction %void None %11
  624. %25 = OpLabel
  625. %26 = OpLoad %v2float %In2
  626. %27 = OpLoad %float %In0
  627. %28 = OpLoad %float %In1
  628. %29 = OpFAdd %float %27 %28
  629. ; CHECK: [[repl:%\w+]] = OpLoad %v2float %In2
  630. ; CHECK-NOT: OpCompositeInsert
  631. ; CHECK: DebugValue {{%\w+}} [[repl:%\w+]]
  632. ; CHECK-NEXT: OpCompositeInsert %v2float %float_0 [[repl]] 0
  633. %35 = OpCompositeInsert %v2float %29 %26 0
  634. %value = OpExtInst %void %ext DebugValue %dbg_foo %35 %nullexpr
  635. %37 = OpCompositeInsert %v2float %float_0 %35 0
  636. %33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
  637. OpStore %OutColor %33
  638. OpReturn
  639. OpFunctionEnd
  640. )";
  641. SinglePassRunAndMatch<DeadInsertElimPass>(text, true);
  642. }
  643. // TODO(greg-lunarg): Add tests to verify handling of these cases:
  644. //
  645. } // namespace
  646. } // namespace opt
  647. } // namespace spvtools