statements.sol 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. // RUN: --target solana --emit cfg -Onone --no-cse
  2. contract testing {
  3. // BEGIN-CHECK: testing::testing::function::calls_and_unreachable__uint64_uint64
  4. function calls_and_unreachable(uint64 a, uint64 b) public pure {
  5. assembly {
  6. function test1(c : u128, d) {
  7. let y := mul(c, d)
  8. }
  9. // CHECK: = call testing::yul_function_0::test1 (zext uint128 (arg #0)), (zext uint256 (arg #1))
  10. test1(a, b)
  11. // CHECK: assert-failure
  12. invalid()
  13. // NOT-CHECK: ty:uint256 %x =
  14. let x := mul(a, b)
  15. }
  16. }
  17. // BEGIN-CHECK: testing::testing::function::yul_block__uint16_int16
  18. function yul_block(uint16 a, int16 b) public pure {
  19. assembly {
  20. // CHECK: ty:uint256 %x = (sext uint256 ((sext int24 (arg #1)) >> (zext int24 (arg #0))))
  21. let x := shr(a, b)
  22. {
  23. // CHECK: ty:uint256 %y = (overflowing (sext uint256 ((sext int24 (arg #1)) >> (zext int24 (arg #0)))) * (zext uint256 (arg #0)))
  24. let y := mul(x, a)
  25. // CHECK: ty:uint8 %g = uint8((unsigned less int256((overflowing (sext uint256 ((sext int24 (arg #1)) >> (zext int24 (arg #0)))) * (zext uint256 (arg #0)))) < (sext int256 (arg #1))))
  26. let g : u8 := lt(y, b)
  27. }
  28. }
  29. }
  30. // BEGIN-CHECK: testing::testing::function::variable_declaration__bool_uint8
  31. function variable_declaration(bool a, uint8 b) public pure {
  32. assembly {
  33. function multiple() -> ret1, ret2 : s32 {
  34. ret1 := 4
  35. ret2 := 6
  36. }
  37. function unique() -> ret3 {
  38. ret3 := 6
  39. }
  40. // CHECK: %ret3.temp.40 = call testing::yul_function_2::unique
  41. // CHECK: ty:uint256 %c = %ret3.temp.40
  42. let c := unique()
  43. // CHECK: %ret1.temp.41, %ret2.temp.42 = call testing::yul_function_1::multiple
  44. // CHECK: ty:uint256 %d = %ret1.temp.41
  45. // CHECK: ty:int8 %e = (trunc int8 %ret2.temp.42)
  46. let d, e : s8 := multiple()
  47. // CHECK: ty:uint256 %f = uint256(((arg #0) == bool 0))
  48. let f := iszero(a)
  49. // CHECK: ty:uint256 %g = undef
  50. // CHECK: ty:uint256 %h = undef
  51. // CHECK: ty:uint256 %i = undef
  52. let g, h, i
  53. }
  54. }
  55. // BEGIN-CHECK: testing::testing::function::if_statement__bool
  56. function if_statement(bool a) public pure {
  57. assembly {
  58. let x := 5
  59. // CHECK: branchcond (arg #0), block1, block2
  60. if a {
  61. // CHECK: block1: # then
  62. // CHECK: ty:uint256 %x = (overflowing uint256((arg #0)) + uint256 5)
  63. x := add(a, x)
  64. // CHECK: ty:bool %a = false
  65. a := false
  66. // CHECK: branch block2
  67. }
  68. // CHECK: block2: # endif
  69. // CHECK: branchcond (uint256 0 != %x), block3, block4
  70. if x {
  71. // CHECK: block3: # then
  72. // CHECK: ty:uint256 %x = uint256 5
  73. x := 5
  74. // CHECK: branch block4
  75. }
  76. // CHECK: block4: # endif
  77. // CHECK: branchcond (unsigned less %x < uint256 3), block5, block6
  78. if lt(x, 3) {
  79. // CHECK: block5: # then
  80. // CHECK: ty:uint256 %x = uint256 4
  81. x := 4
  82. // CHECK: branch block6
  83. }
  84. // CHECK: block6: # endif
  85. // CHECK: branchcond (unsigned less %x < uint256 3), block7, block8
  86. if lt(x, 3) {
  87. // CHECK: block7: # then
  88. // CHECK: ty:uint256 %x = uint256 6
  89. x := 6
  90. // CHECK: assert-failure
  91. invalid()
  92. // NOT-CHECK: branch
  93. }
  94. // CHECK: branchcond (%x == uint256 3), block9, block10
  95. if eq(x, 3) {
  96. // CHECK: block9: # then
  97. // CHECK: branch block10
  98. }
  99. // CHECK: block10: # endif
  100. // CHECK: ty:uint256 %x = uint256 4
  101. x := 4
  102. }
  103. }
  104. // BEGIN-CHECK: testing::testing::function::for_statement__bool
  105. function for_statement(bool a) public pure {
  106. assembly {
  107. for {
  108. // CHECK: ty:uint256 %i = uint256 1
  109. let i := 1
  110. // CHECK: branch block1
  111. // CHECK: block1: # cond
  112. // CHECK: branchcond (uint256 0 != (overflowing %i + uint256 1)), block3, block4
  113. } add(i, 1) {
  114. // CHECK: block2: # next
  115. // CHECK: ty:uint256 %i = (overflowing %i - uint256 1)
  116. i := sub(i, 1)
  117. // CHECK: branch block1
  118. } {
  119. // CHECK: block3: # body
  120. // CHECK: ty:uint256 %i = (%i << uint256 1)
  121. i := mul(i, 2)
  122. // CHECK: branch block2
  123. }
  124. // CHECK: block4: # end_for
  125. for {
  126. // CHECK: ty:uint256 %i.27 = uint256 1
  127. // CHECK: branch block5
  128. let i := 1
  129. // CHECK: block5: # cond
  130. // CHECK: branchcond (unsigned less %i.27 < uint256 10), block7, block8
  131. } lt(i, 10) {
  132. // CHECK: block6: # next
  133. i := add(i, 1)
  134. // CHECK: ty:uint256 %i.27 = (overflowing %i.27 + uint256 1)
  135. // CHECK: branch block5
  136. } {
  137. // CHECK: block7: # body
  138. // CHECK: ty:uint256 %i.27 = (uint256 2 >> %i.27)
  139. i := shr(i, 2)
  140. // CHECK: branch block6
  141. }
  142. // CHECK: block8: # end_for
  143. for {
  144. // CHECK: ty:uint256 %i.28 = uint256 1
  145. let i := 1
  146. // CHECK: branch block9
  147. // CHECK: block9: # cond
  148. // CHECK: branchcond %a, block11, block12
  149. } a {
  150. // CHECK: block10: # next
  151. // CHECK: ty:uint256 %i.28 = (overflowing uint256(%a) + uint256 1)
  152. i := add(a, 1)
  153. // CHECK: ty:bool %a = false
  154. a := false
  155. } {
  156. // CHECK: block11: # body
  157. // CHECK: ty:bool %a = (uint256 0 != (overflowing %i.28 + uint256 2))
  158. a := add(i, 2)
  159. // CHECK: branch block10
  160. }
  161. // CHECK: block12: # end_for
  162. for {
  163. // CHECK: ty:uint256 %i.29 = uint256 2
  164. let i := 2
  165. // CHECK: branch block13
  166. // CHECK: block13: # cond
  167. // CHECK: branchcond (uint256 2 == uint256 0), block15, block16
  168. } eq(i, 0) {
  169. // CHECK: block14: # next
  170. // NOT-CHECK: ty:uint256 %i.29 =
  171. i := sub(i, 2)
  172. } {
  173. // CHECK: block15: # body
  174. i := add(i, 3)
  175. // CHECK: ty:uint256 %i.29 = uint256 5
  176. invalid()
  177. // CHECK: assert-failure
  178. // NOT-CHECK: branch
  179. }
  180. // CHECK: block16: # end_for
  181. for {
  182. // CHECK: ty:uint256 %j = uint256 2
  183. let j := 2
  184. // CHECK: branch block17
  185. // CHECK: block17: # cond
  186. // CHECK: branchcond (uint256 2 == uint256 3), block19, block20
  187. } eq(j, 3) {
  188. // CHECK: block18: # next
  189. j := shr(j, 2)
  190. // CHECK: ty:uint256 %j = (uint256 2 >> %j)
  191. invalid()
  192. // CHECK: assert-failure
  193. } {
  194. // CHECK: block19: # body
  195. j := sar(j, 3)
  196. // CHECK: branch block18
  197. }
  198. // CHECK: block20: # end_for
  199. for {
  200. // CHECK: ty:uint256 %i.31 = uint256 0
  201. let i := 0
  202. // CHECK: branch block21
  203. // CHECK: block21: # cond
  204. // CHECK: branchcond (unsigned less %i.31 < uint256 10), block23, block24
  205. } lt(i, 10) {
  206. // CHECK: block22: # next
  207. i := add(i, 1)
  208. // CHECK: ty:uint256 %i.31 = (overflowing %i.31 + uint256 1)
  209. // CHECK: branch block21
  210. } {
  211. // CHECK: block23: # body
  212. for {
  213. // CHECK: ty:uint256 %j.32 = uint256 0
  214. let j :=0
  215. // CHECK: branch block25
  216. // ---- block 24 contains the for-loop with the invalid function
  217. // CHECK: block24: # end_for
  218. // CHECK: ty:uint256 %i.33 = uint256 2
  219. // CHECK: assert-failure
  220. // NOT-CHECK: branch
  221. // CHECK: block25: # cond
  222. // CHECK: branchcond (unsigned less %j.32 < uint256 10), block27, block28
  223. } lt(j, 10) {
  224. // CHECK: ty:uint256 %j.32 = (overflowing %j.32 + uint256 1)
  225. j := add(j, 1)
  226. // CHECK: branch block25
  227. } {
  228. // CHECK: block27: # body
  229. // CHECK: ty:bool %a = (uint256 0 != (overflowing %i.31 + %j.32))
  230. a := add(i, j)
  231. // CHECK: branch block26
  232. }
  233. // CHECK: block28: # end_for
  234. // CHECK: branch block22
  235. }
  236. for {
  237. let i := 2
  238. invalid()
  239. } lt(3, 4) {
  240. i := add(i, 1)
  241. } {
  242. i := sub(i, 2)
  243. }
  244. }
  245. }
  246. // BEGIN-CHECK: testing::testing::function::break_statement
  247. function break_statement() public pure {
  248. assembly {
  249. for {let i := 1
  250. // CHECK: ty:uint256 %i = uint256 1
  251. // CHECK: branch block1
  252. // CHECK: block1: # cond
  253. // CHECK: branchcond (unsigned less %i < uint256 10), block3, block4
  254. } lt(i, 10) {i := add(i, 1)
  255. // CHECK: block2: # next
  256. // CHECK: ty:uint256 %i = (overflowing %i + uint256 1)
  257. // CHECK: branch block1
  258. } {
  259. // CHECK: block3: # body
  260. i := shr(i, 2)
  261. // CHECK: ty:uint256 %i = (uint256 2 >> %i)
  262. // CHECK: branchcond (unsigned more %i > uint256 10), block5, block6
  263. if gt(i, 10) {
  264. break
  265. }
  266. }
  267. // CHECK: block4: # end_for
  268. // CHECK: return
  269. // IF-block:
  270. // CHECK: block5: # then
  271. // CHECK: branch block4
  272. // End of for for loop after IF
  273. // CHECK: block6: # endif
  274. // CHECK: branch block2
  275. }
  276. }
  277. // BEGIN-CHECK: testing::testing::function::break_nested_for
  278. function break_nested_for() public pure {
  279. assembly {
  280. for {
  281. // CHECK: ty:uint256 %i = uint256 1
  282. let i := 1
  283. // CHECK: branch block1
  284. // CHECK: branchcond (unsigned less %i < uint256 10), block3, block4
  285. } lt(i, 10) {
  286. // CHECK: block2: # next
  287. i := add(i, 1)
  288. // CHECK: ty:uint256 %i = (overflowing %i + uint256 1)
  289. // CHECK: branch block1
  290. } {
  291. for {
  292. // CHECK: block3: # body
  293. let j := 2
  294. // CHECK: ty:uint256 %j = uint256 2
  295. // CHECK: branch block5
  296. } lt(j, 10) {
  297. // after outer for:
  298. // CHECK: block4: # end_for
  299. // CHECK: return
  300. // inner for condition
  301. // CHECK: block5: # cond
  302. // CHECK: branchcond (unsigned less %j < uint256 10), block7, block8
  303. // CHECK: block6: # next
  304. // CHECK: ty:uint256 %j = (overflowing %j + uint256 1)
  305. // CHECK: branch block5
  306. j := add(j, 1)
  307. } {
  308. // CHECK: block7: # body
  309. // CHECK: branchcond (unsigned more %j > uint256 5), block9, block10
  310. if gt(j, 5) {
  311. break
  312. }
  313. // After inner for:
  314. // CHECK: block8: # end_for
  315. // CHECK: branchcond (unsigned more %i > uint256 5), block11, block12
  316. // Inside inner if:
  317. // CHECK: block9: # then
  318. // CHECK: branch block8
  319. // After inner if:
  320. // CHECK: block10: # endif
  321. // CHECK: ty:uint256 %j = (overflowing %i - uint256 2)
  322. j := sub(i, 2)
  323. // CHECK: branch block6
  324. }
  325. if gt(i, 5) {
  326. // CHECK: block11: # then
  327. break
  328. // CHECK: branch block4
  329. }
  330. // CHECK: block12: # endif
  331. // CHECK: ty:uint256 %i = (overflowing %i - uint256 4)
  332. i := sub(i, 4)
  333. // CHECK: branch block2
  334. }
  335. }
  336. }
  337. // BEGIN-CHECK: testing::testing::function::continue_statement
  338. function continue_statement() public pure {
  339. assembly {
  340. for {let i := 1
  341. // CHECK: ty:uint256 %i = uint256 1
  342. // CHECK: branch block1
  343. // CHECK: block1: # cond
  344. // CHECK: branchcond (unsigned less %i < uint256 10), block3, block4
  345. } lt(i, 10) {i := add(i, 1)
  346. // CHECK: block2: # next
  347. // CHECK: ty:uint256 %i = (overflowing %i + uint256 1)
  348. // CHECK: branch block1
  349. } {
  350. // CHECK: block3: # body
  351. i := shr(i, 2)
  352. // CHECK: ty:uint256 %i = (uint256 2 >> %i)
  353. // CHECK: branchcond (unsigned more %i > uint256 10), block5, block6
  354. if gt(i, 10) {
  355. continue
  356. }
  357. }
  358. // CHECK: block4: # end_for
  359. // CHECK: return
  360. // IF-block:
  361. // CHECK: block5: # then
  362. // CHECK: branch block2
  363. // End of for for loop after IF
  364. // CHECK: block6: # endif
  365. // CHECK: branch block2
  366. }
  367. }
  368. // BEGIN-CHECK: testing::testing::function::continue_nested_for
  369. function continue_nested_for() public pure {
  370. assembly {
  371. for {
  372. // CHECK: ty:uint256 %i = uint256 1
  373. let i := 1
  374. // CHECK: branch block1
  375. // CHECK: branchcond (unsigned less %i < uint256 10), block3, block4
  376. } lt(i, 10) {
  377. // CHECK: block2: # next
  378. i := add(i, 1)
  379. // CHECK: ty:uint256 %i = (overflowing %i + uint256 1)
  380. // CHECK: branch block1
  381. } {
  382. for {
  383. // CHECK: block3: # body
  384. let j := 2
  385. // CHECK: ty:uint256 %j = uint256 2
  386. // CHECK: branch block5
  387. } lt(j, 10) {
  388. // after outer for:
  389. // CHECK: block4: # end_for
  390. // CHECK: return
  391. // inner for condition
  392. // CHECK: block5: # cond
  393. // CHECK: branchcond (unsigned less %j < uint256 10), block7, block8
  394. // CHECK: block6: # next
  395. // CHECK: ty:uint256 %j = (overflowing %j + uint256 1)
  396. // CHECK: branch block5
  397. j := add(j, 1)
  398. } {
  399. // CHECK: block7: # body
  400. // CHECK: branchcond (unsigned more %j > uint256 5), block9, block10
  401. if gt(j, 5) {
  402. continue
  403. }
  404. // After inner for:
  405. // CHECK: block8: # end_for
  406. // CHECK: branchcond (unsigned more %i > uint256 5), block11, block12
  407. // Inside inner if:
  408. // CHECK: block9: # then
  409. // CHECK: branch block6
  410. // After inner if:
  411. // CHECK: block10: # endif
  412. // CHECK: ty:uint256 %j = (overflowing %i - uint256 2)
  413. j := sub(i, 2)
  414. // CHECK: branch block6
  415. }
  416. if gt(i, 5) {
  417. // CHECK: block11: # then
  418. continue
  419. // CHECK: branch block2
  420. }
  421. // CHECK: block12: # endif
  422. // CHECK: ty:uint256 %i = (overflowing %i - uint256 4)
  423. i := sub(i, 4)
  424. // CHECK: branch block2
  425. }
  426. }
  427. }
  428. }