wrap_opkill_test.cpp 28 KB

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