nested_loops.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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 <memory>
  15. #include <string>
  16. #include <vector>
  17. #include "gmock/gmock.h"
  18. #include "source/opt/dominator_analysis.h"
  19. #include "source/opt/pass.h"
  20. #include "test/opt/assembly_builder.h"
  21. #include "test/opt/function_utils.h"
  22. #include "test/opt/pass_fixture.h"
  23. #include "test/opt/pass_utils.h"
  24. namespace spvtools {
  25. namespace opt {
  26. namespace {
  27. using ::testing::UnorderedElementsAre;
  28. using PassClassTest = PassTest<::testing::Test>;
  29. /*
  30. Generated from the following GLSL
  31. #version 440 core
  32. layout(location = 0) out vec4 v;
  33. layout(location = 1) in vec4 in_val;
  34. void main() {
  35. for (int i = 0; i < in_val.x; ++i) {
  36. for (int j = 0; j < in_val.y; j++) {
  37. }
  38. }
  39. for (int i = 0; i < in_val.x; ++i) {
  40. for (int j = 0; j < in_val.y; j++) {
  41. }
  42. if (in_val.z == in_val.w) {
  43. break;
  44. }
  45. }
  46. int i = 0;
  47. while (i < in_val.x) {
  48. ++i;
  49. for (int j = 0; j < 1; j++) {
  50. for (int k = 0; k < 1; k++) {
  51. }
  52. }
  53. }
  54. i = 0;
  55. while (i < in_val.x) {
  56. ++i;
  57. if (in_val.z == in_val.w) {
  58. continue;
  59. }
  60. for (int j = 0; j < 1; j++) {
  61. for (int k = 0; k < 1; k++) {
  62. }
  63. if (in_val.z == in_val.w) {
  64. break;
  65. }
  66. }
  67. }
  68. v = vec4(1,1,1,1);
  69. }
  70. */
  71. TEST_F(PassClassTest, BasicVisitFromEntryPoint) {
  72. const std::string text = R"(
  73. OpCapability Shader
  74. %1 = OpExtInstImport "GLSL.std.450"
  75. OpMemoryModel Logical GLSL450
  76. OpEntryPoint Fragment %4 "main" %20 %163
  77. OpExecutionMode %4 OriginUpperLeft
  78. OpSource GLSL 440
  79. OpName %4 "main"
  80. OpName %8 "i"
  81. OpName %20 "in_val"
  82. OpName %28 "j"
  83. OpName %45 "i"
  84. OpName %56 "j"
  85. OpName %81 "i"
  86. OpName %94 "j"
  87. OpName %102 "k"
  88. OpName %134 "j"
  89. OpName %142 "k"
  90. OpName %163 "v"
  91. OpDecorate %20 Location 1
  92. OpDecorate %163 Location 0
  93. %2 = OpTypeVoid
  94. %3 = OpTypeFunction %2
  95. %6 = OpTypeInt 32 1
  96. %7 = OpTypePointer Function %6
  97. %9 = OpConstant %6 0
  98. %16 = OpTypeFloat 32
  99. %18 = OpTypeVector %16 4
  100. %19 = OpTypePointer Input %18
  101. %20 = OpVariable %19 Input
  102. %21 = OpTypeInt 32 0
  103. %22 = OpConstant %21 0
  104. %23 = OpTypePointer Input %16
  105. %26 = OpTypeBool
  106. %36 = OpConstant %21 1
  107. %41 = OpConstant %6 1
  108. %69 = OpConstant %21 2
  109. %72 = OpConstant %21 3
  110. %162 = OpTypePointer Output %18
  111. %163 = OpVariable %162 Output
  112. %164 = OpConstant %16 1
  113. %165 = OpConstantComposite %18 %164 %164 %164 %164
  114. %4 = OpFunction %2 None %3
  115. %5 = OpLabel
  116. %8 = OpVariable %7 Function
  117. %28 = OpVariable %7 Function
  118. %45 = OpVariable %7 Function
  119. %56 = OpVariable %7 Function
  120. %81 = OpVariable %7 Function
  121. %94 = OpVariable %7 Function
  122. %102 = OpVariable %7 Function
  123. %134 = OpVariable %7 Function
  124. %142 = OpVariable %7 Function
  125. OpStore %8 %9
  126. OpBranch %10
  127. %10 = OpLabel
  128. OpLoopMerge %12 %13 None
  129. OpBranch %14
  130. %14 = OpLabel
  131. %15 = OpLoad %6 %8
  132. %17 = OpConvertSToF %16 %15
  133. %24 = OpAccessChain %23 %20 %22
  134. %25 = OpLoad %16 %24
  135. %27 = OpFOrdLessThan %26 %17 %25
  136. OpBranchConditional %27 %11 %12
  137. %11 = OpLabel
  138. OpStore %28 %9
  139. OpBranch %29
  140. %29 = OpLabel
  141. OpLoopMerge %31 %32 None
  142. OpBranch %33
  143. %33 = OpLabel
  144. %34 = OpLoad %6 %28
  145. %35 = OpConvertSToF %16 %34
  146. %37 = OpAccessChain %23 %20 %36
  147. %38 = OpLoad %16 %37
  148. %39 = OpFOrdLessThan %26 %35 %38
  149. OpBranchConditional %39 %30 %31
  150. %30 = OpLabel
  151. OpBranch %32
  152. %32 = OpLabel
  153. %40 = OpLoad %6 %28
  154. %42 = OpIAdd %6 %40 %41
  155. OpStore %28 %42
  156. OpBranch %29
  157. %31 = OpLabel
  158. OpBranch %13
  159. %13 = OpLabel
  160. %43 = OpLoad %6 %8
  161. %44 = OpIAdd %6 %43 %41
  162. OpStore %8 %44
  163. OpBranch %10
  164. %12 = OpLabel
  165. OpStore %45 %9
  166. OpBranch %46
  167. %46 = OpLabel
  168. OpLoopMerge %48 %49 None
  169. OpBranch %50
  170. %50 = OpLabel
  171. %51 = OpLoad %6 %45
  172. %52 = OpConvertSToF %16 %51
  173. %53 = OpAccessChain %23 %20 %22
  174. %54 = OpLoad %16 %53
  175. %55 = OpFOrdLessThan %26 %52 %54
  176. OpBranchConditional %55 %47 %48
  177. %47 = OpLabel
  178. OpStore %56 %9
  179. OpBranch %57
  180. %57 = OpLabel
  181. OpLoopMerge %59 %60 None
  182. OpBranch %61
  183. %61 = OpLabel
  184. %62 = OpLoad %6 %56
  185. %63 = OpConvertSToF %16 %62
  186. %64 = OpAccessChain %23 %20 %36
  187. %65 = OpLoad %16 %64
  188. %66 = OpFOrdLessThan %26 %63 %65
  189. OpBranchConditional %66 %58 %59
  190. %58 = OpLabel
  191. OpBranch %60
  192. %60 = OpLabel
  193. %67 = OpLoad %6 %56
  194. %68 = OpIAdd %6 %67 %41
  195. OpStore %56 %68
  196. OpBranch %57
  197. %59 = OpLabel
  198. %70 = OpAccessChain %23 %20 %69
  199. %71 = OpLoad %16 %70
  200. %73 = OpAccessChain %23 %20 %72
  201. %74 = OpLoad %16 %73
  202. %75 = OpFOrdEqual %26 %71 %74
  203. OpSelectionMerge %77 None
  204. OpBranchConditional %75 %76 %77
  205. %76 = OpLabel
  206. OpBranch %48
  207. %77 = OpLabel
  208. OpBranch %49
  209. %49 = OpLabel
  210. %79 = OpLoad %6 %45
  211. %80 = OpIAdd %6 %79 %41
  212. OpStore %45 %80
  213. OpBranch %46
  214. %48 = OpLabel
  215. OpStore %81 %9
  216. OpBranch %82
  217. %82 = OpLabel
  218. OpLoopMerge %84 %85 None
  219. OpBranch %86
  220. %86 = OpLabel
  221. %87 = OpLoad %6 %81
  222. %88 = OpConvertSToF %16 %87
  223. %89 = OpAccessChain %23 %20 %22
  224. %90 = OpLoad %16 %89
  225. %91 = OpFOrdLessThan %26 %88 %90
  226. OpBranchConditional %91 %83 %84
  227. %83 = OpLabel
  228. %92 = OpLoad %6 %81
  229. %93 = OpIAdd %6 %92 %41
  230. OpStore %81 %93
  231. OpStore %94 %9
  232. OpBranch %95
  233. %95 = OpLabel
  234. OpLoopMerge %97 %98 None
  235. OpBranch %99
  236. %99 = OpLabel
  237. %100 = OpLoad %6 %94
  238. %101 = OpSLessThan %26 %100 %41
  239. OpBranchConditional %101 %96 %97
  240. %96 = OpLabel
  241. OpStore %102 %9
  242. OpBranch %103
  243. %103 = OpLabel
  244. OpLoopMerge %105 %106 None
  245. OpBranch %107
  246. %107 = OpLabel
  247. %108 = OpLoad %6 %102
  248. %109 = OpSLessThan %26 %108 %41
  249. OpBranchConditional %109 %104 %105
  250. %104 = OpLabel
  251. OpBranch %106
  252. %106 = OpLabel
  253. %110 = OpLoad %6 %102
  254. %111 = OpIAdd %6 %110 %41
  255. OpStore %102 %111
  256. OpBranch %103
  257. %105 = OpLabel
  258. OpBranch %98
  259. %98 = OpLabel
  260. %112 = OpLoad %6 %94
  261. %113 = OpIAdd %6 %112 %41
  262. OpStore %94 %113
  263. OpBranch %95
  264. %97 = OpLabel
  265. OpBranch %85
  266. %85 = OpLabel
  267. OpBranch %82
  268. %84 = OpLabel
  269. OpStore %81 %9
  270. OpBranch %114
  271. %114 = OpLabel
  272. OpLoopMerge %116 %117 None
  273. OpBranch %118
  274. %118 = OpLabel
  275. %119 = OpLoad %6 %81
  276. %120 = OpConvertSToF %16 %119
  277. %121 = OpAccessChain %23 %20 %22
  278. %122 = OpLoad %16 %121
  279. %123 = OpFOrdLessThan %26 %120 %122
  280. OpBranchConditional %123 %115 %116
  281. %115 = OpLabel
  282. %124 = OpLoad %6 %81
  283. %125 = OpIAdd %6 %124 %41
  284. OpStore %81 %125
  285. %126 = OpAccessChain %23 %20 %69
  286. %127 = OpLoad %16 %126
  287. %128 = OpAccessChain %23 %20 %72
  288. %129 = OpLoad %16 %128
  289. %130 = OpFOrdEqual %26 %127 %129
  290. OpSelectionMerge %132 None
  291. OpBranchConditional %130 %131 %132
  292. %131 = OpLabel
  293. OpBranch %117
  294. %132 = OpLabel
  295. OpStore %134 %9
  296. OpBranch %135
  297. %135 = OpLabel
  298. OpLoopMerge %137 %138 None
  299. OpBranch %139
  300. %139 = OpLabel
  301. %140 = OpLoad %6 %134
  302. %141 = OpSLessThan %26 %140 %41
  303. OpBranchConditional %141 %136 %137
  304. %136 = OpLabel
  305. OpStore %142 %9
  306. OpBranch %143
  307. %143 = OpLabel
  308. OpLoopMerge %145 %146 None
  309. OpBranch %147
  310. %147 = OpLabel
  311. %148 = OpLoad %6 %142
  312. %149 = OpSLessThan %26 %148 %41
  313. OpBranchConditional %149 %144 %145
  314. %144 = OpLabel
  315. OpBranch %146
  316. %146 = OpLabel
  317. %150 = OpLoad %6 %142
  318. %151 = OpIAdd %6 %150 %41
  319. OpStore %142 %151
  320. OpBranch %143
  321. %145 = OpLabel
  322. %152 = OpAccessChain %23 %20 %69
  323. %153 = OpLoad %16 %152
  324. %154 = OpAccessChain %23 %20 %72
  325. %155 = OpLoad %16 %154
  326. %156 = OpFOrdEqual %26 %153 %155
  327. OpSelectionMerge %158 None
  328. OpBranchConditional %156 %157 %158
  329. %157 = OpLabel
  330. OpBranch %137
  331. %158 = OpLabel
  332. OpBranch %138
  333. %138 = OpLabel
  334. %160 = OpLoad %6 %134
  335. %161 = OpIAdd %6 %160 %41
  336. OpStore %134 %161
  337. OpBranch %135
  338. %137 = OpLabel
  339. OpBranch %117
  340. %117 = OpLabel
  341. OpBranch %114
  342. %116 = OpLabel
  343. OpStore %163 %165
  344. OpReturn
  345. OpFunctionEnd
  346. )";
  347. // clang-format on
  348. std::unique_ptr<IRContext> context =
  349. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  350. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  351. Module* module = context->module();
  352. EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
  353. << text << std::endl;
  354. const Function* f = spvtest::GetFunction(module, 4);
  355. DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
  356. EXPECT_TRUE(analysis->Dominates(5, 10));
  357. EXPECT_TRUE(analysis->Dominates(5, 46));
  358. EXPECT_TRUE(analysis->Dominates(5, 82));
  359. EXPECT_TRUE(analysis->Dominates(5, 114));
  360. EXPECT_TRUE(analysis->Dominates(5, 116));
  361. EXPECT_TRUE(analysis->Dominates(10, 14));
  362. EXPECT_TRUE(analysis->Dominates(10, 11));
  363. EXPECT_TRUE(analysis->Dominates(10, 29));
  364. EXPECT_TRUE(analysis->Dominates(10, 33));
  365. EXPECT_TRUE(analysis->Dominates(10, 30));
  366. EXPECT_TRUE(analysis->Dominates(10, 32));
  367. EXPECT_TRUE(analysis->Dominates(10, 31));
  368. EXPECT_TRUE(analysis->Dominates(10, 13));
  369. EXPECT_TRUE(analysis->Dominates(10, 12));
  370. EXPECT_TRUE(analysis->Dominates(12, 46));
  371. EXPECT_TRUE(analysis->Dominates(46, 50));
  372. EXPECT_TRUE(analysis->Dominates(46, 47));
  373. EXPECT_TRUE(analysis->Dominates(46, 57));
  374. EXPECT_TRUE(analysis->Dominates(46, 61));
  375. EXPECT_TRUE(analysis->Dominates(46, 58));
  376. EXPECT_TRUE(analysis->Dominates(46, 60));
  377. EXPECT_TRUE(analysis->Dominates(46, 59));
  378. EXPECT_TRUE(analysis->Dominates(46, 77));
  379. EXPECT_TRUE(analysis->Dominates(46, 49));
  380. EXPECT_TRUE(analysis->Dominates(46, 76));
  381. EXPECT_TRUE(analysis->Dominates(46, 48));
  382. EXPECT_TRUE(analysis->Dominates(48, 82));
  383. EXPECT_TRUE(analysis->Dominates(82, 86));
  384. EXPECT_TRUE(analysis->Dominates(82, 83));
  385. EXPECT_TRUE(analysis->Dominates(82, 95));
  386. EXPECT_TRUE(analysis->Dominates(82, 99));
  387. EXPECT_TRUE(analysis->Dominates(82, 96));
  388. EXPECT_TRUE(analysis->Dominates(82, 103));
  389. EXPECT_TRUE(analysis->Dominates(82, 107));
  390. EXPECT_TRUE(analysis->Dominates(82, 104));
  391. EXPECT_TRUE(analysis->Dominates(82, 106));
  392. EXPECT_TRUE(analysis->Dominates(82, 105));
  393. EXPECT_TRUE(analysis->Dominates(82, 98));
  394. EXPECT_TRUE(analysis->Dominates(82, 97));
  395. EXPECT_TRUE(analysis->Dominates(82, 85));
  396. EXPECT_TRUE(analysis->Dominates(82, 84));
  397. EXPECT_TRUE(analysis->Dominates(84, 114));
  398. EXPECT_TRUE(analysis->Dominates(114, 118));
  399. EXPECT_TRUE(analysis->Dominates(114, 116));
  400. EXPECT_TRUE(analysis->Dominates(114, 115));
  401. EXPECT_TRUE(analysis->Dominates(114, 132));
  402. EXPECT_TRUE(analysis->Dominates(114, 135));
  403. EXPECT_TRUE(analysis->Dominates(114, 139));
  404. EXPECT_TRUE(analysis->Dominates(114, 136));
  405. EXPECT_TRUE(analysis->Dominates(114, 143));
  406. EXPECT_TRUE(analysis->Dominates(114, 147));
  407. EXPECT_TRUE(analysis->Dominates(114, 144));
  408. EXPECT_TRUE(analysis->Dominates(114, 146));
  409. EXPECT_TRUE(analysis->Dominates(114, 145));
  410. EXPECT_TRUE(analysis->Dominates(114, 158));
  411. EXPECT_TRUE(analysis->Dominates(114, 138));
  412. EXPECT_TRUE(analysis->Dominates(114, 137));
  413. EXPECT_TRUE(analysis->Dominates(114, 131));
  414. EXPECT_TRUE(analysis->Dominates(114, 117));
  415. }
  416. } // namespace
  417. } // namespace opt
  418. } // namespace spvtools