code_sink_test.cpp 19 KB

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