wrap_opkill_test.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  1. // Copyright (c) 2019 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 "test/opt/assembly_builder.h"
  15. #include "test/opt/pass_fixture.h"
  16. #include "test/opt/pass_utils.h"
  17. namespace spvtools {
  18. namespace opt {
  19. namespace {
  20. using WrapOpKillTest = PassTest<::testing::Test>;
  21. TEST_F(WrapOpKillTest, SingleOpKill) {
  22. const std::string text = R"(
  23. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  24. ; CHECK: [[main]] = OpFunction
  25. ; CHECK: OpFunctionCall %void [[orig_kill:%\w+]]
  26. ; CHECK: [[orig_kill]] = OpFunction
  27. ; CHECK-NEXT: OpLabel
  28. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  29. ; CHECK-NEXT: OpReturn
  30. ; CHECK: [[new_kill]] = OpFunction
  31. ; CHECK-NEXT: OpLabel
  32. ; CHECK-NEXT: OpKill
  33. ; CHECK-NEXT: OpFunctionEnd
  34. OpCapability Shader
  35. %1 = OpExtInstImport "GLSL.std.450"
  36. OpMemoryModel Logical GLSL450
  37. OpEntryPoint Fragment %main "main"
  38. OpExecutionMode %main OriginUpperLeft
  39. OpSource GLSL 330
  40. OpName %main "main"
  41. %void = OpTypeVoid
  42. %5 = OpTypeFunction %void
  43. %bool = OpTypeBool
  44. %true = OpConstantTrue %bool
  45. %main = OpFunction %void None %5
  46. %8 = OpLabel
  47. OpBranch %9
  48. %9 = OpLabel
  49. OpLoopMerge %10 %11 None
  50. OpBranch %12
  51. %12 = OpLabel
  52. OpBranchConditional %true %13 %10
  53. %13 = OpLabel
  54. OpBranch %11
  55. %11 = OpLabel
  56. %14 = OpFunctionCall %void %kill_
  57. OpBranch %9
  58. %10 = OpLabel
  59. OpReturn
  60. OpFunctionEnd
  61. %kill_ = OpFunction %void None %5
  62. %15 = OpLabel
  63. OpKill
  64. OpFunctionEnd
  65. )";
  66. SinglePassRunAndMatch<WrapOpKill>(text, true);
  67. }
  68. TEST_F(WrapOpKillTest, MultipleOpKillInSameFunc) {
  69. const std::string text = R"(
  70. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  71. ; CHECK: [[main]] = OpFunction
  72. ; CHECK: OpFunctionCall %void [[orig_kill:%\w+]]
  73. ; CHECK: [[orig_kill]] = OpFunction
  74. ; CHECK-NEXT: OpLabel
  75. ; CHECK-NEXT: OpSelectionMerge
  76. ; CHECK-NEXT: OpBranchConditional
  77. ; CHECK-NEXT: OpLabel
  78. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  79. ; CHECK-NEXT: OpReturn
  80. ; CHECK-NEXT: OpLabel
  81. ; CHECK-NEXT: OpFunctionCall %void [[new_kill]]
  82. ; CHECK-NEXT: OpReturn
  83. ; CHECK: [[new_kill]] = OpFunction
  84. ; CHECK-NEXT: OpLabel
  85. ; CHECK-NEXT: OpKill
  86. ; CHECK-NEXT: OpFunctionEnd
  87. OpCapability Shader
  88. %1 = OpExtInstImport "GLSL.std.450"
  89. OpMemoryModel Logical GLSL450
  90. OpEntryPoint Fragment %main "main"
  91. OpExecutionMode %main OriginUpperLeft
  92. OpSource GLSL 330
  93. OpName %main "main"
  94. %void = OpTypeVoid
  95. %5 = OpTypeFunction %void
  96. %bool = OpTypeBool
  97. %true = OpConstantTrue %bool
  98. %main = OpFunction %void None %5
  99. %8 = OpLabel
  100. OpBranch %9
  101. %9 = OpLabel
  102. OpLoopMerge %10 %11 None
  103. OpBranch %12
  104. %12 = OpLabel
  105. OpBranchConditional %true %13 %10
  106. %13 = OpLabel
  107. OpBranch %11
  108. %11 = OpLabel
  109. %14 = OpFunctionCall %void %kill_
  110. OpBranch %9
  111. %10 = OpLabel
  112. OpReturn
  113. OpFunctionEnd
  114. %kill_ = OpFunction %void None %5
  115. %15 = OpLabel
  116. OpSelectionMerge %16 None
  117. OpBranchConditional %true %17 %18
  118. %17 = OpLabel
  119. OpKill
  120. %18 = OpLabel
  121. OpKill
  122. %16 = OpLabel
  123. OpReturn
  124. OpFunctionEnd
  125. )";
  126. SinglePassRunAndMatch<WrapOpKill>(text, true);
  127. }
  128. TEST_F(WrapOpKillTest, MultipleOpKillInDifferentFunc) {
  129. const std::string text = R"(
  130. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  131. ; CHECK: [[main]] = OpFunction
  132. ; CHECK: OpFunctionCall %void [[orig_kill1:%\w+]]
  133. ; CHECK-NEXT: OpFunctionCall %void [[orig_kill2:%\w+]]
  134. ; CHECK: [[orig_kill1]] = OpFunction
  135. ; CHECK-NEXT: OpLabel
  136. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  137. ; CHECK-NEXT: OpReturn
  138. ; CHECK: [[orig_kill2]] = OpFunction
  139. ; CHECK-NEXT: OpLabel
  140. ; CHECK-NEXT: OpFunctionCall %void [[new_kill]]
  141. ; CHECK-NEXT: OpReturn
  142. ; CHECK: [[new_kill]] = OpFunction
  143. ; CHECK-NEXT: OpLabel
  144. ; CHECK-NEXT: OpKill
  145. ; CHECK-NEXT: OpFunctionEnd
  146. OpCapability Shader
  147. %1 = OpExtInstImport "GLSL.std.450"
  148. OpMemoryModel Logical GLSL450
  149. OpEntryPoint Fragment %main "main"
  150. OpExecutionMode %main OriginUpperLeft
  151. OpSource GLSL 330
  152. OpName %main "main"
  153. %void = OpTypeVoid
  154. %4 = OpTypeFunction %void
  155. %bool = OpTypeBool
  156. %true = OpConstantTrue %bool
  157. %main = OpFunction %void None %4
  158. %7 = OpLabel
  159. OpBranch %8
  160. %8 = OpLabel
  161. OpLoopMerge %9 %10 None
  162. OpBranch %11
  163. %11 = OpLabel
  164. OpBranchConditional %true %12 %9
  165. %12 = OpLabel
  166. OpBranch %10
  167. %10 = OpLabel
  168. %13 = OpFunctionCall %void %14
  169. %15 = OpFunctionCall %void %16
  170. OpBranch %8
  171. %9 = OpLabel
  172. OpReturn
  173. OpFunctionEnd
  174. %14 = OpFunction %void None %4
  175. %17 = OpLabel
  176. OpKill
  177. OpFunctionEnd
  178. %16 = OpFunction %void None %4
  179. %18 = OpLabel
  180. OpKill
  181. OpFunctionEnd
  182. )";
  183. SinglePassRunAndMatch<WrapOpKill>(text, true);
  184. }
  185. TEST_F(WrapOpKillTest, SingleOpTerminateInvocation) {
  186. const std::string text = R"(
  187. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  188. ; CHECK: [[main]] = OpFunction
  189. ; CHECK: OpFunctionCall %void [[orig_kill:%\w+]]
  190. ; CHECK: [[orig_kill]] = OpFunction
  191. ; CHECK-NEXT: OpLabel
  192. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  193. ; CHECK-NEXT: OpReturn
  194. ; CHECK: [[new_kill]] = OpFunction
  195. ; CHECK-NEXT: OpLabel
  196. ; CHECK-NEXT: OpTerminateInvocation
  197. ; CHECK-NEXT: OpFunctionEnd
  198. OpCapability Shader
  199. OpExtension "SPV_KHR_terminate_invocation"
  200. %1 = OpExtInstImport "GLSL.std.450"
  201. OpMemoryModel Logical GLSL450
  202. OpEntryPoint Fragment %main "main"
  203. OpExecutionMode %main OriginUpperLeft
  204. OpSource GLSL 330
  205. OpName %main "main"
  206. %void = OpTypeVoid
  207. %5 = OpTypeFunction %void
  208. %bool = OpTypeBool
  209. %true = OpConstantTrue %bool
  210. %main = OpFunction %void None %5
  211. %8 = OpLabel
  212. OpBranch %9
  213. %9 = OpLabel
  214. OpLoopMerge %10 %11 None
  215. OpBranch %12
  216. %12 = OpLabel
  217. OpBranchConditional %true %13 %10
  218. %13 = OpLabel
  219. OpBranch %11
  220. %11 = OpLabel
  221. %14 = OpFunctionCall %void %kill_
  222. OpBranch %9
  223. %10 = OpLabel
  224. OpReturn
  225. OpFunctionEnd
  226. %kill_ = OpFunction %void None %5
  227. %15 = OpLabel
  228. OpTerminateInvocation
  229. OpFunctionEnd
  230. )";
  231. SinglePassRunAndMatch<WrapOpKill>(text, true);
  232. }
  233. TEST_F(WrapOpKillTest, MultipleTerminateInvocationInSameFunc) {
  234. const std::string text = R"(
  235. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  236. ; CHECK: [[main]] = OpFunction
  237. ; CHECK: OpFunctionCall %void [[orig_kill:%\w+]]
  238. ; CHECK: [[orig_kill]] = OpFunction
  239. ; CHECK-NEXT: OpLabel
  240. ; CHECK-NEXT: OpSelectionMerge
  241. ; CHECK-NEXT: OpBranchConditional
  242. ; CHECK-NEXT: OpLabel
  243. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  244. ; CHECK-NEXT: OpReturn
  245. ; CHECK-NEXT: OpLabel
  246. ; CHECK-NEXT: OpFunctionCall %void [[new_kill]]
  247. ; CHECK-NEXT: OpReturn
  248. ; CHECK: [[new_kill]] = OpFunction
  249. ; CHECK-NEXT: OpLabel
  250. ; CHECK-NEXT: OpTerminateInvocation
  251. ; CHECK-NEXT: OpFunctionEnd
  252. OpCapability Shader
  253. OpExtension "SPV_KHR_terminate_invocation"
  254. %1 = OpExtInstImport "GLSL.std.450"
  255. OpMemoryModel Logical GLSL450
  256. OpEntryPoint Fragment %main "main"
  257. OpExecutionMode %main OriginUpperLeft
  258. OpSource GLSL 330
  259. OpName %main "main"
  260. %void = OpTypeVoid
  261. %5 = OpTypeFunction %void
  262. %bool = OpTypeBool
  263. %true = OpConstantTrue %bool
  264. %main = OpFunction %void None %5
  265. %8 = OpLabel
  266. OpBranch %9
  267. %9 = OpLabel
  268. OpLoopMerge %10 %11 None
  269. OpBranch %12
  270. %12 = OpLabel
  271. OpBranchConditional %true %13 %10
  272. %13 = OpLabel
  273. OpBranch %11
  274. %11 = OpLabel
  275. %14 = OpFunctionCall %void %kill_
  276. OpBranch %9
  277. %10 = OpLabel
  278. OpReturn
  279. OpFunctionEnd
  280. %kill_ = OpFunction %void None %5
  281. %15 = OpLabel
  282. OpSelectionMerge %16 None
  283. OpBranchConditional %true %17 %18
  284. %17 = OpLabel
  285. OpTerminateInvocation
  286. %18 = OpLabel
  287. OpTerminateInvocation
  288. %16 = OpLabel
  289. OpReturn
  290. OpFunctionEnd
  291. )";
  292. SinglePassRunAndMatch<WrapOpKill>(text, true);
  293. }
  294. TEST_F(WrapOpKillTest, MultipleOpTerminateInvocationDifferentFunc) {
  295. const std::string text = R"(
  296. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  297. ; CHECK: [[main]] = OpFunction
  298. ; CHECK: OpFunctionCall %void [[orig_kill1:%\w+]]
  299. ; CHECK-NEXT: OpFunctionCall %void [[orig_kill2:%\w+]]
  300. ; CHECK: [[orig_kill1]] = OpFunction
  301. ; CHECK-NEXT: OpLabel
  302. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  303. ; CHECK-NEXT: OpReturn
  304. ; CHECK: [[orig_kill2]] = OpFunction
  305. ; CHECK-NEXT: OpLabel
  306. ; CHECK-NEXT: OpFunctionCall %void [[new_kill]]
  307. ; CHECK-NEXT: OpReturn
  308. ; CHECK: [[new_kill]] = OpFunction
  309. ; CHECK-NEXT: OpLabel
  310. ; CHECK-NEXT: OpTerminateInvocation
  311. ; CHECK-NEXT: OpFunctionEnd
  312. OpCapability Shader
  313. OpExtension "SPV_KHR_terminate_invocation"
  314. %1 = OpExtInstImport "GLSL.std.450"
  315. OpMemoryModel Logical GLSL450
  316. OpEntryPoint Fragment %main "main"
  317. OpExecutionMode %main OriginUpperLeft
  318. OpSource GLSL 330
  319. OpName %main "main"
  320. %void = OpTypeVoid
  321. %4 = OpTypeFunction %void
  322. %bool = OpTypeBool
  323. %true = OpConstantTrue %bool
  324. %main = OpFunction %void None %4
  325. %7 = OpLabel
  326. OpBranch %8
  327. %8 = OpLabel
  328. OpLoopMerge %9 %10 None
  329. OpBranch %11
  330. %11 = OpLabel
  331. OpBranchConditional %true %12 %9
  332. %12 = OpLabel
  333. OpBranch %10
  334. %10 = OpLabel
  335. %13 = OpFunctionCall %void %14
  336. %15 = OpFunctionCall %void %16
  337. OpBranch %8
  338. %9 = OpLabel
  339. OpReturn
  340. OpFunctionEnd
  341. %14 = OpFunction %void None %4
  342. %17 = OpLabel
  343. OpTerminateInvocation
  344. OpFunctionEnd
  345. %16 = OpFunction %void None %4
  346. %18 = OpLabel
  347. OpTerminateInvocation
  348. OpFunctionEnd
  349. )";
  350. SinglePassRunAndMatch<WrapOpKill>(text, true);
  351. }
  352. TEST_F(WrapOpKillTest, KillAndTerminateInvocationSameFunc) {
  353. const std::string text = R"(
  354. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  355. ; CHECK: [[main]] = OpFunction
  356. ; CHECK: OpFunctionCall %void [[orig_kill:%\w+]]
  357. ; CHECK: [[orig_kill]] = OpFunction
  358. ; CHECK-NEXT: OpLabel
  359. ; CHECK-NEXT: OpSelectionMerge
  360. ; CHECK-NEXT: OpBranchConditional
  361. ; CHECK-NEXT: OpLabel
  362. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  363. ; CHECK-NEXT: OpReturn
  364. ; CHECK-NEXT: OpLabel
  365. ; CHECK-NEXT: OpFunctionCall %void [[new_terminate:%\w+]]
  366. ; CHECK-NEXT: OpReturn
  367. ; CHECK: [[new_kill]] = OpFunction
  368. ; CHECK-NEXT: OpLabel
  369. ; CHECK-NEXT: OpKill
  370. ; CHECK-NEXT: OpFunctionEnd
  371. ; CHECK-NEXT: [[new_terminate]] = OpFunction
  372. ; CHECK-NEXT: OpLabel
  373. ; CHECK-NEXT: OpTerminateInvocation
  374. ; CHECK-NEXT: OpFunctionEnd
  375. OpCapability Shader
  376. OpExtension "SPV_KHR_terminate_invocation"
  377. %1 = OpExtInstImport "GLSL.std.450"
  378. OpMemoryModel Logical GLSL450
  379. OpEntryPoint Fragment %main "main"
  380. OpExecutionMode %main OriginUpperLeft
  381. OpSource GLSL 330
  382. OpName %main "main"
  383. %void = OpTypeVoid
  384. %5 = OpTypeFunction %void
  385. %bool = OpTypeBool
  386. %true = OpConstantTrue %bool
  387. %main = OpFunction %void None %5
  388. %8 = OpLabel
  389. OpBranch %9
  390. %9 = OpLabel
  391. OpLoopMerge %10 %11 None
  392. OpBranch %12
  393. %12 = OpLabel
  394. OpBranchConditional %true %13 %10
  395. %13 = OpLabel
  396. OpBranch %11
  397. %11 = OpLabel
  398. %14 = OpFunctionCall %void %kill_
  399. OpBranch %9
  400. %10 = OpLabel
  401. OpReturn
  402. OpFunctionEnd
  403. %kill_ = OpFunction %void None %5
  404. %15 = OpLabel
  405. OpSelectionMerge %16 None
  406. OpBranchConditional %true %17 %18
  407. %17 = OpLabel
  408. OpKill
  409. %18 = OpLabel
  410. OpTerminateInvocation
  411. %16 = OpLabel
  412. OpReturn
  413. OpFunctionEnd
  414. )";
  415. SinglePassRunAndMatch<WrapOpKill>(text, true);
  416. }
  417. TEST_F(WrapOpKillTest, KillAndTerminateInvocationDifferentFunc) {
  418. const std::string text = R"(
  419. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  420. ; CHECK: [[main]] = OpFunction
  421. ; CHECK: OpFunctionCall %void [[orig_kill1:%\w+]]
  422. ; CHECK-NEXT: OpFunctionCall %void [[orig_kill2:%\w+]]
  423. ; CHECK: [[orig_kill1]] = OpFunction
  424. ; CHECK-NEXT: OpLabel
  425. ; CHECK-NEXT: OpFunctionCall %void [[new_terminate:%\w+]]
  426. ; CHECK-NEXT: OpReturn
  427. ; CHECK: [[orig_kill2]] = OpFunction
  428. ; CHECK-NEXT: OpLabel
  429. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  430. ; CHECK-NEXT: OpReturn
  431. ; CHECK: [[new_kill]] = OpFunction
  432. ; CHECK-NEXT: OpLabel
  433. ; CHECK-NEXT: OpKill
  434. ; CHECK-NEXT: OpFunctionEnd
  435. ; CHECK-NEXT: [[new_terminate]] = OpFunction
  436. ; CHECK-NEXT: OpLabel
  437. ; CHECK-NEXT: OpTerminateInvocation
  438. ; CHECK-NEXT: OpFunctionEnd
  439. OpCapability Shader
  440. OpExtension "SPV_KHR_terminate_invocation"
  441. %1 = OpExtInstImport "GLSL.std.450"
  442. OpMemoryModel Logical GLSL450
  443. OpEntryPoint Fragment %main "main"
  444. OpExecutionMode %main OriginUpperLeft
  445. OpSource GLSL 330
  446. OpName %main "main"
  447. %void = OpTypeVoid
  448. %4 = OpTypeFunction %void
  449. %bool = OpTypeBool
  450. %true = OpConstantTrue %bool
  451. %main = OpFunction %void None %4
  452. %7 = OpLabel
  453. OpBranch %8
  454. %8 = OpLabel
  455. OpLoopMerge %9 %10 None
  456. OpBranch %11
  457. %11 = OpLabel
  458. OpBranchConditional %true %12 %9
  459. %12 = OpLabel
  460. OpBranch %10
  461. %10 = OpLabel
  462. %13 = OpFunctionCall %void %14
  463. %15 = OpFunctionCall %void %16
  464. OpBranch %8
  465. %9 = OpLabel
  466. OpReturn
  467. OpFunctionEnd
  468. %14 = OpFunction %void None %4
  469. %17 = OpLabel
  470. OpTerminateInvocation
  471. OpFunctionEnd
  472. %16 = OpFunction %void None %4
  473. %18 = OpLabel
  474. OpKill
  475. OpFunctionEnd
  476. )";
  477. SinglePassRunAndMatch<WrapOpKill>(text, true);
  478. }
  479. TEST_F(WrapOpKillTest, FuncWithReturnValue) {
  480. const std::string text = R"(
  481. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  482. ; CHECK: [[main]] = OpFunction
  483. ; CHECK: OpFunctionCall %int [[orig_kill:%\w+]]
  484. ; CHECK: [[orig_kill]] = OpFunction
  485. ; CHECK-NEXT: OpLabel
  486. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  487. ; CHECK-NEXT: [[undef:%\w+]] = OpUndef %int
  488. ; CHECK-NEXT: OpReturnValue [[undef]]
  489. ; CHECK: [[new_kill]] = OpFunction
  490. ; CHECK-NEXT: OpLabel
  491. ; CHECK-NEXT: OpKill
  492. ; CHECK-NEXT: OpFunctionEnd
  493. OpCapability Shader
  494. %1 = OpExtInstImport "GLSL.std.450"
  495. OpMemoryModel Logical GLSL450
  496. OpEntryPoint Fragment %main "main"
  497. OpExecutionMode %main OriginUpperLeft
  498. OpSource GLSL 330
  499. OpName %main "main"
  500. %void = OpTypeVoid
  501. %5 = OpTypeFunction %void
  502. %int = OpTypeInt 32 1
  503. %func_type = OpTypeFunction %int
  504. %bool = OpTypeBool
  505. %true = OpConstantTrue %bool
  506. %main = OpFunction %void None %5
  507. %8 = OpLabel
  508. OpBranch %9
  509. %9 = OpLabel
  510. OpLoopMerge %10 %11 None
  511. OpBranch %12
  512. %12 = OpLabel
  513. OpBranchConditional %true %13 %10
  514. %13 = OpLabel
  515. OpBranch %11
  516. %11 = OpLabel
  517. %14 = OpFunctionCall %int %kill_
  518. OpBranch %9
  519. %10 = OpLabel
  520. OpReturn
  521. OpFunctionEnd
  522. %kill_ = OpFunction %int None %func_type
  523. %15 = OpLabel
  524. OpKill
  525. OpFunctionEnd
  526. )";
  527. SinglePassRunAndMatch<WrapOpKill>(text, true);
  528. }
  529. TEST_F(WrapOpKillTest, IdBoundOverflow1) {
  530. const std::string text = R"(
  531. OpCapability GeometryStreams
  532. OpMemoryModel Logical GLSL450
  533. OpEntryPoint Fragment %main "main"
  534. OpExecutionMode %main OriginUpperLeft
  535. %2 = OpTypeVoid
  536. %3 = OpTypeFunction %2
  537. %bool = OpTypeBool
  538. %true = OpConstantTrue %bool
  539. %main = OpFunction %2 None %3
  540. %8 = OpLabel
  541. OpBranch %9
  542. %9 = OpLabel
  543. OpLoopMerge %10 %11 None
  544. OpBranch %12
  545. %12 = OpLabel
  546. OpBranchConditional %true %13 %10
  547. %13 = OpLabel
  548. OpBranch %11
  549. %11 = OpLabel
  550. %14 = OpFunctionCall %void %kill_
  551. OpBranch %9
  552. %10 = OpLabel
  553. OpReturn
  554. OpFunctionEnd
  555. %kill_ = OpFunction %2 Pure|Const %3
  556. %4194302 = OpLabel
  557. OpKill
  558. OpFunctionEnd
  559. )";
  560. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  561. std::vector<Message> messages = {
  562. {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}};
  563. SetMessageConsumer(GetTestMessageConsumer(messages));
  564. auto result = SinglePassRunToBinary<WrapOpKill>(text, true);
  565. EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
  566. }
  567. TEST_F(WrapOpKillTest, IdBoundOverflow2) {
  568. const std::string text = R"(
  569. OpCapability GeometryStreams
  570. OpMemoryModel Logical GLSL450
  571. OpEntryPoint Fragment %main "main"
  572. OpExecutionMode %main OriginUpperLeft
  573. %2 = OpTypeVoid
  574. %3 = OpTypeFunction %2
  575. %bool = OpTypeBool
  576. %true = OpConstantTrue %bool
  577. %main = OpFunction %2 None %3
  578. %8 = OpLabel
  579. OpBranch %9
  580. %9 = OpLabel
  581. OpLoopMerge %10 %11 None
  582. OpBranch %12
  583. %12 = OpLabel
  584. OpBranchConditional %true %13 %10
  585. %13 = OpLabel
  586. OpBranch %11
  587. %11 = OpLabel
  588. %14 = OpFunctionCall %void %kill_
  589. OpBranch %9
  590. %10 = OpLabel
  591. OpReturn
  592. OpFunctionEnd
  593. %kill_ = OpFunction %2 Pure|Const %3
  594. %4194301 = OpLabel
  595. OpKill
  596. OpFunctionEnd
  597. )";
  598. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  599. std::vector<Message> messages = {
  600. {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}};
  601. SetMessageConsumer(GetTestMessageConsumer(messages));
  602. auto result = SinglePassRunToBinary<WrapOpKill>(text, true);
  603. EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
  604. }
  605. TEST_F(WrapOpKillTest, IdBoundOverflow3) {
  606. const std::string text = R"(
  607. OpCapability GeometryStreams
  608. OpMemoryModel Logical GLSL450
  609. OpEntryPoint Fragment %main "main"
  610. OpExecutionMode %main OriginUpperLeft
  611. %2 = OpTypeVoid
  612. %3 = OpTypeFunction %2
  613. %bool = OpTypeBool
  614. %true = OpConstantTrue %bool
  615. %main = OpFunction %2 None %3
  616. %8 = OpLabel
  617. OpBranch %9
  618. %9 = OpLabel
  619. OpLoopMerge %10 %11 None
  620. OpBranch %12
  621. %12 = OpLabel
  622. OpBranchConditional %true %13 %10
  623. %13 = OpLabel
  624. OpBranch %11
  625. %11 = OpLabel
  626. %14 = OpFunctionCall %void %kill_
  627. OpBranch %9
  628. %10 = OpLabel
  629. OpReturn
  630. OpFunctionEnd
  631. %kill_ = OpFunction %2 Pure|Const %3
  632. %4194300 = OpLabel
  633. OpKill
  634. OpFunctionEnd
  635. )";
  636. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  637. std::vector<Message> messages = {
  638. {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}};
  639. SetMessageConsumer(GetTestMessageConsumer(messages));
  640. auto result = SinglePassRunToBinary<WrapOpKill>(text, true);
  641. EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
  642. }
  643. TEST_F(WrapOpKillTest, IdBoundOverflow4) {
  644. const std::string text = R"(
  645. OpCapability DerivativeControl
  646. OpMemoryModel Logical GLSL450
  647. OpEntryPoint Fragment %main "main"
  648. OpExecutionMode %main OriginUpperLeft
  649. OpDecorate %2 Location 539091968
  650. %2 = OpTypeVoid
  651. %3 = OpTypeFunction %2
  652. %bool = OpTypeBool
  653. %true = OpConstantTrue %bool
  654. %main = OpFunction %2 None %3
  655. %8 = OpLabel
  656. OpBranch %9
  657. %9 = OpLabel
  658. OpLoopMerge %10 %11 None
  659. OpBranch %12
  660. %12 = OpLabel
  661. OpBranchConditional %true %13 %10
  662. %13 = OpLabel
  663. OpBranch %11
  664. %11 = OpLabel
  665. %14 = OpFunctionCall %void %kill_
  666. OpBranch %9
  667. %10 = OpLabel
  668. OpReturn
  669. OpFunctionEnd
  670. %kill_ = OpFunction %2 Inline|Pure|Const %3
  671. %4194302 = OpLabel
  672. OpKill
  673. OpFunctionEnd
  674. )";
  675. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  676. std::vector<Message> messages = {
  677. {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}};
  678. SetMessageConsumer(GetTestMessageConsumer(messages));
  679. auto result = SinglePassRunToBinary<WrapOpKill>(text, true);
  680. EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
  681. }
  682. TEST_F(WrapOpKillTest, IdBoundOverflow5) {
  683. const std::string text = R"(
  684. OpCapability Shader
  685. OpMemoryModel Logical GLSL450
  686. OpEntryPoint Fragment %1 "main"
  687. OpExecutionMode %1 OriginUpperLeft
  688. OpDecorate %void Location 539091968
  689. %void = OpTypeVoid
  690. %3 = OpTypeFunction %void
  691. %float = OpTypeFloat 32
  692. %_struct_5 = OpTypeStruct %float %float
  693. %_struct_6 = OpTypeStruct %_struct_5
  694. %_ptr_Function__struct_6 = OpTypePointer Function %_struct_6
  695. %_ptr_Output_float = OpTypePointer Output %float
  696. %9 = OpTypeFunction %_struct_5 %_ptr_Function__struct_6
  697. %bool = OpTypeBool
  698. %true = OpConstantTrue %bool
  699. %1 = OpFunction %void None %3
  700. %12 = OpLabel
  701. %13 = OpVariable %_ptr_Function__struct_6 Function
  702. OpBranch %14
  703. %14 = OpLabel
  704. OpLoopMerge %15 %16 None
  705. OpBranch %17
  706. %17 = OpLabel
  707. OpBranchConditional %true %18 %15
  708. %18 = OpLabel
  709. OpBranch %16
  710. %16 = OpLabel
  711. %19 = OpFunctionCall %void %20
  712. %21 = OpFunctionCall %_struct_5 %22 %13
  713. OpBranch %14
  714. %15 = OpLabel
  715. OpReturn
  716. OpFunctionEnd
  717. %20 = OpFunction %void Inline|Pure|Const %3
  718. %23 = OpLabel
  719. %24 = OpVariable %_ptr_Function__struct_6 Function
  720. %25 = OpFunctionCall %_struct_5 %26 %24
  721. OpKill
  722. OpFunctionEnd
  723. %26 = OpFunction %_struct_5 None %9
  724. %27 = OpLabel
  725. OpUnreachable
  726. OpFunctionEnd
  727. %22 = OpFunction %_struct_5 Inline %9
  728. %4194295 = OpLabel
  729. OpKill
  730. OpFunctionEnd
  731. )";
  732. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  733. std::vector<Message> messages = {
  734. {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}};
  735. SetMessageConsumer(GetTestMessageConsumer(messages));
  736. auto result = SinglePassRunToBinary<WrapOpKill>(text, true);
  737. EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
  738. }
  739. TEST_F(WrapOpKillTest, SkipEntryPoint) {
  740. const std::string text = R"(
  741. OpCapability GeometryStreams
  742. OpMemoryModel Logical GLSL450
  743. OpEntryPoint Fragment %4 "main"
  744. OpExecutionMode %4 OriginUpperLeft
  745. %2 = OpTypeVoid
  746. %3 = OpTypeFunction %2
  747. %4 = OpFunction %2 Pure|Const %3
  748. %5 = OpLabel
  749. OpKill
  750. OpFunctionEnd
  751. )";
  752. auto result = SinglePassRunToBinary<WrapOpKill>(text, true);
  753. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  754. }
  755. TEST_F(WrapOpKillTest, SkipFunctionNotInContinue) {
  756. const std::string text = R"(
  757. OpCapability GeometryStreams
  758. OpMemoryModel Logical GLSL450
  759. OpEntryPoint Fragment %main "main"
  760. OpExecutionMode %main OriginUpperLeft
  761. %2 = OpTypeVoid
  762. %3 = OpTypeFunction %2
  763. %bool = OpTypeBool
  764. %true = OpConstantTrue %bool
  765. %main = OpFunction %2 None %3
  766. %6 = OpLabel
  767. %7 = OpFunctionCall %void %4
  768. OpReturn
  769. OpFunctionEnd
  770. %4 = OpFunction %2 Pure|Const %3
  771. %5 = OpLabel
  772. OpKill
  773. OpFunctionEnd
  774. )";
  775. auto result = SinglePassRunToBinary<WrapOpKill>(text, true);
  776. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  777. }
  778. TEST_F(WrapOpKillTest, SetParentBlock) {
  779. const std::string text = R"(
  780. OpCapability Shader
  781. OpMemoryModel Logical GLSL450
  782. OpEntryPoint Fragment %main "main"
  783. OpExecutionMode %main OriginUpperLeft
  784. %void = OpTypeVoid
  785. %bool = OpTypeBool
  786. %undef = OpUndef %bool
  787. %void_fn = OpTypeFunction %void
  788. %main = OpFunction %void None %void_fn
  789. %entry = OpLabel
  790. OpBranch %loop
  791. %loop = OpLabel
  792. OpLoopMerge %merge %continue None
  793. OpBranchConditional %undef %merge %continue
  794. %continue = OpLabel
  795. %call = OpFunctionCall %void %kill_func
  796. OpBranch %loop
  797. %merge = OpLabel
  798. OpReturn
  799. OpFunctionEnd
  800. %kill_func = OpFunction %void None %void_fn
  801. %kill_entry = OpLabel
  802. OpKill
  803. OpFunctionEnd
  804. )";
  805. auto result = SinglePassRunToBinary<WrapOpKill>(text, true);
  806. EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
  807. result = SinglePassRunToBinary<WrapOpKill>(text, true);
  808. EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
  809. }
  810. TEST_F(WrapOpKillTest, KillInSingleBlockLoop) {
  811. const std::string text = R"(
  812. ; CHECK: OpFunction %void
  813. ; CHECK: OpFunction %void
  814. ; CHECK-NOT: OpKill
  815. ; CHECK: OpFunctionCall %void [[new_kill:%\w+]]
  816. ; CHECK-NOT: OpKill
  817. ; CHECK: [[new_kill]] = OpFunction
  818. ; CHECK-NEXT: OpLabel
  819. ; CHECK-NEXT: OpKill
  820. ; CHECK-NEXT: OpFunctionEnd
  821. OpCapability Shader
  822. OpCapability Linkage
  823. OpMemoryModel Logical GLSL450
  824. %void = OpTypeVoid
  825. %bool = OpTypeBool
  826. %undef = OpUndef %bool
  827. %void_fn = OpTypeFunction %void
  828. %main = OpFunction %void None %void_fn
  829. %main_entry = OpLabel
  830. OpBranch %loop
  831. %loop = OpLabel
  832. %call = OpFunctionCall %void %sub
  833. OpLoopMerge %exit %loop None
  834. OpBranchConditional %undef %loop %exit
  835. %exit = OpLabel
  836. OpReturn
  837. OpFunctionEnd
  838. %sub = OpFunction %void None %void_fn
  839. %sub_entry = OpLabel
  840. OpSelectionMerge %ret None
  841. OpBranchConditional %undef %kill %ret
  842. %kill = OpLabel
  843. OpKill
  844. %ret = OpLabel
  845. OpReturn
  846. OpFunctionEnd
  847. )";
  848. SinglePassRunAndMatch<WrapOpKill>(text, true);
  849. }
  850. TEST_F(WrapOpKillTest, DebugInfoSimple) {
  851. const std::string text = R"(
  852. ; CHECK: OpEntryPoint Fragment [[main:%\w+]]
  853. ; CHECK: [[main]] = OpFunction
  854. ; CHECK: OpFunctionCall %void [[orig_kill:%\w+]]
  855. ; CHECK: [[orig_kill]] = OpFunction
  856. ; CHECK-NEXT: OpLabel
  857. ; CHECK-NEXT: {{%\d+}} = OpExtInst %void [[ext:%\d+]] DebugScope
  858. ; CHECK-NEXT: OpLine [[file:%\d+]] 100 200
  859. ; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
  860. ; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugNoScope
  861. ; CHECK-NEXT: OpReturn
  862. ; CHECK: [[new_kill]] = OpFunction
  863. ; CHECK-NEXT: OpLabel
  864. ; CHECK-NEXT: OpKill
  865. ; CHECK-NEXT: OpFunctionEnd
  866. OpCapability Shader
  867. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  868. OpMemoryModel Logical GLSL450
  869. OpEntryPoint Fragment %main "main"
  870. OpExecutionMode %main OriginUpperLeft
  871. %2 = OpString "File name"
  872. OpSource GLSL 330
  873. OpName %main "main"
  874. %void = OpTypeVoid
  875. %5 = OpTypeFunction %void
  876. %bool = OpTypeBool
  877. %true = OpConstantTrue %bool
  878. %3 = OpExtInst %void %1 DebugSource %2
  879. %4 = OpExtInst %void %1 DebugCompilationUnit 0 0 %3 GLSL
  880. %main = OpFunction %void None %5
  881. %8 = OpLabel
  882. OpBranch %9
  883. %9 = OpLabel
  884. OpLoopMerge %10 %11 None
  885. OpBranch %12
  886. %12 = OpLabel
  887. OpBranchConditional %true %13 %10
  888. %13 = OpLabel
  889. OpBranch %11
  890. %11 = OpLabel
  891. %14 = OpFunctionCall %void %kill_
  892. OpBranch %9
  893. %10 = OpLabel
  894. OpReturn
  895. OpFunctionEnd
  896. %kill_ = OpFunction %void None %5
  897. %15 = OpLabel
  898. %16 = OpExtInst %void %1 DebugScope %4
  899. OpLine %2 100 200
  900. OpKill
  901. OpFunctionEnd
  902. )";
  903. SinglePassRunAndMatch<WrapOpKill>(text, true);
  904. }
  905. } // namespace
  906. } // namespace opt
  907. } // namespace spvtools