common_subexpression_elimination.sol 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. // RUN: --target polkadot --emit cfg
  2. // Tests control commands
  3. contract c1 {
  4. //BEGIN-CHECK: c1::function::test1
  5. function test1(int a, int b) public pure returns (int) {
  6. int x;
  7. // CHECK: ty:int256 %1.cse_temp = ((arg #0) + (arg #1))
  8. // CHECK: ty:int256 %x = (%1.cse_temp - int256 54)
  9. x = a+b-54;
  10. // CHECK: ty:int256 %d = (%x * %1.cse_temp)
  11. int d = x*(a+b);
  12. // CHECK: ty:int256 %2.cse_temp = ((arg #0) - (arg #1))
  13. if (x + d > 0) {
  14. // NOT-CHECK: ty:int256 %t = ((arg #0) - (arg #1))
  15. // CHECK: ty:int256 %t = %2.cse_temp
  16. int t = a-b;
  17. bool e1 = t>3;
  18. }
  19. else {
  20. // NOT-CHECK: ty:int256 %e = ((arg #0) - (arg #1))
  21. // CHECK: ty:int256 %e = %2.cse_temp
  22. int e = a-b;
  23. bool e2 = e > 3;
  24. }
  25. return x-d + (a-b);
  26. // CHECK: return ((%x - %d) + %2.cse_temp)
  27. }
  28. // BEGIN-CHECK: c1::function::test2
  29. function test2(int a, int b) public pure returns (int) {
  30. int x;
  31. // CHECK: ty:int256 %1.cse_temp = ((arg #0) + (arg #1))
  32. x = a+b-54;
  33. // CHECK: ty:int256 %x = (%1.cse_temp - int256 54)
  34. int d = x*(a+b);
  35. // CHECK: ty:int256 %d = (%x * %1.cse_temp)
  36. // CHECK: ty:int256 %2.cse_temp = (%x + %d)
  37. // CHECK: ty:int256 %3.cse_temp = ((arg #0) - (arg #1))
  38. // CHECK: branchcond (signed more %2.cse_temp > int256 0), block1, block2
  39. if (x + d > 0) {
  40. int t = a-b;
  41. // CHECK: ty:int256 %t = %3.cse_temp
  42. bool e1 = t>3;
  43. // CHECK: return ((%x - %d) + %3.cse_temp)
  44. }
  45. else if (x+d < 0) {
  46. int e = a-b;
  47. // CHECK: ty:int256 %e = %3.cse_temp
  48. bool e2 = e > 3;
  49. } else {
  50. int k = a-b;
  51. // CHECK: ty:int256 %k = %3.cse_temp
  52. bool e3 = k < 4;
  53. }
  54. return x-d + (a-b);
  55. }
  56. // BEGIN-CHECK: c1::function::test3
  57. function test3(int a, int b) public pure returns (int) {
  58. int x;
  59. x = a+b-54;
  60. int d = x*(a+b);
  61. // CHECK: branchcond (signed more %2.cse_temp > int256 0), block1, block2
  62. if (x + d > 0) {
  63. // CHECK: ty:int256 %t = ((arg #0) - (arg #1))
  64. int t = a-b;
  65. bool e1 = t>3;
  66. // CHECK: branchcond (signed less %2.cse_temp < int256 0), block4, block5
  67. // CHECK: return ((%x - %d) + ((arg #0) - (arg #1)))
  68. }
  69. else if (x+d < 0) {
  70. // CHECK: ty:int256 %e = ((arg #0) - (arg #1))
  71. int e = a-b;
  72. bool e2 = e > 3;
  73. // CHECK: branchcond (%2.cse_temp == int256 0), block7, block8
  74. } else if (x + d == 0){
  75. // CHECK: ty:int256 %k = %1.cse_temp
  76. int k = a+b;
  77. bool e3 = k < 4;
  78. }
  79. return x-d + (a-b);
  80. }
  81. // BEGIN-CHECK: c1::function::test4
  82. function test4(int a, int b) public pure returns (int) {
  83. int x;
  84. x = a+b-54;
  85. int d = x*(a+b);
  86. int p = x+d;
  87. // CHECK: ty:int256 %2.cse_temp = ((arg #0) + (arg #1))
  88. // CHECK: ty:int256 %1.cse_temp = (%2.cse_temp - int256 54)
  89. // CHECK: ty:int256 %x = %1.cse_temp
  90. // CHECK: ty:int256 %d = (%1.cse_temp * %2.cse_temp)
  91. // CHECK: ty:int256 %p = (%1.cse_temp + %d)
  92. // CHECK: ty:int256 %3.cse_temp = (%x + %d)
  93. // CHECK: branchcond (signed more %3.cse_temp > int256 0), block2, block3
  94. while (x+d > 0) {
  95. // CHECK: ty:int256 %t = ((arg #0) - (arg #1))
  96. int t = a-b;
  97. bool e1 = t > 3;
  98. // CHECK: ty:int256 %x = %3.cse_temp
  99. x = x+d;
  100. }
  101. // CHECK: return (((%x - %d) + ((arg #0) - (arg #1))) - %p)
  102. return x-d + (a-b) - p;
  103. }
  104. // BEGIN-CHECK: c1::function::test5
  105. function test5(int a, int b) public pure returns (int) {
  106. int x;
  107. x = a+b-54;
  108. int d = x*(a+b);
  109. for(int i=0; i<10; i++) {
  110. // CHECK: ty:int256 %t = ((arg #0) - (arg #1))
  111. int t = a-b;
  112. // CHECK: ty:int256 %i = (%temp.187 + int256 1)
  113. bool e1 = t > 3;
  114. }
  115. // CHECK: return ((%x - %d) + ((arg #0) - (arg #1)))
  116. return x-d + (a-b);
  117. }
  118. // BEGIN-CHECK: c1::function::test6
  119. function test6(int a, int b) public pure returns (int) {
  120. int x;
  121. x = a+b-54;
  122. int d = x*(a+b);
  123. do {
  124. int t = a-b;
  125. bool e1 = t > 3;
  126. // CHECK: ty:int256 %x = (%x + %d)
  127. x = x+d;
  128. // CHECK: branchcond (signed more (%x + %d) > int256 0), block1, block3
  129. } while(x+d > 0);
  130. int t = 3;
  131. bool p = t < 2;
  132. // CHECK: return ((%x - %d) + %t
  133. return x-d + (a-b);
  134. }
  135. // BEGIN-CHECK: c1::function::test7
  136. function test7(int a, int b) public pure returns (int) {
  137. int x;
  138. // CHECK: ty:int256 %1.cse_temp = ((arg #0) + (arg #1))
  139. x = a+b-54;
  140. // CHECK: ty:int256 %x = (%1.cse_temp - int256 54)
  141. int d = x*(a+b);
  142. // CHECK: ty:int256 %d = (%x * %1.cse_temp)
  143. // CHECK: ty:int256 %2.cse_temp = (%x + %d)
  144. // CHECK: ty:int256 %3.cse_temp = ((arg #0) - (arg #1))
  145. // CHECK: branchcond (signed more %2.cse_temp > int256 0), block1, block2
  146. if (x + d > 0) {
  147. int t = a-b;
  148. // CHECK: ty:int256 %t = %3.cse_temp
  149. bool e1 = t>3;
  150. // CHECK: return ((%x - %d) + %3.cse_temp)
  151. }
  152. else if (x+d < 0) {
  153. int e = a-b;
  154. // CHECK: ty:int256 %e = %3.cse_temp
  155. bool e2 = e > 3;
  156. } else if (x+d == 0){
  157. int k = a-b;
  158. // CHECK: ty:int256 %k = %3.cse_temp
  159. bool e3 = k < 4;
  160. } else {
  161. int k1 = a-b;
  162. // CHECK: ty:int256 %k1 = %3.cse_temp
  163. bool e4 = k1 < 4;
  164. }
  165. return x-d + (a-b);
  166. }
  167. int k=2;
  168. // BEGIN-CHECK: c1::function::test8
  169. function test8(int a, int b) public view returns (int ret) {
  170. int x = a + b +k;
  171. // CHECK: ty:int256 %x = (%1.cse_temp + %temp.
  172. if(x + k < 0) {
  173. // CHECK: ty:uint256 %p = uint256((%1.cse_temp + %temp.
  174. uint p = uint(a+b+k);
  175. bool e = p > 50;
  176. }
  177. // CHECK: ty:uint256 %p2 = uint256((%1.cse_temp + %temp.
  178. uint p2 = uint(a+b+k);
  179. // CHECK: ty:int256 %2.cse_temp = int256((%p2 + uint256 9))
  180. int r1 = int(p2+9) -4;
  181. // CHECK: ty:int256 %r1 = (%2.cse_temp - int256 4)
  182. int r2= int(p2+9) -9;
  183. // CHECK: ty:int256 %r2 = (%2.cse_temp - int256 9)
  184. // CHECK: ty:int256 %3.cse_temp = -%r1
  185. // CHECK: ty:int256 %ret = %3.cse_temp
  186. ret = -r1;
  187. // CHECK: ty:int256 %ret = (%3.cse_temp + %r2)
  188. ret = -r1 + r2;
  189. }
  190. struct stTest {
  191. int a;
  192. uint b;
  193. }
  194. // BEGIN-CHECK: c1::function::test9
  195. function test9(int a, int b) public view returns (int ret) {
  196. stTest instance = stTest(2, 3);
  197. // CHECK: ty:int256 %1.cse_temp = ((arg #0) + (arg #1))
  198. int x = a + b + instance.a;
  199. // CHECK: ty:int256 %x = (%1.cse_temp + (load (struct %instance field 0)))
  200. // CHECK: branchcond (signed less (%x + int256((load (struct %instance field 1)))) < int256 0)
  201. if(x + int(instance.b) < 0) {
  202. // CHECK: ty:uint256 %p = uint256((%1.cse_temp + (load (struct %instance field 0))))
  203. uint p = uint(a+b+instance.a);
  204. bool e = p > 50;
  205. }
  206. int8 trunc = int8(x);
  207. // CHECK: ty:bool %e2 = (signed more (sext int16 %trunc) > int16 2)
  208. bool e2 = trunc > 2;
  209. int8 trunc2 = 8 + int8(x);
  210. bool e3 = trunc2 < trunc;
  211. bool e4 = e2 || e3;
  212. // CHECK: branchcond %e3, block3, block4
  213. if (trunc2 < trunc && trunc > 2) {
  214. // CHECK: = %e2
  215. // CHECK: ty:int256 %2.cse_temp = ((arg #0) * (arg #1))
  216. // CHECK: ty:int256 %p2 = %1.cse_temp
  217. int p2 = a+b;
  218. int p3 = p2 - x + a + b;
  219. int p4 = p2-x;
  220. int p5 = p3 + a*b+45;
  221. // CHECK: ty:int256 %p5 = ((%p3 + %2.cse_temp) + int256 45)
  222. // CHECK: return %2.cse_temp
  223. if (p5 !=0) {
  224. // CHECK: ty:uint16 %t1 = (trunc uint16 %p5)
  225. uint16 t1 = uint16(p3 + a*b +45);
  226. // CHECK: ty:uint32 %t2 = (trunc uint32 %2.cse_temp)
  227. uint32 t2 = uint32(a*b);
  228. bool e5 = t2 < t1;
  229. }
  230. // CHECK: ty:int256 %ret = %p5
  231. ret = p3 + a*b + 45;
  232. }
  233. ret = a*b;
  234. }
  235. // BEGIN-CHECK: c1::function::test10
  236. function test10(int a, int b) public pure returns (int) {
  237. int x;
  238. x = a+b-54;
  239. int d = x*(a+b);
  240. int k = x+d;
  241. bool e = k < 0;
  242. do {
  243. int t = a-b;
  244. bool e1 = t > 3;
  245. // CHECK: ty:int256 %x = (%x + %d)
  246. x = x+d;
  247. // CHECK: branchcond (signed more (%x + %d) > int256 0), block1, block3
  248. } while(x+d > 0);
  249. int t = 3;
  250. bool p = t < 2;
  251. // CHECK: return ((%x - %d) + %t
  252. return x-d + (a-b);
  253. }
  254. function get(int a, int b) private pure returns (int) {
  255. return a+b+1;
  256. }
  257. event testEvent(int a, int b, string str);
  258. // BEGIN-CHECK: c1::function::test11
  259. function test11(int a, int b) public returns (int) {
  260. string ast = "Hello!";
  261. string bst = "from Solang";
  262. string cst = ast + bst;
  263. // CHECK: ty:int256 %1.cse_temp = (signed divide (arg #0) / (int256 2 * (arg #1)))
  264. // CHECK: call c1::c1::function::get__int256_int256 %1.cse_temp, (arg #1)
  265. int p = a + get(a/(2*b), b);
  266. bool e = (ast == bst) || p < 2;
  267. // CHECK: ty:bool %2.cse_temp = (strcmp (%ast) (%bst))
  268. // CHECK: branchcond %2.cse_temp, block2, block1
  269. bool e2 = e;
  270. // CHECK: branchcond (strcmp (%cst) (%cst)), block3, block4
  271. if (ast + bst == cst) {
  272. // CHECK: call c1::c1::function::get__int256_int256 %1.cse_temp, (arg #1)
  273. require(a + get(a/(2*b), b) < 0);
  274. emit testEvent(a + get(a/(2*b) -p, b), p, ast+bst);
  275. }
  276. // CHECK: branchcond %2.cse_temp, block21, block22
  277. if (ast == bst) {
  278. ast = ast + "b";
  279. }
  280. // CHECK: call c1::c1::function::get__int256_int256 (%1.cse_temp - %p), (arg #1)
  281. // CHECK: branchcond (strcmp (%ast) (%bst)), block24, block25
  282. while (ast == bst) {
  283. ast = ast + "a";
  284. }
  285. // CHECK: call c1::c1::function::get__int256_int256 (arg #1), (signed divide (arg #0) / (arg #1))
  286. return get(b, a/b);
  287. }
  288. // BEGIN-CHECK: c1::function::test12
  289. function test12(int a, int b) public returns (int) {
  290. int x = a+b;
  291. bool e = (x == a);
  292. // NOT-CHECK: %1.cse_temp =
  293. bool e2 = e;
  294. // CHECK: branchcond (%x == (arg #0))
  295. while(x == a) {
  296. x = x+1;
  297. // NOT-CHECK: cse_temp
  298. x+=1;
  299. x++;
  300. x--;
  301. x++;
  302. x--;
  303. --x;
  304. ++x;
  305. }
  306. return x;
  307. }
  308. function testing(bytes b) public returns (string) {
  309. return string(b);
  310. }
  311. // BEGIN-CHECK: c1::function::test13
  312. function test13(int a, int b) public returns (int) {
  313. string c = "Hello";
  314. bytes b1 = bytes(c);
  315. string b2 = string(b1);
  316. string b3 = b2;
  317. int[4] vec = [1, 2, 3, 4];
  318. // CHECK: ty:int256 %1.cse_temp = ((arg #0) + (arg #1))
  319. int x = (a+b) - (vec[1]-vec[2]);
  320. // CHECK: ty:int256 %x = (%1.cse_temp - ((load (subscript int256[4] %vec[uint32 1])) - (load (subscript int256[4] %vec[uint32 2]))))
  321. bool k3 = x < 1;
  322. // CHECK: = uint256(%1.cse_temp)
  323. vec[uint(a+b)] = 54*(a+b);
  324. // CHECK: = (int256 54 * %1.cse_temp)
  325. // CHECK: = uint256((int256 1 - %1.cse_temp))
  326. vec[uint(1-(a+b))] = vec.length - (a+b);
  327. // CHECK: = (int256 4 - %1.cse_temp)
  328. if(vec.length - (a+b) == 1) {
  329. // CHECK: call c1::c1::function::testing__bytes %c
  330. string k = testing(bytes(c));
  331. string p = "a" +k;
  332. // CHECK: ty:string %p = (concat ((alloc string uint32 1 "a")) (%k))
  333. // CHECK: branchcond ((builtin ArrayLength (%p)) == uint32 2), block11, block12
  334. if(p.length == 2) {
  335. // CHECK: ty:string %p1 = (concat ((alloc string uint32 1 "a")) (%k))
  336. string p1 = "a" + k;
  337. string l = p1;
  338. }
  339. }
  340. // CHECK: branchcond (signed less (%a + (arg #1)) < int256 0), block14, block15
  341. while(a+b < 0) {
  342. // CHECK: branchcond (strcmp (%c) ("a")), block16, block17
  343. if("a" == c) {
  344. a = a+b;
  345. }
  346. }
  347. do {
  348. // CHECK: branchcond (strcmp (%c) ("a")), block21, block22
  349. if("a" == c) {
  350. a = a+b;
  351. }
  352. // CHECK: branchcond (signed more (%a + (arg #1)) > int256 0), block18, block20
  353. } while(a+b > 0);
  354. for(int p=0; p<a; ++p) {
  355. b1.push();
  356. // CHECK: = call c1::c1::function::testing__bytes %b1
  357. string k1 = testing(bytes(string(b1)));
  358. string k2 = k1;
  359. }
  360. return 2;
  361. }
  362. function doNothing(bytes32 b) private {
  363. b = hex"abcd";
  364. }
  365. // BEGIN-CHECK: c1::function::test14
  366. function test14(int a, uint b) public returns (int) {
  367. string c = "Hello";
  368. bytes b3 = bytes(c);
  369. bytes32 b1 = bytes32(b3);
  370. for(int p=0; p<a; ++p) {
  371. doNothing(b1);
  372. // CHECK: ty:bytes32 %b2 = %b1
  373. bytes32 b2 = bytes32(b3);
  374. doNothing(b2);
  375. }
  376. b3 = bytes("d");
  377. for(int p=0; p<a; ++p) {
  378. doNothing(b1);
  379. // CHECK: ty:bytes32 %b2.155 = bytes32 from:bytes (%b3)
  380. bytes32 b2 = bytes32(b3);
  381. doNothing(b2);
  382. }
  383. return 2;
  384. }
  385. // BEGIN-CHECK: c1::function::test15
  386. function test15(uint a, uint b) public pure returns (uint) {
  387. uint c = a << b;
  388. bool b1 = c > 0;
  389. // CHECK: ty:uint256 %1.cse_temp = ((arg #0) << (arg #1))
  390. // CHECK: ty:uint256 %c = %1.cse_temp
  391. // CHECK: ty:bool %b1 = (unsigned more %1.cse_temp > uint256 0)
  392. // CHECK: ty:bool %2.cse_temp = !%b1
  393. // CHECK: branchcond %2.cse_temp, block1, block2
  394. if (!b1) {
  395. // CHECK: return (%1.cse_temp + uint256 1)
  396. return (a << b) + 1;
  397. }
  398. // CHECK: branchcond %2.cse_temp, block4, block3
  399. if(!b1 || c > 0) {
  400. // CHECK: = %b1
  401. // CHECK: return ((arg #0) << ((arg #1) + uint256 1))
  402. return a << b + 1;
  403. }
  404. // CHECK: branchcond (unsigned more %c > uint256 0), block11, block12
  405. for(int i=0; c > 0 && i<10; ++i) {
  406. c++;
  407. }
  408. // CHECK: ty:uint256 %3.cse_temp = ((arg #0) & (arg #1))
  409. // CHECK: branchcond (%3.cse_temp == uint256 0), block13, block14
  410. if (a & b == 0) {
  411. return c--;
  412. }
  413. // CHECK: branchcond (unsigned more %3.cse_temp > uint256 1), block15, block16
  414. if (a & b > 1) {
  415. return a;
  416. }
  417. return c;
  418. }
  419. // BEGIN-CHECK: c1::function::test16
  420. function test16(int a, int b) public pure returns (int) {
  421. int k = (a-b);
  422. bool e = k>0;
  423. for(int i=1; a-b < 0; i++) {
  424. // CHECK: ty:int256 %4.cse_temp = (signed divide %k / (arg #0))
  425. // CHECK: ty:int256 %p = ((%1.cse_temp * int256 5) - %4.cse_temp)
  426. int p = (a-b)*5-k/a;
  427. b++;
  428. // CHECK: ty:int256 %1.cse_temp = ((arg #0) - %b)
  429. // CHECK: branchcond (signed less %1.cse_temp < int256 0), block1, block4
  430. // CHECK: ty:int256 %2.cse_temp = ((arg #0) - %b)
  431. // CHECK: branchcond (signed more %2.cse_temp > int256 0), block6, block7
  432. while(a-b > 0) {
  433. // CHECK: ty:int256 %p = (%2.cse_temp * int256 5)
  434. p = (a-b)*5;
  435. b--;
  436. }
  437. bool e2 = p<1;
  438. }
  439. do {
  440. // CHECK: ty:int256 %p.170 = ((((arg #0) - %b) * int256 5) - %4.cse_temp)
  441. int p = (a-b)*5-k/a;
  442. b++;
  443. bool e2 = p<1;
  444. // CHECK: branchcond (signed less ((arg #0) - %b) < int256 0), block8, block10
  445. }while(a - b < 0);
  446. int g = b;
  447. // CHECK: ty:uint256 %p1 = (uint256((arg #0)) ** uint256(%g))
  448. uint p1 = uint(a)**uint(g);
  449. bool e9 = p1 == 0;
  450. // CHECK: ty:int256 %3.cse_temp = ((arg #0) - %b)
  451. // CHECK: branchcond (signed less %3.cse_temp < int256 0), block12, block13
  452. while(a - b < 0) {
  453. // CHECK: = ((%3.cse_temp * int256 5) - %4.cse_temp)
  454. int p = (a-b)*5-k/a;
  455. b=4;
  456. // CHECK: ty:int256 %5.cse_temp = ((arg #0) - int256 4)
  457. // CHECK: branchcond (signed more %5.cse_temp > int256 0), block14, block15
  458. if (a-b > 0) {
  459. // CHECK: return (%4.cse_temp + int256(%p1))
  460. // CHECK: = (%5.cse_temp * int256 4)
  461. p = (a-b)*4;
  462. b++;
  463. }
  464. bool e2 = p<1;
  465. }
  466. return k/a + int(uint(a)**uint(g));
  467. }
  468. }