fusion_pass.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. // Copyright (c) 2018 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 <string>
  15. #include "effcee/effcee.h"
  16. #include "gmock/gmock.h"
  17. #include "test/opt/pass_fixture.h"
  18. namespace spvtools {
  19. namespace opt {
  20. namespace {
  21. using FusionPassTest = PassTest<::testing::Test>;
  22. /*
  23. Generated from the following GLSL + --eliminate-local-multi-store
  24. #version 440 core
  25. void main() {
  26. int[10] a;
  27. int[10] b;
  28. for (int i = 0; i < 10; i++) {
  29. a[i] = a[i]*2;
  30. }
  31. for (int i = 0; i < 10; i++) {
  32. b[i] = a[i]+2;
  33. }
  34. }
  35. */
  36. TEST_F(FusionPassTest, SimpleFusion) {
  37. const std::string text = R"(
  38. ; CHECK: OpPhi
  39. ; CHECK: OpLoad
  40. ; CHECK: OpStore
  41. ; CHECK-NOT: OpPhi
  42. ; CHECK: OpLoad
  43. ; CHECK: OpStore
  44. OpCapability Shader
  45. %1 = OpExtInstImport "GLSL.std.450"
  46. OpMemoryModel Logical GLSL450
  47. OpEntryPoint Fragment %4 "main"
  48. OpExecutionMode %4 OriginUpperLeft
  49. OpSource GLSL 440
  50. OpName %4 "main"
  51. OpName %8 "i"
  52. OpName %23 "a"
  53. OpName %34 "i"
  54. OpName %42 "b"
  55. %2 = OpTypeVoid
  56. %3 = OpTypeFunction %2
  57. %6 = OpTypeInt 32 1
  58. %7 = OpTypePointer Function %6
  59. %9 = OpConstant %6 0
  60. %16 = OpConstant %6 10
  61. %17 = OpTypeBool
  62. %19 = OpTypeInt 32 0
  63. %20 = OpConstant %19 10
  64. %21 = OpTypeArray %6 %20
  65. %22 = OpTypePointer Function %21
  66. %28 = OpConstant %6 2
  67. %32 = OpConstant %6 1
  68. %4 = OpFunction %2 None %3
  69. %5 = OpLabel
  70. %8 = OpVariable %7 Function
  71. %23 = OpVariable %22 Function
  72. %34 = OpVariable %7 Function
  73. %42 = OpVariable %22 Function
  74. OpStore %8 %9
  75. OpBranch %10
  76. %10 = OpLabel
  77. %51 = OpPhi %6 %9 %5 %33 %13
  78. OpLoopMerge %12 %13 None
  79. OpBranch %14
  80. %14 = OpLabel
  81. %18 = OpSLessThan %17 %51 %16
  82. OpBranchConditional %18 %11 %12
  83. %11 = OpLabel
  84. %26 = OpAccessChain %7 %23 %51
  85. %27 = OpLoad %6 %26
  86. %29 = OpIMul %6 %27 %28
  87. %30 = OpAccessChain %7 %23 %51
  88. OpStore %30 %29
  89. OpBranch %13
  90. %13 = OpLabel
  91. %33 = OpIAdd %6 %51 %32
  92. OpStore %8 %33
  93. OpBranch %10
  94. %12 = OpLabel
  95. OpStore %34 %9
  96. OpBranch %35
  97. %35 = OpLabel
  98. %52 = OpPhi %6 %9 %12 %50 %38
  99. OpLoopMerge %37 %38 None
  100. OpBranch %39
  101. %39 = OpLabel
  102. %41 = OpSLessThan %17 %52 %16
  103. OpBranchConditional %41 %36 %37
  104. %36 = OpLabel
  105. %45 = OpAccessChain %7 %23 %52
  106. %46 = OpLoad %6 %45
  107. %47 = OpIAdd %6 %46 %28
  108. %48 = OpAccessChain %7 %42 %52
  109. OpStore %48 %47
  110. OpBranch %38
  111. %38 = OpLabel
  112. %50 = OpIAdd %6 %52 %32
  113. OpStore %34 %50
  114. OpBranch %35
  115. %37 = OpLabel
  116. OpReturn
  117. OpFunctionEnd
  118. )";
  119. SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
  120. }
  121. /*
  122. Generated from the following GLSL + --eliminate-local-multi-store
  123. #version 440 core
  124. void main() {
  125. int[10] a;
  126. int[10] b;
  127. int[10] c;
  128. for (int i = 0; i < 10; i++) {
  129. a[i] = b[i] + 1;
  130. }
  131. for (int i = 0; i < 10; i++) {
  132. c[i] = a[i] + 2;
  133. }
  134. for (int i = 0; i < 10; i++) {
  135. b[i] = c[i] + 10;
  136. }
  137. }
  138. */
  139. TEST_F(FusionPassTest, ThreeLoopsFused) {
  140. const std::string text = R"(
  141. ; CHECK: OpPhi
  142. ; CHECK: OpLoad
  143. ; CHECK: OpStore
  144. ; CHECK-NOT: OpPhi
  145. ; CHECK: OpLoad
  146. ; CHECK: OpStore
  147. ; CHECK-NOT: OpPhi
  148. ; CHECK: OpLoad
  149. ; CHECK: OpStore
  150. OpCapability Shader
  151. %1 = OpExtInstImport "GLSL.std.450"
  152. OpMemoryModel Logical GLSL450
  153. OpEntryPoint Fragment %4 "main"
  154. OpExecutionMode %4 OriginUpperLeft
  155. OpSource GLSL 440
  156. OpName %4 "main"
  157. OpName %8 "i"
  158. OpName %23 "a"
  159. OpName %25 "b"
  160. OpName %34 "i"
  161. OpName %42 "c"
  162. OpName %52 "i"
  163. %2 = OpTypeVoid
  164. %3 = OpTypeFunction %2
  165. %6 = OpTypeInt 32 1
  166. %7 = OpTypePointer Function %6
  167. %9 = OpConstant %6 0
  168. %16 = OpConstant %6 10
  169. %17 = OpTypeBool
  170. %19 = OpTypeInt 32 0
  171. %20 = OpConstant %19 10
  172. %21 = OpTypeArray %6 %20
  173. %22 = OpTypePointer Function %21
  174. %29 = OpConstant %6 1
  175. %47 = OpConstant %6 2
  176. %4 = OpFunction %2 None %3
  177. %5 = OpLabel
  178. %8 = OpVariable %7 Function
  179. %23 = OpVariable %22 Function
  180. %25 = OpVariable %22 Function
  181. %34 = OpVariable %7 Function
  182. %42 = OpVariable %22 Function
  183. %52 = OpVariable %7 Function
  184. OpStore %8 %9
  185. OpBranch %10
  186. %10 = OpLabel
  187. %68 = OpPhi %6 %9 %5 %33 %13
  188. OpLoopMerge %12 %13 None
  189. OpBranch %14
  190. %14 = OpLabel
  191. %18 = OpSLessThan %17 %68 %16
  192. OpBranchConditional %18 %11 %12
  193. %11 = OpLabel
  194. %27 = OpAccessChain %7 %25 %68
  195. %28 = OpLoad %6 %27
  196. %30 = OpIAdd %6 %28 %29
  197. %31 = OpAccessChain %7 %23 %68
  198. OpStore %31 %30
  199. OpBranch %13
  200. %13 = OpLabel
  201. %33 = OpIAdd %6 %68 %29
  202. OpStore %8 %33
  203. OpBranch %10
  204. %12 = OpLabel
  205. OpStore %34 %9
  206. OpBranch %35
  207. %35 = OpLabel
  208. %69 = OpPhi %6 %9 %12 %51 %38
  209. OpLoopMerge %37 %38 None
  210. OpBranch %39
  211. %39 = OpLabel
  212. %41 = OpSLessThan %17 %69 %16
  213. OpBranchConditional %41 %36 %37
  214. %36 = OpLabel
  215. %45 = OpAccessChain %7 %23 %69
  216. %46 = OpLoad %6 %45
  217. %48 = OpIAdd %6 %46 %47
  218. %49 = OpAccessChain %7 %42 %69
  219. OpStore %49 %48
  220. OpBranch %38
  221. %38 = OpLabel
  222. %51 = OpIAdd %6 %69 %29
  223. OpStore %34 %51
  224. OpBranch %35
  225. %37 = OpLabel
  226. OpStore %52 %9
  227. OpBranch %53
  228. %53 = OpLabel
  229. %70 = OpPhi %6 %9 %37 %67 %56
  230. OpLoopMerge %55 %56 None
  231. OpBranch %57
  232. %57 = OpLabel
  233. %59 = OpSLessThan %17 %70 %16
  234. OpBranchConditional %59 %54 %55
  235. %54 = OpLabel
  236. %62 = OpAccessChain %7 %42 %70
  237. %63 = OpLoad %6 %62
  238. %64 = OpIAdd %6 %63 %16
  239. %65 = OpAccessChain %7 %25 %70
  240. OpStore %65 %64
  241. OpBranch %56
  242. %56 = OpLabel
  243. %67 = OpIAdd %6 %70 %29
  244. OpStore %52 %67
  245. OpBranch %53
  246. %55 = OpLabel
  247. OpReturn
  248. OpFunctionEnd
  249. )";
  250. SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
  251. }
  252. /*
  253. Generated from the following GLSL + --eliminate-local-multi-store
  254. #version 440 core
  255. void main() {
  256. int[10][10] a;
  257. int[10][10] b;
  258. int[10][10] c;
  259. // Legal both
  260. for (int i = 0; i < 10; i++) {
  261. for (int j = 0; j < 10; j++) {
  262. c[i][j] = a[i][j] + 2;
  263. }
  264. }
  265. for (int i = 0; i < 10; i++) {
  266. for (int j = 0; j < 10; j++) {
  267. b[i][j] = c[i][j] + 10;
  268. }
  269. }
  270. }
  271. */
  272. TEST_F(FusionPassTest, NestedLoopsFused) {
  273. const std::string text = R"(
  274. ; CHECK: OpPhi
  275. ; CHECK: OpPhi
  276. ; CHECK: OpLoad
  277. ; CHECK: OpStore
  278. ; CHECK-NOT: OpPhi
  279. ; CHECK: OpLoad
  280. ; CHECK: OpStore
  281. OpCapability Shader
  282. %1 = OpExtInstImport "GLSL.std.450"
  283. OpMemoryModel Logical GLSL450
  284. OpEntryPoint Fragment %4 "main"
  285. OpExecutionMode %4 OriginUpperLeft
  286. OpSource GLSL 440
  287. OpName %4 "main"
  288. OpName %8 "i"
  289. OpName %19 "j"
  290. OpName %32 "c"
  291. OpName %35 "a"
  292. OpName %48 "i"
  293. OpName %56 "j"
  294. OpName %64 "b"
  295. %2 = OpTypeVoid
  296. %3 = OpTypeFunction %2
  297. %6 = OpTypeInt 32 1
  298. %7 = OpTypePointer Function %6
  299. %9 = OpConstant %6 0
  300. %16 = OpConstant %6 10
  301. %17 = OpTypeBool
  302. %27 = OpTypeInt 32 0
  303. %28 = OpConstant %27 10
  304. %29 = OpTypeArray %6 %28
  305. %30 = OpTypeArray %29 %28
  306. %31 = OpTypePointer Function %30
  307. %40 = OpConstant %6 2
  308. %44 = OpConstant %6 1
  309. %4 = OpFunction %2 None %3
  310. %5 = OpLabel
  311. %8 = OpVariable %7 Function
  312. %19 = OpVariable %7 Function
  313. %32 = OpVariable %31 Function
  314. %35 = OpVariable %31 Function
  315. %48 = OpVariable %7 Function
  316. %56 = OpVariable %7 Function
  317. %64 = OpVariable %31 Function
  318. OpStore %8 %9
  319. OpBranch %10
  320. %10 = OpLabel
  321. %77 = OpPhi %6 %9 %5 %47 %13
  322. OpLoopMerge %12 %13 None
  323. OpBranch %14
  324. %14 = OpLabel
  325. %18 = OpSLessThan %17 %77 %16
  326. OpBranchConditional %18 %11 %12
  327. %11 = OpLabel
  328. OpStore %19 %9
  329. OpBranch %20
  330. %20 = OpLabel
  331. %81 = OpPhi %6 %9 %11 %45 %23
  332. OpLoopMerge %22 %23 None
  333. OpBranch %24
  334. %24 = OpLabel
  335. %26 = OpSLessThan %17 %81 %16
  336. OpBranchConditional %26 %21 %22
  337. %21 = OpLabel
  338. %38 = OpAccessChain %7 %35 %77 %81
  339. %39 = OpLoad %6 %38
  340. %41 = OpIAdd %6 %39 %40
  341. %42 = OpAccessChain %7 %32 %77 %81
  342. OpStore %42 %41
  343. OpBranch %23
  344. %23 = OpLabel
  345. %45 = OpIAdd %6 %81 %44
  346. OpStore %19 %45
  347. OpBranch %20
  348. %22 = OpLabel
  349. OpBranch %13
  350. %13 = OpLabel
  351. %47 = OpIAdd %6 %77 %44
  352. OpStore %8 %47
  353. OpBranch %10
  354. %12 = OpLabel
  355. OpStore %48 %9
  356. OpBranch %49
  357. %49 = OpLabel
  358. %78 = OpPhi %6 %9 %12 %76 %52
  359. OpLoopMerge %51 %52 None
  360. OpBranch %53
  361. %53 = OpLabel
  362. %55 = OpSLessThan %17 %78 %16
  363. OpBranchConditional %55 %50 %51
  364. %50 = OpLabel
  365. OpStore %56 %9
  366. OpBranch %57
  367. %57 = OpLabel
  368. %79 = OpPhi %6 %9 %50 %74 %60
  369. OpLoopMerge %59 %60 None
  370. OpBranch %61
  371. %61 = OpLabel
  372. %63 = OpSLessThan %17 %79 %16
  373. OpBranchConditional %63 %58 %59
  374. %58 = OpLabel
  375. %69 = OpAccessChain %7 %32 %78 %79
  376. %70 = OpLoad %6 %69
  377. %71 = OpIAdd %6 %70 %16
  378. %72 = OpAccessChain %7 %64 %78 %79
  379. OpStore %72 %71
  380. OpBranch %60
  381. %60 = OpLabel
  382. %74 = OpIAdd %6 %79 %44
  383. OpStore %56 %74
  384. OpBranch %57
  385. %59 = OpLabel
  386. OpBranch %52
  387. %52 = OpLabel
  388. %76 = OpIAdd %6 %78 %44
  389. OpStore %48 %76
  390. OpBranch %49
  391. %51 = OpLabel
  392. OpReturn
  393. OpFunctionEnd
  394. )";
  395. SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
  396. }
  397. /*
  398. Generated from the following GLSL + --eliminate-local-multi-store
  399. #version 440 core
  400. void main() {
  401. // Can't fuse, different step
  402. for (int i = 0; i < 10; i++) {}
  403. for (int j = 0; j < 10; j=j+2) {}
  404. }
  405. */
  406. TEST_F(FusionPassTest, Incompatible) {
  407. const std::string text = R"(
  408. ; CHECK: OpPhi
  409. ; CHECK-NEXT: OpLoopMerge
  410. ; CHECK: OpPhi
  411. ; CHECK-NEXT: OpLoopMerge
  412. OpCapability Shader
  413. %1 = OpExtInstImport "GLSL.std.450"
  414. OpMemoryModel Logical GLSL450
  415. OpEntryPoint Fragment %4 "main"
  416. OpExecutionMode %4 OriginUpperLeft
  417. OpSource GLSL 440
  418. OpName %4 "main"
  419. OpName %8 "i"
  420. OpName %22 "j"
  421. %2 = OpTypeVoid
  422. %3 = OpTypeFunction %2
  423. %6 = OpTypeInt 32 1
  424. %7 = OpTypePointer Function %6
  425. %9 = OpConstant %6 0
  426. %16 = OpConstant %6 10
  427. %17 = OpTypeBool
  428. %20 = OpConstant %6 1
  429. %31 = OpConstant %6 2
  430. %4 = OpFunction %2 None %3
  431. %5 = OpLabel
  432. %8 = OpVariable %7 Function
  433. %22 = OpVariable %7 Function
  434. OpStore %8 %9
  435. OpBranch %10
  436. %10 = OpLabel
  437. %33 = OpPhi %6 %9 %5 %21 %13
  438. OpLoopMerge %12 %13 None
  439. OpBranch %14
  440. %14 = OpLabel
  441. %18 = OpSLessThan %17 %33 %16
  442. OpBranchConditional %18 %11 %12
  443. %11 = OpLabel
  444. OpBranch %13
  445. %13 = OpLabel
  446. %21 = OpIAdd %6 %33 %20
  447. OpStore %8 %21
  448. OpBranch %10
  449. %12 = OpLabel
  450. OpStore %22 %9
  451. OpBranch %23
  452. %23 = OpLabel
  453. %34 = OpPhi %6 %9 %12 %32 %26
  454. OpLoopMerge %25 %26 None
  455. OpBranch %27
  456. %27 = OpLabel
  457. %29 = OpSLessThan %17 %34 %16
  458. OpBranchConditional %29 %24 %25
  459. %24 = OpLabel
  460. OpBranch %26
  461. %26 = OpLabel
  462. %32 = OpIAdd %6 %34 %31
  463. OpStore %22 %32
  464. OpBranch %23
  465. %25 = OpLabel
  466. OpReturn
  467. OpFunctionEnd
  468. )";
  469. SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
  470. }
  471. /*
  472. Generated from the following GLSL + --eliminate-local-multi-store
  473. #version 440 core
  474. void main() {
  475. int[10] a;
  476. int[10] b;
  477. int[10] c;
  478. // Illegal, loop-independent dependence will become a
  479. // backward loop-carried antidependence
  480. for (int i = 0; i < 10; i++) {
  481. a[i] = b[i] + 1;
  482. }
  483. for (int i = 0; i < 10; i++) {
  484. c[i] = a[i+1] + 2;
  485. }
  486. }
  487. */
  488. TEST_F(FusionPassTest, Illegal) {
  489. std::string text = R"(
  490. ; CHECK: OpPhi
  491. ; CHECK-NEXT: OpLoopMerge
  492. ; CHECK: OpLoad
  493. ; CHECK: OpStore
  494. ; CHECK: OpPhi
  495. ; CHECK-NEXT: OpLoopMerge
  496. ; CHECK: OpLoad
  497. ; CHECK: OpStore
  498. OpCapability Shader
  499. %1 = OpExtInstImport "GLSL.std.450"
  500. OpMemoryModel Logical GLSL450
  501. OpEntryPoint Fragment %4 "main"
  502. OpExecutionMode %4 OriginUpperLeft
  503. OpSource GLSL 440
  504. OpName %4 "main"
  505. OpName %8 "i"
  506. OpName %23 "a"
  507. OpName %25 "b"
  508. OpName %34 "i"
  509. OpName %42 "c"
  510. %2 = OpTypeVoid
  511. %3 = OpTypeFunction %2
  512. %6 = OpTypeInt 32 1
  513. %7 = OpTypePointer Function %6
  514. %9 = OpConstant %6 0
  515. %16 = OpConstant %6 10
  516. %17 = OpTypeBool
  517. %19 = OpTypeInt 32 0
  518. %20 = OpConstant %19 10
  519. %21 = OpTypeArray %6 %20
  520. %22 = OpTypePointer Function %21
  521. %29 = OpConstant %6 1
  522. %48 = OpConstant %6 2
  523. %4 = OpFunction %2 None %3
  524. %5 = OpLabel
  525. %8 = OpVariable %7 Function
  526. %23 = OpVariable %22 Function
  527. %25 = OpVariable %22 Function
  528. %34 = OpVariable %7 Function
  529. %42 = OpVariable %22 Function
  530. OpStore %8 %9
  531. OpBranch %10
  532. %10 = OpLabel
  533. %53 = OpPhi %6 %9 %5 %33 %13
  534. OpLoopMerge %12 %13 None
  535. OpBranch %14
  536. %14 = OpLabel
  537. %18 = OpSLessThan %17 %53 %16
  538. OpBranchConditional %18 %11 %12
  539. %11 = OpLabel
  540. %27 = OpAccessChain %7 %25 %53
  541. %28 = OpLoad %6 %27
  542. %30 = OpIAdd %6 %28 %29
  543. %31 = OpAccessChain %7 %23 %53
  544. OpStore %31 %30
  545. OpBranch %13
  546. %13 = OpLabel
  547. %33 = OpIAdd %6 %53 %29
  548. OpStore %8 %33
  549. OpBranch %10
  550. %12 = OpLabel
  551. OpStore %34 %9
  552. OpBranch %35
  553. %35 = OpLabel
  554. %54 = OpPhi %6 %9 %12 %52 %38
  555. OpLoopMerge %37 %38 None
  556. OpBranch %39
  557. %39 = OpLabel
  558. %41 = OpSLessThan %17 %54 %16
  559. OpBranchConditional %41 %36 %37
  560. %36 = OpLabel
  561. %45 = OpIAdd %6 %54 %29
  562. %46 = OpAccessChain %7 %23 %45
  563. %47 = OpLoad %6 %46
  564. %49 = OpIAdd %6 %47 %48
  565. %50 = OpAccessChain %7 %42 %54
  566. OpStore %50 %49
  567. OpBranch %38
  568. %38 = OpLabel
  569. %52 = OpIAdd %6 %54 %29
  570. OpStore %34 %52
  571. OpBranch %35
  572. %37 = OpLabel
  573. OpReturn
  574. OpFunctionEnd
  575. )";
  576. SinglePassRunAndMatch<LoopFusionPass>(text, true, 20);
  577. }
  578. /*
  579. Generated from the following GLSL + --eliminate-local-multi-store
  580. #version 440 core
  581. void main() {
  582. int[10] a;
  583. int[10] b;
  584. for (int i = 0; i < 10; i++) {
  585. a[i] = a[i]*2;
  586. }
  587. for (int i = 0; i < 10; i++) {
  588. b[i] = a[i]+2;
  589. }
  590. }
  591. */
  592. TEST_F(FusionPassTest, TooManyRegisters) {
  593. const std::string text = R"(
  594. ; CHECK: OpPhi
  595. ; CHECK-NEXT: OpLoopMerge
  596. ; CHECK: OpLoad
  597. ; CHECK: OpStore
  598. ; CHECK: OpPhi
  599. ; CHECK-NEXT: OpLoopMerge
  600. ; CHECK: OpLoad
  601. ; CHECK: OpStore
  602. OpCapability Shader
  603. %1 = OpExtInstImport "GLSL.std.450"
  604. OpMemoryModel Logical GLSL450
  605. OpEntryPoint Fragment %4 "main"
  606. OpExecutionMode %4 OriginUpperLeft
  607. OpSource GLSL 440
  608. OpName %4 "main"
  609. OpName %8 "i"
  610. OpName %23 "a"
  611. OpName %34 "i"
  612. OpName %42 "b"
  613. %2 = OpTypeVoid
  614. %3 = OpTypeFunction %2
  615. %6 = OpTypeInt 32 1
  616. %7 = OpTypePointer Function %6
  617. %9 = OpConstant %6 0
  618. %16 = OpConstant %6 10
  619. %17 = OpTypeBool
  620. %19 = OpTypeInt 32 0
  621. %20 = OpConstant %19 10
  622. %21 = OpTypeArray %6 %20
  623. %22 = OpTypePointer Function %21
  624. %28 = OpConstant %6 2
  625. %32 = OpConstant %6 1
  626. %4 = OpFunction %2 None %3
  627. %5 = OpLabel
  628. %8 = OpVariable %7 Function
  629. %23 = OpVariable %22 Function
  630. %34 = OpVariable %7 Function
  631. %42 = OpVariable %22 Function
  632. OpStore %8 %9
  633. OpBranch %10
  634. %10 = OpLabel
  635. %51 = OpPhi %6 %9 %5 %33 %13
  636. OpLoopMerge %12 %13 None
  637. OpBranch %14
  638. %14 = OpLabel
  639. %18 = OpSLessThan %17 %51 %16
  640. OpBranchConditional %18 %11 %12
  641. %11 = OpLabel
  642. %26 = OpAccessChain %7 %23 %51
  643. %27 = OpLoad %6 %26
  644. %29 = OpIMul %6 %27 %28
  645. %30 = OpAccessChain %7 %23 %51
  646. OpStore %30 %29
  647. OpBranch %13
  648. %13 = OpLabel
  649. %33 = OpIAdd %6 %51 %32
  650. OpStore %8 %33
  651. OpBranch %10
  652. %12 = OpLabel
  653. OpStore %34 %9
  654. OpBranch %35
  655. %35 = OpLabel
  656. %52 = OpPhi %6 %9 %12 %50 %38
  657. OpLoopMerge %37 %38 None
  658. OpBranch %39
  659. %39 = OpLabel
  660. %41 = OpSLessThan %17 %52 %16
  661. OpBranchConditional %41 %36 %37
  662. %36 = OpLabel
  663. %45 = OpAccessChain %7 %23 %52
  664. %46 = OpLoad %6 %45
  665. %47 = OpIAdd %6 %46 %28
  666. %48 = OpAccessChain %7 %42 %52
  667. OpStore %48 %47
  668. OpBranch %38
  669. %38 = OpLabel
  670. %50 = OpIAdd %6 %52 %32
  671. OpStore %34 %50
  672. OpBranch %35
  673. %37 = OpLabel
  674. OpReturn
  675. OpFunctionEnd
  676. )";
  677. SinglePassRunAndMatch<LoopFusionPass>(text, true, 5);
  678. }
  679. } // namespace
  680. } // namespace opt
  681. } // namespace spvtools