cfg_cleanup_test.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. // Copyright (c) 2017 Google Inc.
  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 CFGCleanupTest = PassTest<::testing::Test>;
  21. TEST_F(CFGCleanupTest, RemoveUnreachableBlocks) {
  22. const std::string declarations = R"(OpCapability Shader
  23. %1 = OpExtInstImport "GLSL.std.450"
  24. OpMemoryModel Logical GLSL450
  25. OpEntryPoint Fragment %main "main" %inf %outf4
  26. OpExecutionMode %main OriginUpperLeft
  27. OpSource GLSL 450
  28. OpName %main "main"
  29. OpName %inf "inf"
  30. OpName %outf4 "outf4"
  31. OpDecorate %inf Location 0
  32. OpDecorate %outf4 Location 0
  33. %void = OpTypeVoid
  34. %6 = OpTypeFunction %void
  35. %float = OpTypeFloat 32
  36. %_ptr_Input_float = OpTypePointer Input %float
  37. %inf = OpVariable %_ptr_Input_float Input
  38. %float_2 = OpConstant %float 2
  39. %bool = OpTypeBool
  40. %v4float = OpTypeVector %float 4
  41. %_ptr_Output_v4float = OpTypePointer Output %v4float
  42. %outf4 = OpVariable %_ptr_Output_v4float Output
  43. %float_n0_5 = OpConstant %float -0.5
  44. )";
  45. const std::string body_before = R"(%main = OpFunction %void None %6
  46. %14 = OpLabel
  47. OpBranch %18
  48. %19 = OpLabel
  49. %20 = OpLoad %float %inf
  50. %21 = OpCompositeConstruct %v4float %20 %20 %20 %20
  51. OpStore %outf4 %21
  52. OpBranch %17
  53. %18 = OpLabel
  54. %22 = OpLoad %float %inf
  55. %23 = OpFAdd %float %22 %float_n0_5
  56. %24 = OpCompositeConstruct %v4float %23 %23 %23 %23
  57. OpStore %outf4 %24
  58. OpBranch %17
  59. %17 = OpLabel
  60. OpReturn
  61. OpFunctionEnd
  62. )";
  63. const std::string body_after = R"(%main = OpFunction %void None %6
  64. %14 = OpLabel
  65. OpBranch %15
  66. %15 = OpLabel
  67. %20 = OpLoad %float %inf
  68. %21 = OpFAdd %float %20 %float_n0_5
  69. %22 = OpCompositeConstruct %v4float %21 %21 %21 %21
  70. OpStore %outf4 %22
  71. OpBranch %19
  72. %19 = OpLabel
  73. OpReturn
  74. OpFunctionEnd
  75. )";
  76. SinglePassRunAndCheck<CFGCleanupPass>(declarations + body_before,
  77. declarations + body_after, true, true);
  78. }
  79. TEST_F(CFGCleanupTest, RemoveDecorations) {
  80. const std::string before = R"(
  81. OpCapability Shader
  82. %1 = OpExtInstImport "GLSL.std.450"
  83. OpMemoryModel Logical GLSL450
  84. OpEntryPoint Fragment %main "main"
  85. OpExecutionMode %main OriginUpperLeft
  86. OpName %main "main"
  87. OpName %x "x"
  88. OpName %dead "dead"
  89. OpDecorate %x RelaxedPrecision
  90. OpDecorate %dead RelaxedPrecision
  91. %void = OpTypeVoid
  92. %6 = OpTypeFunction %void
  93. %float = OpTypeFloat 32
  94. %_ptr_Function_float = OpTypePointer Function %float
  95. %float_2 = OpConstant %float 2
  96. %float_4 = OpConstant %float 4
  97. %main = OpFunction %void None %6
  98. %14 = OpLabel
  99. %x = OpVariable %_ptr_Function_float Function
  100. OpBranch %18
  101. %19 = OpLabel
  102. %dead = OpVariable %_ptr_Function_float Function
  103. OpStore %dead %float_2
  104. OpBranch %17
  105. %18 = OpLabel
  106. OpStore %x %float_4
  107. OpBranch %17
  108. %17 = OpLabel
  109. OpReturn
  110. OpFunctionEnd
  111. )";
  112. const std::string after = R"(OpCapability Shader
  113. %1 = OpExtInstImport "GLSL.std.450"
  114. OpMemoryModel Logical GLSL450
  115. OpEntryPoint Fragment %main "main"
  116. OpExecutionMode %main OriginUpperLeft
  117. OpName %main "main"
  118. OpName %x "x"
  119. OpDecorate %x RelaxedPrecision
  120. %void = OpTypeVoid
  121. %6 = OpTypeFunction %void
  122. %float = OpTypeFloat 32
  123. %_ptr_Function_float = OpTypePointer Function %float
  124. %float_2 = OpConstant %float 2
  125. %float_4 = OpConstant %float 4
  126. %main = OpFunction %void None %6
  127. %11 = OpLabel
  128. %x = OpVariable %_ptr_Function_float Function
  129. OpBranch %12
  130. %12 = OpLabel
  131. OpStore %x %float_4
  132. OpBranch %14
  133. %14 = OpLabel
  134. OpReturn
  135. OpFunctionEnd
  136. )";
  137. SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
  138. }
  139. TEST_F(CFGCleanupTest, UpdatePhis) {
  140. const std::string before = R"(
  141. OpCapability Shader
  142. %1 = OpExtInstImport "GLSL.std.450"
  143. OpMemoryModel Logical GLSL450
  144. OpEntryPoint Fragment %main "main" %y %outparm
  145. OpExecutionMode %main OriginUpperLeft
  146. OpName %main "main"
  147. OpName %y "y"
  148. OpName %outparm "outparm"
  149. OpDecorate %y Flat
  150. OpDecorate %y Location 0
  151. OpDecorate %outparm Location 0
  152. %void = OpTypeVoid
  153. %3 = OpTypeFunction %void
  154. %int = OpTypeInt 32 1
  155. %_ptr_Function_int = OpTypePointer Function %int
  156. %_ptr_Input_int = OpTypePointer Input %int
  157. %y = OpVariable %_ptr_Input_int Input
  158. %int_10 = OpConstant %int 10
  159. %bool = OpTypeBool
  160. %int_42 = OpConstant %int 42
  161. %int_23 = OpConstant %int 23
  162. %int_5 = OpConstant %int 5
  163. %_ptr_Output_int = OpTypePointer Output %int
  164. %outparm = OpVariable %_ptr_Output_int Output
  165. %main = OpFunction %void None %3
  166. %5 = OpLabel
  167. %11 = OpLoad %int %y
  168. OpBranch %21
  169. %16 = OpLabel
  170. %20 = OpIAdd %int %11 %int_42
  171. OpBranch %17
  172. %21 = OpLabel
  173. %24 = OpISub %int %11 %int_23
  174. OpBranch %17
  175. %17 = OpLabel
  176. %31 = OpPhi %int %20 %16 %24 %21
  177. %27 = OpIAdd %int %31 %int_5
  178. OpStore %outparm %27
  179. OpReturn
  180. OpFunctionEnd
  181. )";
  182. const std::string after = R"(OpCapability Shader
  183. %1 = OpExtInstImport "GLSL.std.450"
  184. OpMemoryModel Logical GLSL450
  185. OpEntryPoint Fragment %main "main" %y %outparm
  186. OpExecutionMode %main OriginUpperLeft
  187. OpName %main "main"
  188. OpName %y "y"
  189. OpName %outparm "outparm"
  190. OpDecorate %y Flat
  191. OpDecorate %y Location 0
  192. OpDecorate %outparm Location 0
  193. %void = OpTypeVoid
  194. %6 = OpTypeFunction %void
  195. %int = OpTypeInt 32 1
  196. %_ptr_Function_int = OpTypePointer Function %int
  197. %_ptr_Input_int = OpTypePointer Input %int
  198. %y = OpVariable %_ptr_Input_int Input
  199. %int_10 = OpConstant %int 10
  200. %bool = OpTypeBool
  201. %int_42 = OpConstant %int 42
  202. %int_23 = OpConstant %int 23
  203. %int_5 = OpConstant %int 5
  204. %_ptr_Output_int = OpTypePointer Output %int
  205. %outparm = OpVariable %_ptr_Output_int Output
  206. %main = OpFunction %void None %6
  207. %16 = OpLabel
  208. %17 = OpLoad %int %y
  209. OpBranch %18
  210. %18 = OpLabel
  211. %22 = OpISub %int %17 %int_23
  212. OpBranch %21
  213. %21 = OpLabel
  214. %23 = OpPhi %int %22 %18
  215. %24 = OpIAdd %int %23 %int_5
  216. OpStore %outparm %24
  217. OpReturn
  218. OpFunctionEnd
  219. )";
  220. SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
  221. }
  222. TEST_F(CFGCleanupTest, RemoveNamedLabels) {
  223. const std::string before = R"(
  224. OpCapability Shader
  225. %1 = OpExtInstImport "GLSL.std.450"
  226. OpMemoryModel Logical GLSL450
  227. OpEntryPoint Vertex %main "main"
  228. OpSource GLSL 430
  229. OpName %main "main"
  230. OpName %dead "dead"
  231. %void = OpTypeVoid
  232. %5 = OpTypeFunction %void
  233. %main = OpFunction %void None %5
  234. %6 = OpLabel
  235. OpReturn
  236. %dead = OpLabel
  237. OpReturn
  238. OpFunctionEnd)";
  239. const std::string after = R"(OpCapability Shader
  240. %1 = OpExtInstImport "GLSL.std.450"
  241. OpMemoryModel Logical GLSL450
  242. OpEntryPoint Vertex %main "main"
  243. OpSource GLSL 430
  244. OpName %main "main"
  245. %void = OpTypeVoid
  246. %5 = OpTypeFunction %void
  247. %main = OpFunction %void None %5
  248. %6 = OpLabel
  249. OpReturn
  250. OpFunctionEnd
  251. )";
  252. SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
  253. }
  254. TEST_F(CFGCleanupTest, RemovePhiArgsFromFarBlocks) {
  255. const std::string before = R"(
  256. OpCapability Shader
  257. %1 = OpExtInstImport "GLSL.std.450"
  258. OpMemoryModel Logical GLSL450
  259. OpEntryPoint Fragment %main "main" %y %outparm
  260. OpExecutionMode %main OriginUpperLeft
  261. OpName %main "main"
  262. OpName %y "y"
  263. OpName %outparm "outparm"
  264. OpDecorate %y Flat
  265. OpDecorate %y Location 0
  266. OpDecorate %outparm Location 0
  267. %void = OpTypeVoid
  268. %3 = OpTypeFunction %void
  269. %int = OpTypeInt 32 1
  270. %_ptr_Function_int = OpTypePointer Function %int
  271. %_ptr_Input_int = OpTypePointer Input %int
  272. %y = OpVariable %_ptr_Input_int Input
  273. %int_42 = OpConstant %int 42
  274. %_ptr_Output_int = OpTypePointer Output %int
  275. %outparm = OpVariable %_ptr_Output_int Output
  276. %int_14 = OpConstant %int 14
  277. %int_15 = OpConstant %int 15
  278. %int_5 = OpConstant %int 5
  279. %main = OpFunction %void None %3
  280. %5 = OpLabel
  281. OpBranch %40
  282. %41 = OpLabel
  283. %11 = OpLoad %int %y
  284. OpBranch %40
  285. %40 = OpLabel
  286. %12 = OpLoad %int %y
  287. OpSelectionMerge %16 None
  288. OpSwitch %12 %16 10 %13 13 %14 18 %15
  289. %13 = OpLabel
  290. OpBranch %16
  291. %14 = OpLabel
  292. OpStore %outparm %int_14
  293. OpBranch %16
  294. %15 = OpLabel
  295. OpStore %outparm %int_15
  296. OpBranch %16
  297. %16 = OpLabel
  298. %30 = OpPhi %int %11 %40 %int_42 %13 %11 %14 %11 %15
  299. %28 = OpIAdd %int %30 %int_5
  300. OpStore %outparm %28
  301. OpReturn
  302. OpFunctionEnd)";
  303. const std::string after = R"(OpCapability Shader
  304. %1 = OpExtInstImport "GLSL.std.450"
  305. OpMemoryModel Logical GLSL450
  306. OpEntryPoint Fragment %main "main" %y %outparm
  307. OpExecutionMode %main OriginUpperLeft
  308. OpName %main "main"
  309. OpName %y "y"
  310. OpName %outparm "outparm"
  311. OpDecorate %y Flat
  312. OpDecorate %y Location 0
  313. OpDecorate %outparm Location 0
  314. %void = OpTypeVoid
  315. %6 = OpTypeFunction %void
  316. %int = OpTypeInt 32 1
  317. %_ptr_Function_int = OpTypePointer Function %int
  318. %_ptr_Input_int = OpTypePointer Input %int
  319. %y = OpVariable %_ptr_Input_int Input
  320. %int_42 = OpConstant %int 42
  321. %_ptr_Output_int = OpTypePointer Output %int
  322. %outparm = OpVariable %_ptr_Output_int Output
  323. %int_14 = OpConstant %int 14
  324. %int_15 = OpConstant %int 15
  325. %int_5 = OpConstant %int 5
  326. %26 = OpUndef %int
  327. %main = OpFunction %void None %6
  328. %15 = OpLabel
  329. OpBranch %16
  330. %16 = OpLabel
  331. %19 = OpLoad %int %y
  332. OpSelectionMerge %20 None
  333. OpSwitch %19 %20 10 %21 13 %22 18 %23
  334. %21 = OpLabel
  335. OpBranch %20
  336. %22 = OpLabel
  337. OpStore %outparm %int_14
  338. OpBranch %20
  339. %23 = OpLabel
  340. OpStore %outparm %int_15
  341. OpBranch %20
  342. %20 = OpLabel
  343. %24 = OpPhi %int %26 %16 %int_42 %21 %26 %22 %26 %23
  344. %25 = OpIAdd %int %24 %int_5
  345. OpStore %outparm %25
  346. OpReturn
  347. OpFunctionEnd
  348. )";
  349. SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
  350. }
  351. TEST_F(CFGCleanupTest, RemovePhiConstantArgs) {
  352. const std::string before = R"(
  353. OpCapability Shader
  354. %1 = OpExtInstImport "GLSL.std.450"
  355. OpMemoryModel Logical GLSL450
  356. OpEntryPoint Fragment %main "main" %y %outparm
  357. OpExecutionMode %main OriginUpperLeft
  358. OpName %main "main"
  359. OpName %y "y"
  360. OpName %outparm "outparm"
  361. OpDecorate %y Flat
  362. OpDecorate %y Location 0
  363. OpDecorate %outparm Location 0
  364. %void = OpTypeVoid
  365. %3 = OpTypeFunction %void
  366. %int = OpTypeInt 32 1
  367. %_ptr_Input_int = OpTypePointer Input %int
  368. %y = OpVariable %_ptr_Input_int Input
  369. %int_10 = OpConstant %int 10
  370. %bool = OpTypeBool
  371. %_ptr_Function_int = OpTypePointer Function %int
  372. %int_23 = OpConstant %int 23
  373. %int_5 = OpConstant %int 5
  374. %_ptr_Output_int = OpTypePointer Output %int
  375. %outparm = OpVariable %_ptr_Output_int Output
  376. %24 = OpUndef %int
  377. %main = OpFunction %void None %3
  378. %5 = OpLabel
  379. OpBranch %14
  380. %40 = OpLabel
  381. %9 = OpLoad %int %y
  382. %12 = OpSGreaterThan %bool %9 %int_10
  383. OpSelectionMerge %14 None
  384. OpBranchConditional %12 %13 %14
  385. %13 = OpLabel
  386. OpBranch %14
  387. %14 = OpLabel
  388. %25 = OpPhi %int %24 %5 %int_23 %13
  389. %20 = OpIAdd %int %25 %int_5
  390. OpStore %outparm %20
  391. OpReturn
  392. OpFunctionEnd)";
  393. const std::string after = R"(OpCapability Shader
  394. %1 = OpExtInstImport "GLSL.std.450"
  395. OpMemoryModel Logical GLSL450
  396. OpEntryPoint Fragment %main "main" %y %outparm
  397. OpExecutionMode %main OriginUpperLeft
  398. OpName %main "main"
  399. OpName %y "y"
  400. OpName %outparm "outparm"
  401. OpDecorate %y Flat
  402. OpDecorate %y Location 0
  403. OpDecorate %outparm Location 0
  404. %void = OpTypeVoid
  405. %6 = OpTypeFunction %void
  406. %int = OpTypeInt 32 1
  407. %_ptr_Input_int = OpTypePointer Input %int
  408. %y = OpVariable %_ptr_Input_int Input
  409. %int_10 = OpConstant %int 10
  410. %bool = OpTypeBool
  411. %_ptr_Function_int = OpTypePointer Function %int
  412. %int_23 = OpConstant %int 23
  413. %int_5 = OpConstant %int 5
  414. %_ptr_Output_int = OpTypePointer Output %int
  415. %outparm = OpVariable %_ptr_Output_int Output
  416. %15 = OpUndef %int
  417. %main = OpFunction %void None %6
  418. %16 = OpLabel
  419. OpBranch %17
  420. %17 = OpLabel
  421. %22 = OpPhi %int %15 %16
  422. %23 = OpIAdd %int %22 %int_5
  423. OpStore %outparm %23
  424. OpReturn
  425. OpFunctionEnd
  426. )";
  427. SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
  428. }
  429. } // namespace
  430. } // namespace opt
  431. } // namespace spvtools