insert_extract_elim_test.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  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 "source/opt/simplification_pass.h"
  17. #include "test/opt/pass_fixture.h"
  18. #include "test/opt/pass_utils.h"
  19. namespace spvtools {
  20. namespace opt {
  21. namespace {
  22. using InsertExtractElimTest = PassTest<::testing::Test>;
  23. TEST_F(InsertExtractElimTest, Simple) {
  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 140
  29. //
  30. // in vec4 BaseColor;
  31. //
  32. // struct S_t {
  33. // vec4 v0;
  34. // vec4 v1;
  35. // };
  36. //
  37. // void main()
  38. // {
  39. // S_t s0;
  40. // s0.v1 = BaseColor;
  41. // gl_FragColor = s0.v1;
  42. // }
  43. const std::string predefs =
  44. R"(OpCapability Shader
  45. %1 = OpExtInstImport "GLSL.std.450"
  46. OpMemoryModel Logical GLSL450
  47. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  48. OpExecutionMode %main OriginUpperLeft
  49. OpSource GLSL 140
  50. OpName %main "main"
  51. OpName %S_t "S_t"
  52. OpMemberName %S_t 0 "v0"
  53. OpMemberName %S_t 1 "v1"
  54. OpName %s0 "s0"
  55. OpName %BaseColor "BaseColor"
  56. OpName %gl_FragColor "gl_FragColor"
  57. %void = OpTypeVoid
  58. %8 = OpTypeFunction %void
  59. %float = OpTypeFloat 32
  60. %v4float = OpTypeVector %float 4
  61. %S_t = OpTypeStruct %v4float %v4float
  62. %_ptr_Function_S_t = OpTypePointer Function %S_t
  63. %int = OpTypeInt 32 1
  64. %int_1 = OpConstant %int 1
  65. %_ptr_Input_v4float = OpTypePointer Input %v4float
  66. %BaseColor = OpVariable %_ptr_Input_v4float Input
  67. %_ptr_Function_v4float = OpTypePointer Function %v4float
  68. %_ptr_Output_v4float = OpTypePointer Output %v4float
  69. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  70. )";
  71. const std::string before =
  72. R"(%main = OpFunction %void None %8
  73. %17 = OpLabel
  74. %s0 = OpVariable %_ptr_Function_S_t Function
  75. %18 = OpLoad %v4float %BaseColor
  76. %19 = OpLoad %S_t %s0
  77. %20 = OpCompositeInsert %S_t %18 %19 1
  78. OpStore %s0 %20
  79. %21 = OpCompositeExtract %v4float %20 1
  80. OpStore %gl_FragColor %21
  81. OpReturn
  82. OpFunctionEnd
  83. )";
  84. const std::string after =
  85. R"(%main = OpFunction %void None %8
  86. %17 = OpLabel
  87. %s0 = OpVariable %_ptr_Function_S_t Function
  88. %18 = OpLoad %v4float %BaseColor
  89. %19 = OpLoad %S_t %s0
  90. %20 = OpCompositeInsert %S_t %18 %19 1
  91. OpStore %s0 %20
  92. OpStore %gl_FragColor %18
  93. OpReturn
  94. OpFunctionEnd
  95. )";
  96. SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
  97. true, true);
  98. }
  99. TEST_F(InsertExtractElimTest, OptimizeAcrossNonConflictingInsert) {
  100. // Note: The SPIR-V assembly has had store/load elimination
  101. // performed to allow the inserts and extracts to directly
  102. // reference each other.
  103. //
  104. // #version 140
  105. //
  106. // in vec4 BaseColor;
  107. //
  108. // struct S_t {
  109. // vec4 v0;
  110. // vec4 v1;
  111. // };
  112. //
  113. // void main()
  114. // {
  115. // S_t s0;
  116. // s0.v1 = BaseColor;
  117. // s0.v0[2] = 0.0;
  118. // gl_FragColor = s0.v1;
  119. // }
  120. const std::string predefs =
  121. R"(OpCapability Shader
  122. %1 = OpExtInstImport "GLSL.std.450"
  123. OpMemoryModel Logical GLSL450
  124. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  125. OpExecutionMode %main OriginUpperLeft
  126. OpSource GLSL 140
  127. OpName %main "main"
  128. OpName %S_t "S_t"
  129. OpMemberName %S_t 0 "v0"
  130. OpMemberName %S_t 1 "v1"
  131. OpName %s0 "s0"
  132. OpName %BaseColor "BaseColor"
  133. OpName %gl_FragColor "gl_FragColor"
  134. %void = OpTypeVoid
  135. %8 = OpTypeFunction %void
  136. %float = OpTypeFloat 32
  137. %v4float = OpTypeVector %float 4
  138. %S_t = OpTypeStruct %v4float %v4float
  139. %_ptr_Function_S_t = OpTypePointer Function %S_t
  140. %int = OpTypeInt 32 1
  141. %int_1 = OpConstant %int 1
  142. %float_0 = OpConstant %float 0
  143. %_ptr_Input_v4float = OpTypePointer Input %v4float
  144. %BaseColor = OpVariable %_ptr_Input_v4float Input
  145. %_ptr_Function_v4float = OpTypePointer Function %v4float
  146. %_ptr_Output_v4float = OpTypePointer Output %v4float
  147. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  148. )";
  149. const std::string before =
  150. R"(%main = OpFunction %void None %8
  151. %18 = OpLabel
  152. %s0 = OpVariable %_ptr_Function_S_t Function
  153. %19 = OpLoad %v4float %BaseColor
  154. %20 = OpLoad %S_t %s0
  155. %21 = OpCompositeInsert %S_t %19 %20 1
  156. %22 = OpCompositeInsert %S_t %float_0 %21 0 2
  157. OpStore %s0 %22
  158. %23 = OpCompositeExtract %v4float %22 1
  159. OpStore %gl_FragColor %23
  160. OpReturn
  161. OpFunctionEnd
  162. )";
  163. const std::string after =
  164. R"(%main = OpFunction %void None %8
  165. %18 = OpLabel
  166. %s0 = OpVariable %_ptr_Function_S_t Function
  167. %19 = OpLoad %v4float %BaseColor
  168. %20 = OpLoad %S_t %s0
  169. %21 = OpCompositeInsert %S_t %19 %20 1
  170. %22 = OpCompositeInsert %S_t %float_0 %21 0 2
  171. OpStore %s0 %22
  172. OpStore %gl_FragColor %19
  173. OpReturn
  174. OpFunctionEnd
  175. )";
  176. SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
  177. true, true);
  178. }
  179. TEST_F(InsertExtractElimTest, OptimizeOpaque) {
  180. // SPIR-V not representable in GLSL; not generatable from HLSL
  181. // for the moment.
  182. const std::string predefs =
  183. R"(OpCapability Shader
  184. %1 = OpExtInstImport "GLSL.std.450"
  185. OpMemoryModel Logical GLSL450
  186. OpEntryPoint Fragment %main "main" %outColor %texCoords
  187. OpExecutionMode %main OriginUpperLeft
  188. OpSource GLSL 140
  189. OpName %main "main"
  190. OpName %S_t "S_t"
  191. OpMemberName %S_t 0 "v0"
  192. OpMemberName %S_t 1 "v1"
  193. OpMemberName %S_t 2 "smp"
  194. OpName %outColor "outColor"
  195. OpName %sampler15 "sampler15"
  196. OpName %s0 "s0"
  197. OpName %texCoords "texCoords"
  198. OpDecorate %sampler15 DescriptorSet 0
  199. %void = OpTypeVoid
  200. %9 = OpTypeFunction %void
  201. %float = OpTypeFloat 32
  202. %v2float = OpTypeVector %float 2
  203. %v4float = OpTypeVector %float 4
  204. %_ptr_Output_v4float = OpTypePointer Output %v4float
  205. %outColor = OpVariable %_ptr_Output_v4float Output
  206. %14 = OpTypeImage %float 2D 0 0 0 1 Unknown
  207. %15 = OpTypeSampledImage %14
  208. %S_t = OpTypeStruct %v2float %v2float %15
  209. %_ptr_Function_S_t = OpTypePointer Function %S_t
  210. %17 = OpTypeFunction %void %_ptr_Function_S_t
  211. %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
  212. %_ptr_Function_15 = OpTypePointer Function %15
  213. %sampler15 = OpVariable %_ptr_UniformConstant_15 UniformConstant
  214. %int = OpTypeInt 32 1
  215. %int_0 = OpConstant %int 0
  216. %int_2 = OpConstant %int 2
  217. %_ptr_Function_v2float = OpTypePointer Function %v2float
  218. %_ptr_Input_v2float = OpTypePointer Input %v2float
  219. %texCoords = OpVariable %_ptr_Input_v2float Input
  220. )";
  221. const std::string before =
  222. R"(%main = OpFunction %void None %9
  223. %25 = OpLabel
  224. %s0 = OpVariable %_ptr_Function_S_t Function
  225. %26 = OpLoad %v2float %texCoords
  226. %27 = OpLoad %S_t %s0
  227. %28 = OpCompositeInsert %S_t %26 %27 0
  228. %29 = OpLoad %15 %sampler15
  229. %30 = OpCompositeInsert %S_t %29 %28 2
  230. OpStore %s0 %30
  231. %31 = OpCompositeExtract %15 %30 2
  232. %32 = OpCompositeExtract %v2float %30 0
  233. %33 = OpImageSampleImplicitLod %v4float %31 %32
  234. OpStore %outColor %33
  235. OpReturn
  236. OpFunctionEnd
  237. )";
  238. const std::string after =
  239. R"(%main = OpFunction %void None %9
  240. %25 = OpLabel
  241. %s0 = OpVariable %_ptr_Function_S_t Function
  242. %26 = OpLoad %v2float %texCoords
  243. %27 = OpLoad %S_t %s0
  244. %28 = OpCompositeInsert %S_t %26 %27 0
  245. %29 = OpLoad %15 %sampler15
  246. %30 = OpCompositeInsert %S_t %29 %28 2
  247. OpStore %s0 %30
  248. %33 = OpImageSampleImplicitLod %v4float %29 %26
  249. OpStore %outColor %33
  250. OpReturn
  251. OpFunctionEnd
  252. )";
  253. SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
  254. true, true);
  255. }
  256. TEST_F(InsertExtractElimTest, OptimizeNestedStruct) {
  257. // The following HLSL has been pre-optimized to get the SPIR-V:
  258. // struct S0
  259. // {
  260. // int x;
  261. // SamplerState ss;
  262. // };
  263. //
  264. // struct S1
  265. // {
  266. // float b;
  267. // S0 s0;
  268. // };
  269. //
  270. // struct S2
  271. // {
  272. // int a1;
  273. // S1 resources;
  274. // };
  275. //
  276. // SamplerState samp;
  277. // Texture2D tex;
  278. //
  279. // float4 main(float4 vpos : VPOS) : COLOR0
  280. // {
  281. // S1 s1;
  282. // S2 s2;
  283. // s1.s0.ss = samp;
  284. // s2.resources = s1;
  285. // return tex.Sample(s2.resources.s0.ss, float2(0.5));
  286. // }
  287. const std::string predefs =
  288. R"(OpCapability Shader
  289. %1 = OpExtInstImport "GLSL.std.450"
  290. OpMemoryModel Logical GLSL450
  291. OpEntryPoint Fragment %main "main" %_entryPointOutput
  292. OpExecutionMode %main OriginUpperLeft
  293. OpSource HLSL 500
  294. OpName %main "main"
  295. OpName %S0 "S0"
  296. OpMemberName %S0 0 "x"
  297. OpMemberName %S0 1 "ss"
  298. OpName %S1 "S1"
  299. OpMemberName %S1 0 "b"
  300. OpMemberName %S1 1 "s0"
  301. OpName %samp "samp"
  302. OpName %S2 "S2"
  303. OpMemberName %S2 0 "a1"
  304. OpMemberName %S2 1 "resources"
  305. OpName %tex "tex"
  306. OpName %_entryPointOutput "@entryPointOutput"
  307. OpDecorate %samp DescriptorSet 0
  308. OpDecorate %tex DescriptorSet 0
  309. OpDecorate %_entryPointOutput Location 0
  310. %void = OpTypeVoid
  311. %10 = OpTypeFunction %void
  312. %float = OpTypeFloat 32
  313. %v4float = OpTypeVector %float 4
  314. %_ptr_Function_v4float = OpTypePointer Function %v4float
  315. %14 = OpTypeFunction %v4float %_ptr_Function_v4float
  316. %int = OpTypeInt 32 1
  317. %16 = OpTypeSampler
  318. %S0 = OpTypeStruct %int %16
  319. %S1 = OpTypeStruct %float %S0
  320. %_ptr_Function_S1 = OpTypePointer Function %S1
  321. %int_1 = OpConstant %int 1
  322. %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
  323. %samp = OpVariable %_ptr_UniformConstant_16 UniformConstant
  324. %_ptr_Function_16 = OpTypePointer Function %16
  325. %S2 = OpTypeStruct %int %S1
  326. %_ptr_Function_S2 = OpTypePointer Function %S2
  327. %22 = OpTypeImage %float 2D 0 0 0 1 Unknown
  328. %_ptr_UniformConstant_22 = OpTypePointer UniformConstant %22
  329. %tex = OpVariable %_ptr_UniformConstant_22 UniformConstant
  330. %24 = OpTypeSampledImage %22
  331. %v2float = OpTypeVector %float 2
  332. %float_0_5 = OpConstant %float 0.5
  333. %27 = OpConstantComposite %v2float %float_0_5 %float_0_5
  334. %_ptr_Input_v4float = OpTypePointer Input %v4float
  335. %_ptr_Output_v4float = OpTypePointer Output %v4float
  336. %_entryPointOutput = OpVariable %_ptr_Output_v4float Output
  337. )";
  338. const std::string before =
  339. R"(%main = OpFunction %void None %10
  340. %30 = OpLabel
  341. %31 = OpVariable %_ptr_Function_S1 Function
  342. %32 = OpVariable %_ptr_Function_S2 Function
  343. %33 = OpLoad %16 %samp
  344. %34 = OpLoad %S1 %31
  345. %35 = OpCompositeInsert %S1 %33 %34 1 1
  346. OpStore %31 %35
  347. %36 = OpLoad %S2 %32
  348. %37 = OpCompositeInsert %S2 %35 %36 1
  349. OpStore %32 %37
  350. %38 = OpLoad %22 %tex
  351. %39 = OpCompositeExtract %16 %37 1 1 1
  352. %40 = OpSampledImage %24 %38 %39
  353. %41 = OpImageSampleImplicitLod %v4float %40 %27
  354. OpStore %_entryPointOutput %41
  355. OpReturn
  356. OpFunctionEnd
  357. )";
  358. const std::string after =
  359. R"(%main = OpFunction %void None %10
  360. %30 = OpLabel
  361. %31 = OpVariable %_ptr_Function_S1 Function
  362. %32 = OpVariable %_ptr_Function_S2 Function
  363. %33 = OpLoad %16 %samp
  364. %34 = OpLoad %S1 %31
  365. %35 = OpCompositeInsert %S1 %33 %34 1 1
  366. OpStore %31 %35
  367. %36 = OpLoad %S2 %32
  368. %37 = OpCompositeInsert %S2 %35 %36 1
  369. OpStore %32 %37
  370. %38 = OpLoad %22 %tex
  371. %40 = OpSampledImage %24 %38 %33
  372. %41 = OpImageSampleImplicitLod %v4float %40 %27
  373. OpStore %_entryPointOutput %41
  374. OpReturn
  375. OpFunctionEnd
  376. )";
  377. SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
  378. true, true);
  379. }
  380. TEST_F(InsertExtractElimTest, ConflictingInsertPreventsOptimization) {
  381. // Note: The SPIR-V assembly has had store/load elimination
  382. // performed to allow the inserts and extracts to directly
  383. // reference each other.
  384. //
  385. // #version 140
  386. //
  387. // in vec4 BaseColor;
  388. //
  389. // struct S_t {
  390. // vec4 v0;
  391. // vec4 v1;
  392. // };
  393. //
  394. // void main()
  395. // {
  396. // S_t s0;
  397. // s0.v1 = BaseColor;
  398. // s0.v1[2] = 0.0;
  399. // gl_FragColor = s0.v1;
  400. // }
  401. const std::string assembly =
  402. R"(OpCapability Shader
  403. %1 = OpExtInstImport "GLSL.std.450"
  404. OpMemoryModel Logical GLSL450
  405. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  406. OpExecutionMode %main OriginUpperLeft
  407. OpSource GLSL 140
  408. OpName %main "main"
  409. OpName %S_t "S_t"
  410. OpMemberName %S_t 0 "v0"
  411. OpMemberName %S_t 1 "v1"
  412. OpName %s0 "s0"
  413. OpName %BaseColor "BaseColor"
  414. OpName %gl_FragColor "gl_FragColor"
  415. %void = OpTypeVoid
  416. %8 = OpTypeFunction %void
  417. %float = OpTypeFloat 32
  418. %v4float = OpTypeVector %float 4
  419. %S_t = OpTypeStruct %v4float %v4float
  420. %_ptr_Function_S_t = OpTypePointer Function %S_t
  421. %int = OpTypeInt 32 1
  422. %int_1 = OpConstant %int 1
  423. %float_0 = OpConstant %float 0
  424. %_ptr_Input_v4float = OpTypePointer Input %v4float
  425. %BaseColor = OpVariable %_ptr_Input_v4float Input
  426. %_ptr_Function_v4float = OpTypePointer Function %v4float
  427. %_ptr_Output_v4float = OpTypePointer Output %v4float
  428. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  429. %main = OpFunction %void None %8
  430. %18 = OpLabel
  431. %s0 = OpVariable %_ptr_Function_S_t Function
  432. %19 = OpLoad %v4float %BaseColor
  433. %20 = OpLoad %S_t %s0
  434. %21 = OpCompositeInsert %S_t %19 %20 1
  435. %22 = OpCompositeInsert %S_t %float_0 %21 1 2
  436. OpStore %s0 %22
  437. %23 = OpCompositeExtract %v4float %22 1
  438. OpStore %gl_FragColor %23
  439. OpReturn
  440. OpFunctionEnd
  441. )";
  442. SinglePassRunAndCheck<SimplificationPass>(assembly, assembly, true, true);
  443. }
  444. TEST_F(InsertExtractElimTest, ConflictingInsertPreventsOptimization2) {
  445. // Note: The SPIR-V assembly has had store/load elimination
  446. // performed to allow the inserts and extracts to directly
  447. // reference each other.
  448. //
  449. // #version 140
  450. //
  451. // in vec4 BaseColor;
  452. //
  453. // struct S_t {
  454. // vec4 v0;
  455. // vec4 v1;
  456. // };
  457. //
  458. // void main()
  459. // {
  460. // S_t s0;
  461. // s0.v1[1] = 1.0; // dead
  462. // s0.v1 = Baseline;
  463. // gl_FragColor = vec4(s0.v1[1], 0.0, 0.0, 0.0);
  464. // }
  465. const std::string before_predefs =
  466. R"(OpCapability Shader
  467. %1 = OpExtInstImport "GLSL.std.450"
  468. OpMemoryModel Logical GLSL450
  469. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  470. OpExecutionMode %main OriginUpperLeft
  471. OpSource GLSL 140
  472. OpName %main "main"
  473. OpName %S_t "S_t"
  474. OpMemberName %S_t 0 "v0"
  475. OpMemberName %S_t 1 "v1"
  476. OpName %s0 "s0"
  477. OpName %BaseColor "BaseColor"
  478. OpName %gl_FragColor "gl_FragColor"
  479. %void = OpTypeVoid
  480. %8 = OpTypeFunction %void
  481. %float = OpTypeFloat 32
  482. %v4float = OpTypeVector %float 4
  483. %S_t = OpTypeStruct %v4float %v4float
  484. %_ptr_Function_S_t = OpTypePointer Function %S_t
  485. %int = OpTypeInt 32 1
  486. %int_1 = OpConstant %int 1
  487. %float_1 = OpConstant %float 1
  488. %uint = OpTypeInt 32 0
  489. %uint_1 = OpConstant %uint 1
  490. %_ptr_Function_float = OpTypePointer Function %float
  491. %_ptr_Input_v4float = OpTypePointer Input %v4float
  492. %BaseColor = OpVariable %_ptr_Input_v4float Input
  493. %_ptr_Function_v4float = OpTypePointer Function %v4float
  494. %_ptr_Output_v4float = OpTypePointer Output %v4float
  495. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  496. %float_0 = OpConstant %float 0
  497. )";
  498. const std::string after_predefs =
  499. R"(OpCapability Shader
  500. %1 = OpExtInstImport "GLSL.std.450"
  501. OpMemoryModel Logical GLSL450
  502. OpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
  503. OpExecutionMode %main OriginUpperLeft
  504. OpSource GLSL 140
  505. OpName %main "main"
  506. OpName %S_t "S_t"
  507. OpMemberName %S_t 0 "v0"
  508. OpMemberName %S_t 1 "v1"
  509. OpName %s0 "s0"
  510. OpName %BaseColor "BaseColor"
  511. OpName %gl_FragColor "gl_FragColor"
  512. %void = OpTypeVoid
  513. %8 = OpTypeFunction %void
  514. %float = OpTypeFloat 32
  515. %v4float = OpTypeVector %float 4
  516. %S_t = OpTypeStruct %v4float %v4float
  517. %_ptr_Function_S_t = OpTypePointer Function %S_t
  518. %int = OpTypeInt 32 1
  519. %int_1 = OpConstant %int 1
  520. %float_1 = OpConstant %float 1
  521. %uint = OpTypeInt 32 0
  522. %uint_1 = OpConstant %uint 1
  523. %_ptr_Function_float = OpTypePointer Function %float
  524. %_ptr_Input_v4float = OpTypePointer Input %v4float
  525. %BaseColor = OpVariable %_ptr_Input_v4float Input
  526. %_ptr_Function_v4float = OpTypePointer Function %v4float
  527. %_ptr_Output_v4float = OpTypePointer Output %v4float
  528. %gl_FragColor = OpVariable %_ptr_Output_v4float Output
  529. %float_0 = OpConstant %float 0
  530. )";
  531. const std::string before =
  532. R"(%main = OpFunction %void None %8
  533. %22 = OpLabel
  534. %s0 = OpVariable %_ptr_Function_S_t Function
  535. %23 = OpLoad %S_t %s0
  536. %24 = OpCompositeInsert %S_t %float_1 %23 1 1
  537. %25 = OpLoad %v4float %BaseColor
  538. %26 = OpCompositeInsert %S_t %25 %24 1
  539. %27 = OpCompositeExtract %float %26 1 1
  540. %28 = OpCompositeConstruct %v4float %27 %float_0 %float_0 %float_0
  541. OpStore %gl_FragColor %28
  542. OpReturn
  543. OpFunctionEnd
  544. )";
  545. const std::string after =
  546. R"(%main = OpFunction %void None %8
  547. %22 = OpLabel
  548. %s0 = OpVariable %_ptr_Function_S_t Function
  549. %23 = OpLoad %S_t %s0
  550. %24 = OpCompositeInsert %S_t %float_1 %23 1 1
  551. %25 = OpLoad %v4float %BaseColor
  552. %26 = OpCompositeInsert %S_t %25 %24 1
  553. %27 = OpCompositeExtract %float %25 1
  554. %28 = OpCompositeConstruct %v4float %27 %float_0 %float_0 %float_0
  555. OpStore %gl_FragColor %28
  556. OpReturn
  557. OpFunctionEnd
  558. )";
  559. SinglePassRunAndCheck<SimplificationPass>(before_predefs + before,
  560. after_predefs + after, true, true);
  561. }
  562. TEST_F(InsertExtractElimTest, MixWithConstants) {
  563. // Extract component of FMix with 0.0 or 1.0 as the a-value.
  564. //
  565. // Note: The SPIR-V assembly has had store/load elimination
  566. // performed to allow the inserts and extracts to directly
  567. // reference each other.
  568. //
  569. // #version 450
  570. //
  571. // layout (location=0) in float bc;
  572. // layout (location=1) in float bc2;
  573. // layout (location=2) in float m;
  574. // layout (location=3) in float m2;
  575. // layout (location=0) out vec4 OutColor;
  576. //
  577. // void main()
  578. // {
  579. // vec4 bcv = vec4(bc, bc2, 0.0, 1.0);
  580. // vec4 bcv2 = vec4(bc2, bc, 1.0, 0.0);
  581. // vec4 v = mix(bcv, bcv2, vec4(0.0,1.0,m,m2));
  582. // OutColor = vec4(v.y);
  583. // }
  584. const std::string predefs =
  585. R"(OpCapability Shader
  586. %1 = OpExtInstImport "GLSL.std.450"
  587. OpMemoryModel Logical GLSL450
  588. OpEntryPoint Fragment %main "main" %bc %bc2 %m %m2 %OutColor
  589. OpExecutionMode %main OriginUpperLeft
  590. OpSource GLSL 450
  591. OpName %main "main"
  592. OpName %bc "bc"
  593. OpName %bc2 "bc2"
  594. OpName %m "m"
  595. OpName %m2 "m2"
  596. OpName %OutColor "OutColor"
  597. OpDecorate %bc Location 0
  598. OpDecorate %bc2 Location 1
  599. OpDecorate %m Location 2
  600. OpDecorate %m2 Location 3
  601. OpDecorate %OutColor Location 0
  602. %void = OpTypeVoid
  603. %9 = OpTypeFunction %void
  604. %float = OpTypeFloat 32
  605. %v4float = OpTypeVector %float 4
  606. %_ptr_Function_v4float = OpTypePointer Function %v4float
  607. %_ptr_Input_float = OpTypePointer Input %float
  608. %bc = OpVariable %_ptr_Input_float Input
  609. %bc2 = OpVariable %_ptr_Input_float Input
  610. %float_0 = OpConstant %float 0
  611. %float_1 = OpConstant %float 1
  612. %m = OpVariable %_ptr_Input_float Input
  613. %m2 = OpVariable %_ptr_Input_float Input
  614. %_ptr_Output_v4float = OpTypePointer Output %v4float
  615. %OutColor = OpVariable %_ptr_Output_v4float Output
  616. %uint = OpTypeInt 32 0
  617. %_ptr_Function_float = OpTypePointer Function %float
  618. )";
  619. const std::string before =
  620. R"(%main = OpFunction %void None %9
  621. %19 = OpLabel
  622. %20 = OpLoad %float %bc
  623. %21 = OpLoad %float %bc2
  624. %22 = OpCompositeConstruct %v4float %20 %21 %float_0 %float_1
  625. %23 = OpLoad %float %bc2
  626. %24 = OpLoad %float %bc
  627. %25 = OpCompositeConstruct %v4float %23 %24 %float_1 %float_0
  628. %26 = OpLoad %float %m
  629. %27 = OpLoad %float %m2
  630. %28 = OpCompositeConstruct %v4float %float_0 %float_1 %26 %27
  631. %29 = OpExtInst %v4float %1 FMix %22 %25 %28
  632. %30 = OpCompositeExtract %float %29 1
  633. %31 = OpCompositeConstruct %v4float %30 %30 %30 %30
  634. OpStore %OutColor %31
  635. OpReturn
  636. OpFunctionEnd
  637. )";
  638. const std::string after =
  639. R"(%main = OpFunction %void None %9
  640. %19 = OpLabel
  641. %20 = OpLoad %float %bc
  642. %21 = OpLoad %float %bc2
  643. %22 = OpCompositeConstruct %v4float %20 %21 %float_0 %float_1
  644. %23 = OpLoad %float %bc2
  645. %24 = OpLoad %float %bc
  646. %25 = OpCompositeConstruct %v4float %23 %24 %float_1 %float_0
  647. %26 = OpLoad %float %m
  648. %27 = OpLoad %float %m2
  649. %28 = OpCompositeConstruct %v4float %float_0 %float_1 %26 %27
  650. %29 = OpExtInst %v4float %1 FMix %22 %25 %28
  651. %31 = OpCompositeConstruct %v4float %24 %24 %24 %24
  652. OpStore %OutColor %31
  653. OpReturn
  654. OpFunctionEnd
  655. )";
  656. SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
  657. true, true);
  658. }
  659. TEST_F(InsertExtractElimTest, VectorShuffle1) {
  660. // Extract component from first vector in VectorShuffle
  661. //
  662. // Note: The SPIR-V assembly has had store/load elimination
  663. // performed to allow the inserts and extracts to directly
  664. // reference each other.
  665. //
  666. // #version 450
  667. //
  668. // layout (location=0) in float bc;
  669. // layout (location=1) in float bc2;
  670. // layout (location=0) out vec4 OutColor;
  671. //
  672. // void main()
  673. // {
  674. // vec4 bcv = vec4(bc, bc2, 0.0, 1.0);
  675. // vec4 v = bcv.zwxy;
  676. // OutColor = vec4(v.y);
  677. // }
  678. const std::string predefs_before =
  679. R"(OpCapability Shader
  680. %1 = OpExtInstImport "GLSL.std.450"
  681. OpMemoryModel Logical GLSL450
  682. OpEntryPoint Fragment %main "main" %bc %bc2 %OutColor
  683. OpExecutionMode %main OriginUpperLeft
  684. OpSource GLSL 450
  685. OpName %main "main"
  686. OpName %bc "bc"
  687. OpName %bc2 "bc2"
  688. OpName %OutColor "OutColor"
  689. OpDecorate %bc Location 0
  690. OpDecorate %bc2 Location 1
  691. OpDecorate %OutColor Location 0
  692. %void = OpTypeVoid
  693. %7 = OpTypeFunction %void
  694. %float = OpTypeFloat 32
  695. %v4float = OpTypeVector %float 4
  696. %_ptr_Function_v4float = OpTypePointer Function %v4float
  697. %_ptr_Input_float = OpTypePointer Input %float
  698. %bc = OpVariable %_ptr_Input_float Input
  699. %bc2 = OpVariable %_ptr_Input_float Input
  700. %float_0 = OpConstant %float 0
  701. %float_1 = OpConstant %float 1
  702. %_ptr_Output_v4float = OpTypePointer Output %v4float
  703. %OutColor = OpVariable %_ptr_Output_v4float Output
  704. %uint = OpTypeInt 32 0
  705. %_ptr_Function_float = OpTypePointer Function %float
  706. )";
  707. const std::string predefs_after = predefs_before +
  708. "%24 = OpConstantComposite %v4float "
  709. "%float_1 %float_1 %float_1 %float_1\n";
  710. const std::string before =
  711. R"(%main = OpFunction %void None %7
  712. %17 = OpLabel
  713. %18 = OpLoad %float %bc
  714. %19 = OpLoad %float %bc2
  715. %20 = OpCompositeConstruct %v4float %18 %19 %float_0 %float_1
  716. %21 = OpVectorShuffle %v4float %20 %20 2 3 0 1
  717. %22 = OpCompositeExtract %float %21 1
  718. %23 = OpCompositeConstruct %v4float %22 %22 %22 %22
  719. OpStore %OutColor %23
  720. OpReturn
  721. OpFunctionEnd
  722. )";
  723. const std::string after =
  724. R"(%main = OpFunction %void None %7
  725. %17 = OpLabel
  726. %18 = OpLoad %float %bc
  727. %19 = OpLoad %float %bc2
  728. %20 = OpCompositeConstruct %v4float %18 %19 %float_0 %float_1
  729. %21 = OpVectorShuffle %v4float %20 %20 2 3 0 1
  730. OpStore %OutColor %24
  731. OpReturn
  732. OpFunctionEnd
  733. )";
  734. SinglePassRunAndCheck<SimplificationPass>(predefs_before + before,
  735. predefs_after + after, true, true);
  736. }
  737. TEST_F(InsertExtractElimTest, VectorShuffle2) {
  738. // Extract component from second vector in VectorShuffle
  739. // Identical to test VectorShuffle1 except for the vector
  740. // shuffle index of 7.
  741. //
  742. // Note: The SPIR-V assembly has had store/load elimination
  743. // performed to allow the inserts and extracts to directly
  744. // reference each other.
  745. //
  746. // #version 450
  747. //
  748. // layout (location=0) in float bc;
  749. // layout (location=1) in float bc2;
  750. // layout (location=0) out vec4 OutColor;
  751. //
  752. // void main()
  753. // {
  754. // vec4 bcv = vec4(bc, bc2, 0.0, 1.0);
  755. // vec4 v = bcv.zwxy;
  756. // OutColor = vec4(v.y);
  757. // }
  758. const std::string predefs_before =
  759. R"(OpCapability Shader
  760. %1 = OpExtInstImport "GLSL.std.450"
  761. OpMemoryModel Logical GLSL450
  762. OpEntryPoint Fragment %main "main" %bc %bc2 %OutColor
  763. OpExecutionMode %main OriginUpperLeft
  764. OpSource GLSL 450
  765. OpName %main "main"
  766. OpName %bc "bc"
  767. OpName %bc2 "bc2"
  768. OpName %OutColor "OutColor"
  769. OpDecorate %bc Location 0
  770. OpDecorate %bc2 Location 1
  771. OpDecorate %OutColor Location 0
  772. %void = OpTypeVoid
  773. %7 = OpTypeFunction %void
  774. %float = OpTypeFloat 32
  775. %v4float = OpTypeVector %float 4
  776. %_ptr_Function_v4float = OpTypePointer Function %v4float
  777. %_ptr_Input_float = OpTypePointer Input %float
  778. %bc = OpVariable %_ptr_Input_float Input
  779. %bc2 = OpVariable %_ptr_Input_float Input
  780. %float_0 = OpConstant %float 0
  781. %float_1 = OpConstant %float 1
  782. %_ptr_Output_v4float = OpTypePointer Output %v4float
  783. %OutColor = OpVariable %_ptr_Output_v4float Output
  784. %uint = OpTypeInt 32 0
  785. %_ptr_Function_float = OpTypePointer Function %float
  786. )";
  787. const std::string predefs_after =
  788. R"(OpCapability Shader
  789. %1 = OpExtInstImport "GLSL.std.450"
  790. OpMemoryModel Logical GLSL450
  791. OpEntryPoint Fragment %main "main" %bc %bc2 %OutColor
  792. OpExecutionMode %main OriginUpperLeft
  793. OpSource GLSL 450
  794. OpName %main "main"
  795. OpName %bc "bc"
  796. OpName %bc2 "bc2"
  797. OpName %OutColor "OutColor"
  798. OpDecorate %bc Location 0
  799. OpDecorate %bc2 Location 1
  800. OpDecorate %OutColor Location 0
  801. %void = OpTypeVoid
  802. %7 = OpTypeFunction %void
  803. %float = OpTypeFloat 32
  804. %v4float = OpTypeVector %float 4
  805. %_ptr_Function_v4float = OpTypePointer Function %v4float
  806. %_ptr_Input_float = OpTypePointer Input %float
  807. %bc = OpVariable %_ptr_Input_float Input
  808. %bc2 = OpVariable %_ptr_Input_float Input
  809. %float_0 = OpConstant %float 0
  810. %float_1 = OpConstant %float 1
  811. %_ptr_Output_v4float = OpTypePointer Output %v4float
  812. %OutColor = OpVariable %_ptr_Output_v4float Output
  813. %uint = OpTypeInt 32 0
  814. %_ptr_Function_float = OpTypePointer Function %float
  815. %24 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
  816. )";
  817. const std::string before =
  818. R"(%main = OpFunction %void None %7
  819. %17 = OpLabel
  820. %18 = OpLoad %float %bc
  821. %19 = OpLoad %float %bc2
  822. %20 = OpCompositeConstruct %v4float %18 %19 %float_0 %float_1
  823. %21 = OpVectorShuffle %v4float %20 %20 2 7 0 1
  824. %22 = OpCompositeExtract %float %21 1
  825. %23 = OpCompositeConstruct %v4float %22 %22 %22 %22
  826. OpStore %OutColor %23
  827. OpReturn
  828. OpFunctionEnd
  829. )";
  830. const std::string after =
  831. R"(%main = OpFunction %void None %7
  832. %17 = OpLabel
  833. %18 = OpLoad %float %bc
  834. %19 = OpLoad %float %bc2
  835. %20 = OpCompositeConstruct %v4float %18 %19 %float_0 %float_1
  836. %21 = OpVectorShuffle %v4float %20 %20 2 7 0 1
  837. OpStore %OutColor %24
  838. OpReturn
  839. OpFunctionEnd
  840. )";
  841. SinglePassRunAndCheck<SimplificationPass>(predefs_before + before,
  842. predefs_after + after, true, true);
  843. }
  844. // TODO(greg-lunarg): Add tests to verify handling of these cases:
  845. //
  846. } // namespace
  847. } // namespace opt
  848. } // namespace spvtools