code_sink_test.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  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 <string>
  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 CodeSinkTest = PassTest<::testing::Test>;
  22. TEST_F(CodeSinkTest, MoveToNextBlock) {
  23. const std::string text = R"(
  24. ;CHECK: OpFunction
  25. ;CHECK: OpLabel
  26. ;CHECK: OpLabel
  27. ;CHECK: [[ac:%\w+]] = OpAccessChain
  28. ;CHECK: [[ld:%\w+]] = OpLoad %uint [[ac]]
  29. ;CHECK: OpCopyObject %uint [[ld]]
  30. OpCapability Shader
  31. OpMemoryModel Logical GLSL450
  32. OpEntryPoint GLCompute %1 "main"
  33. %void = OpTypeVoid
  34. %uint = OpTypeInt 32 0
  35. %uint_0 = OpConstant %uint 0
  36. %uint_4 = OpConstant %uint 4
  37. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  38. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  39. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  40. %9 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  41. %10 = OpTypeFunction %void
  42. %1 = OpFunction %void None %10
  43. %11 = OpLabel
  44. %12 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0
  45. %13 = OpLoad %uint %12
  46. OpBranch %14
  47. %14 = OpLabel
  48. %15 = OpCopyObject %uint %13
  49. OpReturn
  50. OpFunctionEnd
  51. )";
  52. SinglePassRunAndMatch<CodeSinkingPass>(text, true);
  53. }
  54. TEST_F(CodeSinkTest, MovePastSelection) {
  55. const std::string text = R"(
  56. ;CHECK: OpFunction
  57. ;CHECK: OpLabel
  58. ;CHECK: OpSelectionMerge [[merge_bb:%\w+]]
  59. ;CHECK: [[merge_bb]] = OpLabel
  60. ;CHECK: [[ac:%\w+]] = OpAccessChain
  61. ;CHECK: [[ld:%\w+]] = OpLoad %uint [[ac]]
  62. ;CHECK: OpCopyObject %uint [[ld]]
  63. OpCapability Shader
  64. OpMemoryModel Logical GLSL450
  65. OpEntryPoint GLCompute %1 "main"
  66. %void = OpTypeVoid
  67. %bool = OpTypeBool
  68. %true = OpConstantTrue %bool
  69. %uint = OpTypeInt 32 0
  70. %uint_0 = OpConstant %uint 0
  71. %uint_4 = OpConstant %uint 4
  72. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  73. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  74. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  75. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  76. %12 = OpTypeFunction %void
  77. %1 = OpFunction %void None %12
  78. %13 = OpLabel
  79. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  80. %15 = OpLoad %uint %14
  81. OpSelectionMerge %16 None
  82. OpBranchConditional %true %17 %16
  83. %17 = OpLabel
  84. OpBranch %16
  85. %16 = OpLabel
  86. %18 = OpCopyObject %uint %15
  87. OpReturn
  88. OpFunctionEnd
  89. )";
  90. SinglePassRunAndMatch<CodeSinkingPass>(text, true);
  91. }
  92. TEST_F(CodeSinkTest, MoveIntoSelection) {
  93. const std::string text = R"(
  94. ;CHECK: OpFunction
  95. ;CHECK: OpLabel
  96. ;CHECK: OpSelectionMerge [[merge_bb:%\w+]]
  97. ;CHECK-NEXT: OpBranchConditional %true [[bb:%\w+]] [[merge_bb]]
  98. ;CHECK: [[bb]] = OpLabel
  99. ;CHECK-NEXT: [[ac:%\w+]] = OpAccessChain
  100. ;CHECK-NEXT: [[ld:%\w+]] = OpLoad %uint [[ac]]
  101. ;CHECK-NEXT: OpCopyObject %uint [[ld]]
  102. OpCapability Shader
  103. OpMemoryModel Logical GLSL450
  104. OpEntryPoint GLCompute %1 "main"
  105. %void = OpTypeVoid
  106. %bool = OpTypeBool
  107. %true = OpConstantTrue %bool
  108. %uint = OpTypeInt 32 0
  109. %uint_0 = OpConstant %uint 0
  110. %uint_4 = OpConstant %uint 4
  111. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  112. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  113. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  114. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  115. %12 = OpTypeFunction %void
  116. %1 = OpFunction %void None %12
  117. %13 = OpLabel
  118. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  119. %15 = OpLoad %uint %14
  120. OpSelectionMerge %16 None
  121. OpBranchConditional %true %17 %16
  122. %17 = OpLabel
  123. %18 = OpCopyObject %uint %15
  124. OpBranch %16
  125. %16 = OpLabel
  126. OpReturn
  127. OpFunctionEnd
  128. )";
  129. SinglePassRunAndMatch<CodeSinkingPass>(text, true);
  130. }
  131. TEST_F(CodeSinkTest, LeaveBeforeSelection) {
  132. const std::string text = R"(
  133. OpCapability Shader
  134. OpMemoryModel Logical GLSL450
  135. OpEntryPoint GLCompute %1 "main"
  136. %void = OpTypeVoid
  137. %bool = OpTypeBool
  138. %true = OpConstantTrue %bool
  139. %uint = OpTypeInt 32 0
  140. %uint_0 = OpConstant %uint 0
  141. %uint_4 = OpConstant %uint 4
  142. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  143. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  144. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  145. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  146. %12 = OpTypeFunction %void
  147. %1 = OpFunction %void None %12
  148. %13 = OpLabel
  149. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  150. %15 = OpLoad %uint %14
  151. OpSelectionMerge %16 None
  152. OpBranchConditional %true %17 %20
  153. %20 = OpLabel
  154. OpBranch %16
  155. %17 = OpLabel
  156. %18 = OpCopyObject %uint %15
  157. OpBranch %16
  158. %16 = OpLabel
  159. %19 = OpCopyObject %uint %15
  160. OpReturn
  161. OpFunctionEnd
  162. )";
  163. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  164. text, /* skip_nop = */ true, /* do_validation = */ true);
  165. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  166. }
  167. TEST_F(CodeSinkTest, LeaveAloneUseInSameBlock) {
  168. const std::string text = R"(
  169. OpCapability Shader
  170. OpMemoryModel Logical GLSL450
  171. OpEntryPoint GLCompute %1 "main"
  172. %void = OpTypeVoid
  173. %bool = OpTypeBool
  174. %true = OpConstantTrue %bool
  175. %uint = OpTypeInt 32 0
  176. %uint_0 = OpConstant %uint 0
  177. %uint_4 = OpConstant %uint 4
  178. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  179. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  180. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  181. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  182. %12 = OpTypeFunction %void
  183. %1 = OpFunction %void None %12
  184. %13 = OpLabel
  185. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  186. %15 = OpLoad %uint %14
  187. %cond = OpIEqual %bool %15 %uint_0
  188. OpSelectionMerge %16 None
  189. OpBranchConditional %cond %17 %16
  190. %17 = OpLabel
  191. OpBranch %16
  192. %16 = OpLabel
  193. %19 = OpCopyObject %uint %15
  194. OpReturn
  195. OpFunctionEnd
  196. )";
  197. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  198. text, /* skip_nop = */ true, /* do_validation = */ true);
  199. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  200. }
  201. TEST_F(CodeSinkTest, DontMoveIntoLoop) {
  202. const std::string text = R"(
  203. OpCapability Shader
  204. OpMemoryModel Logical GLSL450
  205. OpEntryPoint GLCompute %1 "main"
  206. %void = OpTypeVoid
  207. %bool = OpTypeBool
  208. %true = OpConstantTrue %bool
  209. %uint = OpTypeInt 32 0
  210. %uint_0 = OpConstant %uint 0
  211. %uint_4 = OpConstant %uint 4
  212. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  213. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  214. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  215. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  216. %12 = OpTypeFunction %void
  217. %1 = OpFunction %void None %12
  218. %13 = OpLabel
  219. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  220. %15 = OpLoad %uint %14
  221. OpBranch %17
  222. %17 = OpLabel
  223. OpLoopMerge %merge %cont None
  224. OpBranch %cont
  225. %cont = OpLabel
  226. %cond = OpIEqual %bool %15 %uint_0
  227. OpBranchConditional %cond %merge %17
  228. %merge = OpLabel
  229. OpReturn
  230. OpFunctionEnd
  231. )";
  232. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  233. text, /* skip_nop = */ true, /* do_validation = */ true);
  234. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  235. }
  236. TEST_F(CodeSinkTest, DontMoveIntoLoop2) {
  237. const std::string text = R"(
  238. OpCapability Shader
  239. OpMemoryModel Logical GLSL450
  240. OpEntryPoint GLCompute %1 "main"
  241. %void = OpTypeVoid
  242. %bool = OpTypeBool
  243. %true = OpConstantTrue %bool
  244. %uint = OpTypeInt 32 0
  245. %uint_0 = OpConstant %uint 0
  246. %uint_4 = OpConstant %uint 4
  247. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  248. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  249. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  250. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  251. %12 = OpTypeFunction %void
  252. %1 = OpFunction %void None %12
  253. %13 = OpLabel
  254. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  255. %15 = OpLoad %uint %14
  256. OpSelectionMerge %16 None
  257. OpBranchConditional %true %17 %16
  258. %17 = OpLabel
  259. OpLoopMerge %merge %cont None
  260. OpBranch %cont
  261. %cont = OpLabel
  262. %cond = OpIEqual %bool %15 %uint_0
  263. OpBranchConditional %cond %merge %17
  264. %merge = OpLabel
  265. OpBranch %16
  266. %16 = OpLabel
  267. OpReturn
  268. OpFunctionEnd
  269. )";
  270. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  271. text, /* skip_nop = */ true, /* do_validation = */ true);
  272. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  273. }
  274. TEST_F(CodeSinkTest, DontMoveSelectionUsedInBothSides) {
  275. const std::string text = R"(
  276. OpCapability Shader
  277. OpMemoryModel Logical GLSL450
  278. OpEntryPoint GLCompute %1 "main"
  279. %void = OpTypeVoid
  280. %bool = OpTypeBool
  281. %true = OpConstantTrue %bool
  282. %uint = OpTypeInt 32 0
  283. %uint_0 = OpConstant %uint 0
  284. %uint_4 = OpConstant %uint 4
  285. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  286. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  287. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  288. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  289. %12 = OpTypeFunction %void
  290. %1 = OpFunction %void None %12
  291. %13 = OpLabel
  292. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  293. %15 = OpLoad %uint %14
  294. OpSelectionMerge %16 None
  295. OpBranchConditional %true %17 %20
  296. %20 = OpLabel
  297. %19 = OpCopyObject %uint %15
  298. OpBranch %16
  299. %17 = OpLabel
  300. %18 = OpCopyObject %uint %15
  301. OpBranch %16
  302. %16 = OpLabel
  303. OpReturn
  304. OpFunctionEnd
  305. )";
  306. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  307. text, /* skip_nop = */ true, /* do_validation = */ true);
  308. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  309. }
  310. TEST_F(CodeSinkTest, DontMoveBecauseOfStore) {
  311. const std::string text = R"(
  312. OpCapability Shader
  313. OpMemoryModel Logical GLSL450
  314. OpEntryPoint GLCompute %1 "main"
  315. %void = OpTypeVoid
  316. %bool = OpTypeBool
  317. %true = OpConstantTrue %bool
  318. %uint = OpTypeInt 32 0
  319. %uint_0 = OpConstant %uint 0
  320. %uint_4 = OpConstant %uint 4
  321. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  322. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  323. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  324. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  325. %12 = OpTypeFunction %void
  326. %1 = OpFunction %void None %12
  327. %13 = OpLabel
  328. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  329. %15 = OpLoad %uint %14
  330. OpStore %14 %15
  331. OpSelectionMerge %16 None
  332. OpBranchConditional %true %17 %20
  333. %20 = OpLabel
  334. OpBranch %16
  335. %17 = OpLabel
  336. %18 = OpCopyObject %uint %15
  337. OpBranch %16
  338. %16 = OpLabel
  339. OpReturn
  340. OpFunctionEnd
  341. )";
  342. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  343. text, /* skip_nop = */ true, /* do_validation = */ true);
  344. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  345. }
  346. TEST_F(CodeSinkTest, MoveReadOnlyLoadWithSync) {
  347. const std::string text = R"(
  348. OpCapability Shader
  349. OpMemoryModel Logical GLSL450
  350. OpEntryPoint GLCompute %1 "main"
  351. %void = OpTypeVoid
  352. %bool = OpTypeBool
  353. %true = OpConstantTrue %bool
  354. %uint = OpTypeInt 32 0
  355. %uint_0 = OpConstant %uint 0
  356. %uint_4 = OpConstant %uint 4
  357. %mem_semantics = OpConstant %uint 0x42 ; Uniform memory arquire
  358. %_arr_uint_uint_4 = OpTypeArray %uint %uint_4
  359. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  360. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  361. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  362. %12 = OpTypeFunction %void
  363. %1 = OpFunction %void None %12
  364. %13 = OpLabel
  365. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  366. %15 = OpLoad %uint %14
  367. OpMemoryBarrier %uint_4 %mem_semantics
  368. OpSelectionMerge %16 None
  369. OpBranchConditional %true %17 %20
  370. %20 = OpLabel
  371. OpBranch %16
  372. %17 = OpLabel
  373. %18 = OpCopyObject %uint %15
  374. OpBranch %16
  375. %16 = OpLabel
  376. OpReturn
  377. OpFunctionEnd
  378. )";
  379. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  380. text, /* skip_nop = */ true, /* do_validation = */ true);
  381. EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
  382. }
  383. TEST_F(CodeSinkTest, DontMoveBecauseOfSync) {
  384. const std::string text = R"(
  385. OpCapability Shader
  386. OpMemoryModel Logical GLSL450
  387. OpEntryPoint GLCompute %1 "main"
  388. OpDecorate %_arr_uint_uint_4 BufferBlock
  389. OpMemberDecorate %_arr_uint_uint_4 0 Offset 0
  390. %void = OpTypeVoid
  391. %bool = OpTypeBool
  392. %true = OpConstantTrue %bool
  393. %uint = OpTypeInt 32 0
  394. %uint_0 = OpConstant %uint 0
  395. %uint_4 = OpConstant %uint 4
  396. %mem_semantics = OpConstant %uint 0x42 ; Uniform memory arquire
  397. %_arr_uint_uint_4 = OpTypeStruct %uint
  398. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  399. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  400. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  401. %12 = OpTypeFunction %void
  402. %1 = OpFunction %void None %12
  403. %13 = OpLabel
  404. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  405. %15 = OpLoad %uint %14
  406. OpMemoryBarrier %uint_4 %mem_semantics
  407. OpSelectionMerge %16 None
  408. OpBranchConditional %true %17 %20
  409. %20 = OpLabel
  410. OpBranch %16
  411. %17 = OpLabel
  412. %18 = OpCopyObject %uint %15
  413. OpBranch %16
  414. %16 = OpLabel
  415. OpReturn
  416. OpFunctionEnd
  417. )";
  418. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  419. text, /* skip_nop = */ true, /* do_validation = */ true);
  420. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  421. }
  422. TEST_F(CodeSinkTest, DontMoveBecauseOfAtomicWithSync) {
  423. const std::string text = R"(
  424. OpCapability Shader
  425. OpMemoryModel Logical GLSL450
  426. OpEntryPoint GLCompute %1 "main"
  427. OpDecorate %_arr_uint_uint_4 BufferBlock
  428. OpMemberDecorate %_arr_uint_uint_4 0 Offset 0
  429. %void = OpTypeVoid
  430. %bool = OpTypeBool
  431. %true = OpConstantTrue %bool
  432. %uint = OpTypeInt 32 0
  433. %uint_0 = OpConstant %uint 0
  434. %uint_4 = OpConstant %uint 4
  435. %mem_semantics = OpConstant %uint 0x42 ; Uniform memory arquire
  436. %_arr_uint_uint_4 = OpTypeStruct %uint
  437. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  438. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  439. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  440. %12 = OpTypeFunction %void
  441. %1 = OpFunction %void None %12
  442. %13 = OpLabel
  443. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  444. %15 = OpLoad %uint %14
  445. %al = OpAtomicLoad %uint %14 %uint_4 %mem_semantics
  446. OpSelectionMerge %16 None
  447. OpBranchConditional %true %17 %20
  448. %20 = OpLabel
  449. OpBranch %16
  450. %17 = OpLabel
  451. %18 = OpCopyObject %uint %15
  452. OpBranch %16
  453. %16 = OpLabel
  454. OpReturn
  455. OpFunctionEnd
  456. )";
  457. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  458. text, /* skip_nop = */ true, /* do_validation = */ true);
  459. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  460. }
  461. TEST_F(CodeSinkTest, MoveWithAtomicWithoutSync) {
  462. const std::string text = R"(
  463. OpCapability Shader
  464. OpMemoryModel Logical GLSL450
  465. OpEntryPoint GLCompute %1 "main"
  466. OpDecorate %_arr_uint_uint_4 BufferBlock
  467. OpMemberDecorate %_arr_uint_uint_4 0 Offset 0
  468. %void = OpTypeVoid
  469. %bool = OpTypeBool
  470. %true = OpConstantTrue %bool
  471. %uint = OpTypeInt 32 0
  472. %uint_0 = OpConstant %uint 0
  473. %uint_4 = OpConstant %uint 4
  474. %_arr_uint_uint_4 = OpTypeStruct %uint
  475. %_ptr_Uniform_uint = OpTypePointer Uniform %uint
  476. %_ptr_Uniform__arr_uint_uint_4 = OpTypePointer Uniform %_arr_uint_uint_4
  477. %11 = OpVariable %_ptr_Uniform__arr_uint_uint_4 Uniform
  478. %12 = OpTypeFunction %void
  479. %1 = OpFunction %void None %12
  480. %13 = OpLabel
  481. %14 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0
  482. %15 = OpLoad %uint %14
  483. %al = OpAtomicLoad %uint %14 %uint_4 %uint_0
  484. OpSelectionMerge %16 None
  485. OpBranchConditional %true %17 %20
  486. %20 = OpLabel
  487. OpBranch %16
  488. %17 = OpLabel
  489. %18 = OpCopyObject %uint %15
  490. OpBranch %16
  491. %16 = OpLabel
  492. OpReturn
  493. OpFunctionEnd
  494. )";
  495. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  496. text, /* skip_nop = */ true, /* do_validation = */ true);
  497. EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
  498. }
  499. TEST_F(CodeSinkTest, DecorationOnLoad) {
  500. const std::string text = R"(
  501. OpCapability Shader
  502. OpMemoryModel Logical GLSL450
  503. OpEntryPoint GLCompute %1 "main" %2
  504. OpDecorate %3 RelaxedPrecision
  505. %void = OpTypeVoid
  506. %5 = OpTypeFunction %void
  507. %float = OpTypeFloat 32
  508. %_ptr_Input_float = OpTypePointer Input %float
  509. %2 = OpVariable %_ptr_Input_float Input
  510. %1 = OpFunction %void None %5
  511. %8 = OpLabel
  512. %3 = OpLoad %float %2
  513. OpReturn
  514. OpFunctionEnd
  515. )";
  516. // We just want to make sure the code does not crash.
  517. auto result = SinglePassRunAndDisassemble<CodeSinkingPass>(
  518. text, /* skip_nop = */ true, /* do_validation = */ true);
  519. EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
  520. }
  521. } // namespace
  522. } // namespace opt
  523. } // namespace spvtools