basic.ll 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. ; RUN: opt < %s -loop-reroll -S | FileCheck %s
  2. target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
  3. target triple = "x86_64-unknown-linux-gnu"
  4. ; int foo(int a);
  5. ; void bar(int *x) {
  6. ; for (int i = 0; i < 500; i += 3) {
  7. ; foo(i);
  8. ; foo(i+1);
  9. ; foo(i+2);
  10. ; }
  11. ; }
  12. ; Function Attrs: nounwind uwtable
  13. define void @bar(i32* nocapture readnone %x) #0 {
  14. entry:
  15. br label %for.body
  16. for.body: ; preds = %for.body, %entry
  17. %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
  18. %call = tail call i32 @foo(i32 %i.08) #1
  19. %add = add nsw i32 %i.08, 1
  20. %call1 = tail call i32 @foo(i32 %add) #1
  21. %add2 = add nsw i32 %i.08, 2
  22. %call3 = tail call i32 @foo(i32 %add2) #1
  23. %add3 = add nsw i32 %i.08, 3
  24. %exitcond = icmp eq i32 %add3, 500
  25. br i1 %exitcond, label %for.end, label %for.body
  26. ; CHECK-LABEL: @bar
  27. ; CHECK: for.body:
  28. ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
  29. ; CHECK: %call = tail call i32 @foo(i32 %indvar) #1
  30. ; CHECK: %indvar.next = add i32 %indvar, 1
  31. ; CHECK: %exitcond1 = icmp eq i32 %indvar, 497
  32. ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
  33. ; CHECK: ret
  34. for.end: ; preds = %for.body
  35. ret void
  36. }
  37. declare i32 @foo(i32)
  38. ; void hi1(int *x) {
  39. ; for (int i = 0; i < 1500; i += 3) {
  40. ; x[i] = foo(0);
  41. ; x[i+1] = foo(0);
  42. ; x[i+2] = foo(0);
  43. ; }
  44. ; }
  45. ; Function Attrs: nounwind uwtable
  46. define void @hi1(i32* nocapture %x) #0 {
  47. entry:
  48. br label %for.body
  49. for.body: ; preds = %entry, %for.body
  50. %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  51. %call = tail call i32 @foo(i32 0) #1
  52. %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
  53. store i32 %call, i32* %arrayidx, align 4
  54. %call1 = tail call i32 @foo(i32 0) #1
  55. %0 = add nsw i64 %indvars.iv, 1
  56. %arrayidx3 = getelementptr inbounds i32, i32* %x, i64 %0
  57. store i32 %call1, i32* %arrayidx3, align 4
  58. %call4 = tail call i32 @foo(i32 0) #1
  59. %1 = add nsw i64 %indvars.iv, 2
  60. %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %1
  61. store i32 %call4, i32* %arrayidx7, align 4
  62. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3
  63. %2 = trunc i64 %indvars.iv.next to i32
  64. %cmp = icmp slt i32 %2, 1500
  65. br i1 %cmp, label %for.body, label %for.end
  66. ; CHECK-LABEL: @hi1
  67. ; CHECK: for.body:
  68. ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
  69. ; CHECK: %call = tail call i32 @foo(i32 0) #1
  70. ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvar
  71. ; CHECK: store i32 %call, i32* %arrayidx, align 4
  72. ; CHECK: %indvar.next = add i64 %indvar, 1
  73. ; CHECK: %exitcond = icmp eq i64 %indvar, 1499
  74. ; CHECK: br i1 %exitcond, label %for.end, label %for.body
  75. ; CHECK: ret
  76. for.end: ; preds = %for.body
  77. ret void
  78. }
  79. ; void hi2(int *x) {
  80. ; for (int i = 0; i < 500; ++i) {
  81. ; x[3*i] = foo(0);
  82. ; x[3*i+1] = foo(0);
  83. ; x[3*i+2] = foo(0);
  84. ; }
  85. ; }
  86. ; Function Attrs: nounwind uwtable
  87. define void @hi2(i32* nocapture %x) #0 {
  88. entry:
  89. br label %for.body
  90. for.body: ; preds = %for.body, %entry
  91. %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  92. %call = tail call i32 @foo(i32 0) #1
  93. %0 = mul nsw i64 %indvars.iv, 3
  94. %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
  95. store i32 %call, i32* %arrayidx, align 4
  96. %call1 = tail call i32 @foo(i32 0) #1
  97. %1 = add nsw i64 %0, 1
  98. %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
  99. store i32 %call1, i32* %arrayidx4, align 4
  100. %call5 = tail call i32 @foo(i32 0) #1
  101. %2 = add nsw i64 %0, 2
  102. %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
  103. store i32 %call5, i32* %arrayidx9, align 4
  104. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  105. %exitcond = icmp eq i64 %indvars.iv.next, 500
  106. br i1 %exitcond, label %for.end, label %for.body
  107. ; CHECK-LABEL: @hi2
  108. ; CHECK: for.body:
  109. ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  110. ; CHECK: %call = tail call i32 @foo(i32 0) #1
  111. ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
  112. ; CHECK: store i32 %call, i32* %arrayidx, align 4
  113. ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  114. ; CHECK: %exitcond1 = icmp eq i64 %indvars.iv, 1499
  115. ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
  116. ; CHECK: ret
  117. for.end: ; preds = %for.body
  118. ret void
  119. }
  120. ; void goo(float alpha, float *a, float *b) {
  121. ; for (int i = 0; i < 3200; i += 5) {
  122. ; a[i] += alpha * b[i];
  123. ; a[i + 1] += alpha * b[i + 1];
  124. ; a[i + 2] += alpha * b[i + 2];
  125. ; a[i + 3] += alpha * b[i + 3];
  126. ; a[i + 4] += alpha * b[i + 4];
  127. ; }
  128. ; }
  129. ; Function Attrs: nounwind uwtable
  130. define void @goo(float %alpha, float* nocapture %a, float* nocapture readonly %b) #0 {
  131. entry:
  132. br label %for.body
  133. for.body: ; preds = %entry, %for.body
  134. %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  135. %arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv
  136. %0 = load float, float* %arrayidx, align 4
  137. %mul = fmul float %0, %alpha
  138. %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv
  139. %1 = load float, float* %arrayidx2, align 4
  140. %add = fadd float %1, %mul
  141. store float %add, float* %arrayidx2, align 4
  142. %2 = add nsw i64 %indvars.iv, 1
  143. %arrayidx5 = getelementptr inbounds float, float* %b, i64 %2
  144. %3 = load float, float* %arrayidx5, align 4
  145. %mul6 = fmul float %3, %alpha
  146. %arrayidx9 = getelementptr inbounds float, float* %a, i64 %2
  147. %4 = load float, float* %arrayidx9, align 4
  148. %add10 = fadd float %4, %mul6
  149. store float %add10, float* %arrayidx9, align 4
  150. %5 = add nsw i64 %indvars.iv, 2
  151. %arrayidx13 = getelementptr inbounds float, float* %b, i64 %5
  152. %6 = load float, float* %arrayidx13, align 4
  153. %mul14 = fmul float %6, %alpha
  154. %arrayidx17 = getelementptr inbounds float, float* %a, i64 %5
  155. %7 = load float, float* %arrayidx17, align 4
  156. %add18 = fadd float %7, %mul14
  157. store float %add18, float* %arrayidx17, align 4
  158. %8 = add nsw i64 %indvars.iv, 3
  159. %arrayidx21 = getelementptr inbounds float, float* %b, i64 %8
  160. %9 = load float, float* %arrayidx21, align 4
  161. %mul22 = fmul float %9, %alpha
  162. %arrayidx25 = getelementptr inbounds float, float* %a, i64 %8
  163. %10 = load float, float* %arrayidx25, align 4
  164. %add26 = fadd float %10, %mul22
  165. store float %add26, float* %arrayidx25, align 4
  166. %11 = add nsw i64 %indvars.iv, 4
  167. %arrayidx29 = getelementptr inbounds float, float* %b, i64 %11
  168. %12 = load float, float* %arrayidx29, align 4
  169. %mul30 = fmul float %12, %alpha
  170. %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11
  171. %13 = load float, float* %arrayidx33, align 4
  172. %add34 = fadd float %13, %mul30
  173. store float %add34, float* %arrayidx33, align 4
  174. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5
  175. %14 = trunc i64 %indvars.iv.next to i32
  176. %cmp = icmp slt i32 %14, 3200
  177. br i1 %cmp, label %for.body, label %for.end
  178. ; CHECK-LABEL: @goo
  179. ; CHECK: for.body:
  180. ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
  181. ; CHECK: %arrayidx = getelementptr inbounds float, float* %b, i64 %indvar
  182. ; CHECK: %0 = load float, float* %arrayidx, align 4
  183. ; CHECK: %mul = fmul float %0, %alpha
  184. ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvar
  185. ; CHECK: %1 = load float, float* %arrayidx2, align 4
  186. ; CHECK: %add = fadd float %1, %mul
  187. ; CHECK: store float %add, float* %arrayidx2, align 4
  188. ; CHECK: %indvar.next = add i64 %indvar, 1
  189. ; CHECK: %exitcond = icmp eq i64 %indvar, 3199
  190. ; CHECK: br i1 %exitcond, label %for.end, label %for.body
  191. ; CHECK: ret
  192. for.end: ; preds = %for.body
  193. ret void
  194. }
  195. ; void hoo(float alpha, float *a, float *b, int *ip) {
  196. ; for (int i = 0; i < 3200; i += 5) {
  197. ; a[i] += alpha * b[ip[i]];
  198. ; a[i + 1] += alpha * b[ip[i + 1]];
  199. ; a[i + 2] += alpha * b[ip[i + 2]];
  200. ; a[i + 3] += alpha * b[ip[i + 3]];
  201. ; a[i + 4] += alpha * b[ip[i + 4]];
  202. ; }
  203. ; }
  204. ; Function Attrs: nounwind uwtable
  205. define void @hoo(float %alpha, float* nocapture %a, float* nocapture readonly %b, i32* nocapture readonly %ip) #0 {
  206. entry:
  207. br label %for.body
  208. for.body: ; preds = %entry, %for.body
  209. %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  210. %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvars.iv
  211. %0 = load i32, i32* %arrayidx, align 4
  212. %idxprom1 = sext i32 %0 to i64
  213. %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1
  214. %1 = load float, float* %arrayidx2, align 4
  215. %mul = fmul float %1, %alpha
  216. %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvars.iv
  217. %2 = load float, float* %arrayidx4, align 4
  218. %add = fadd float %2, %mul
  219. store float %add, float* %arrayidx4, align 4
  220. %3 = add nsw i64 %indvars.iv, 1
  221. %arrayidx7 = getelementptr inbounds i32, i32* %ip, i64 %3
  222. %4 = load i32, i32* %arrayidx7, align 4
  223. %idxprom8 = sext i32 %4 to i64
  224. %arrayidx9 = getelementptr inbounds float, float* %b, i64 %idxprom8
  225. %5 = load float, float* %arrayidx9, align 4
  226. %mul10 = fmul float %5, %alpha
  227. %arrayidx13 = getelementptr inbounds float, float* %a, i64 %3
  228. %6 = load float, float* %arrayidx13, align 4
  229. %add14 = fadd float %6, %mul10
  230. store float %add14, float* %arrayidx13, align 4
  231. %7 = add nsw i64 %indvars.iv, 2
  232. %arrayidx17 = getelementptr inbounds i32, i32* %ip, i64 %7
  233. %8 = load i32, i32* %arrayidx17, align 4
  234. %idxprom18 = sext i32 %8 to i64
  235. %arrayidx19 = getelementptr inbounds float, float* %b, i64 %idxprom18
  236. %9 = load float, float* %arrayidx19, align 4
  237. %mul20 = fmul float %9, %alpha
  238. %arrayidx23 = getelementptr inbounds float, float* %a, i64 %7
  239. %10 = load float, float* %arrayidx23, align 4
  240. %add24 = fadd float %10, %mul20
  241. store float %add24, float* %arrayidx23, align 4
  242. %11 = add nsw i64 %indvars.iv, 3
  243. %arrayidx27 = getelementptr inbounds i32, i32* %ip, i64 %11
  244. %12 = load i32, i32* %arrayidx27, align 4
  245. %idxprom28 = sext i32 %12 to i64
  246. %arrayidx29 = getelementptr inbounds float, float* %b, i64 %idxprom28
  247. %13 = load float, float* %arrayidx29, align 4
  248. %mul30 = fmul float %13, %alpha
  249. %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11
  250. %14 = load float, float* %arrayidx33, align 4
  251. %add34 = fadd float %14, %mul30
  252. store float %add34, float* %arrayidx33, align 4
  253. %15 = add nsw i64 %indvars.iv, 4
  254. %arrayidx37 = getelementptr inbounds i32, i32* %ip, i64 %15
  255. %16 = load i32, i32* %arrayidx37, align 4
  256. %idxprom38 = sext i32 %16 to i64
  257. %arrayidx39 = getelementptr inbounds float, float* %b, i64 %idxprom38
  258. %17 = load float, float* %arrayidx39, align 4
  259. %mul40 = fmul float %17, %alpha
  260. %arrayidx43 = getelementptr inbounds float, float* %a, i64 %15
  261. %18 = load float, float* %arrayidx43, align 4
  262. %add44 = fadd float %18, %mul40
  263. store float %add44, float* %arrayidx43, align 4
  264. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5
  265. %19 = trunc i64 %indvars.iv.next to i32
  266. %cmp = icmp slt i32 %19, 3200
  267. br i1 %cmp, label %for.body, label %for.end
  268. ; CHECK-LABEL: @hoo
  269. ; CHECK: for.body:
  270. ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
  271. ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvar
  272. ; CHECK: %0 = load i32, i32* %arrayidx, align 4
  273. ; CHECK: %idxprom1 = sext i32 %0 to i64
  274. ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1
  275. ; CHECK: %1 = load float, float* %arrayidx2, align 4
  276. ; CHECK: %mul = fmul float %1, %alpha
  277. ; CHECK: %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvar
  278. ; CHECK: %2 = load float, float* %arrayidx4, align 4
  279. ; CHECK: %add = fadd float %2, %mul
  280. ; CHECK: store float %add, float* %arrayidx4, align 4
  281. ; CHECK: %indvar.next = add i64 %indvar, 1
  282. ; CHECK: %exitcond = icmp eq i64 %indvar, 3199
  283. ; CHECK: br i1 %exitcond, label %for.end, label %for.body
  284. ; CHECK: ret
  285. for.end: ; preds = %for.body
  286. ret void
  287. }
  288. ; void multi1(int *x) {
  289. ; y = foo(0)
  290. ; for (int i = 0; i < 500; ++i) {
  291. ; x[3*i] = y;
  292. ; x[3*i+1] = y;
  293. ; x[3*i+2] = y;
  294. ; x[3*i+6] = y;
  295. ; x[3*i+7] = y;
  296. ; x[3*i+8] = y;
  297. ; }
  298. ; }
  299. ; Function Attrs: nounwind uwtable
  300. define void @multi1(i32* nocapture %x) #0 {
  301. entry:
  302. %call = tail call i32 @foo(i32 0) #1
  303. br label %for.body
  304. for.body: ; preds = %for.body, %entry
  305. %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  306. %0 = mul nsw i64 %indvars.iv, 3
  307. %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
  308. store i32 %call, i32* %arrayidx, align 4
  309. %1 = add nsw i64 %0, 1
  310. %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
  311. store i32 %call, i32* %arrayidx4, align 4
  312. %2 = add nsw i64 %0, 2
  313. %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
  314. store i32 %call, i32* %arrayidx9, align 4
  315. %3 = add nsw i64 %0, 6
  316. %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %3
  317. store i32 %call, i32* %arrayidx6, align 4
  318. %4 = add nsw i64 %0, 7
  319. %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %4
  320. store i32 %call, i32* %arrayidx7, align 4
  321. %5 = add nsw i64 %0, 8
  322. %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %5
  323. store i32 %call, i32* %arrayidx8, align 4
  324. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  325. %exitcond = icmp eq i64 %indvars.iv.next, 500
  326. br i1 %exitcond, label %for.end, label %for.body
  327. ; CHECK-LABEL: @multi1
  328. ; CHECK:for.body:
  329. ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  330. ; CHECK: %0 = add i64 %indvars.iv, 6
  331. ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
  332. ; CHECK: store i32 %call, i32* %arrayidx, align 4
  333. ; CHECK: %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0
  334. ; CHECK: store i32 %call, i32* %arrayidx6, align 4
  335. ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  336. ; CHECK: %exitcond2 = icmp eq i64 %0, 1505
  337. ; CHECK: br i1 %exitcond2, label %for.end, label %for.body
  338. for.end: ; preds = %for.body
  339. ret void
  340. }
  341. ; void multi2(int *x) {
  342. ; y = foo(0)
  343. ; for (int i = 0; i < 500; ++i) {
  344. ; x[3*i] = y;
  345. ; x[3*i+1] = y;
  346. ; x[3*i+2] = y;
  347. ; x[3*(i+1)] = y;
  348. ; x[3*(i+1)+1] = y;
  349. ; x[3*(i+1)+2] = y;
  350. ; }
  351. ; }
  352. ; Function Attrs: nounwind uwtable
  353. define void @multi2(i32* nocapture %x) #0 {
  354. entry:
  355. %call = tail call i32 @foo(i32 0) #1
  356. br label %for.body
  357. for.body: ; preds = %for.body, %entry
  358. %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  359. %0 = mul nsw i64 %indvars.iv, 3
  360. %add = add nsw i64 %indvars.iv, 1
  361. %newmul = mul nsw i64 %add, 3
  362. %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
  363. store i32 %call, i32* %arrayidx, align 4
  364. %1 = add nsw i64 %0, 1
  365. %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
  366. store i32 %call, i32* %arrayidx4, align 4
  367. %2 = add nsw i64 %0, 2
  368. %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
  369. store i32 %call, i32* %arrayidx9, align 4
  370. %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %newmul
  371. store i32 %call, i32* %arrayidx6, align 4
  372. %3 = add nsw i64 %newmul, 1
  373. %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %3
  374. store i32 %call, i32* %arrayidx7, align 4
  375. %4 = add nsw i64 %newmul, 2
  376. %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %4
  377. store i32 %call, i32* %arrayidx8, align 4
  378. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  379. %exitcond = icmp eq i64 %indvars.iv.next, 500
  380. br i1 %exitcond, label %for.end, label %for.body
  381. ; CHECK-LABEL: @multi2
  382. ; CHECK:for.body:
  383. ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  384. ; CHECK: %0 = add i64 %indvars.iv, 3
  385. ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
  386. ; CHECK: store i32 %call, i32* %arrayidx, align 4
  387. ; CHECK: %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0
  388. ; CHECK: store i32 %call, i32* %arrayidx6, align 4
  389. ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  390. ; CHECK: %exitcond2 = icmp eq i64 %indvars.iv, 1499
  391. ; CHECK: br i1 %exitcond2, label %for.end, label %for.body
  392. for.end: ; preds = %for.body
  393. ret void
  394. }
  395. ; void multi3(int *x) {
  396. ; y = foo(0)
  397. ; for (int i = 0; i < 500; ++i) {
  398. ; // Note: No zero index
  399. ; x[3*i+3] = y;
  400. ; x[3*i+4] = y;
  401. ; x[3*i+5] = y;
  402. ; }
  403. ; }
  404. ; Function Attrs: nounwind uwtable
  405. define void @multi3(i32* nocapture %x) #0 {
  406. entry:
  407. %call = tail call i32 @foo(i32 0) #1
  408. br label %for.body
  409. for.body: ; preds = %for.body, %entry
  410. %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  411. %0 = mul nsw i64 %indvars.iv, 3
  412. %x0 = add nsw i64 %0, 3
  413. %add = add nsw i64 %indvars.iv, 1
  414. %arrayidx = getelementptr inbounds i32, i32* %x, i64 %x0
  415. store i32 %call, i32* %arrayidx, align 4
  416. %1 = add nsw i64 %0, 4
  417. %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
  418. store i32 %call, i32* %arrayidx4, align 4
  419. %2 = add nsw i64 %0, 5
  420. %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
  421. store i32 %call, i32* %arrayidx9, align 4
  422. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  423. %exitcond = icmp eq i64 %indvars.iv.next, 500
  424. br i1 %exitcond, label %for.end, label %for.body
  425. ; CHECK-LABEL: @multi3
  426. ; CHECK: for.body:
  427. ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  428. ; CHECK: %0 = add i64 %indvars.iv, 3
  429. ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
  430. ; CHECK: store i32 %call, i32* %arrayidx, align 4
  431. ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  432. ; CHECK: %exitcond1 = icmp eq i64 %0, 1502
  433. ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
  434. for.end: ; preds = %for.body
  435. ret void
  436. }
  437. ; int foo(int a);
  438. ; void bar2(int *x, int y, int z) {
  439. ; for (int i = 0; i < 500; i += 3) {
  440. ; foo(i+y+i*z); // Slightly reordered instruction order
  441. ; foo(i+1+y+(i+1)*z);
  442. ; foo(i+2+y+(i+2)*z);
  443. ; }
  444. ; }
  445. ; Function Attrs: nounwind uwtable
  446. define void @bar2(i32* nocapture readnone %x, i32 %y, i32 %z) #0 {
  447. entry:
  448. br label %for.body
  449. for.body: ; preds = %for.body, %entry
  450. %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
  451. %tmp1 = add i32 %i.08, %y
  452. %tmp2 = mul i32 %i.08, %z
  453. %tmp3 = add i32 %tmp2, %tmp1
  454. %call = tail call i32 @foo(i32 %tmp3) #1
  455. %add = add nsw i32 %i.08, 1
  456. %tmp2a = mul i32 %add, %z
  457. %tmp1a = add i32 %add, %y
  458. %tmp3a = add i32 %tmp2a, %tmp1a
  459. %calla = tail call i32 @foo(i32 %tmp3a) #1
  460. %add2 = add nsw i32 %i.08, 2
  461. %tmp2b = mul i32 %add2, %z
  462. %tmp1b = add i32 %add2, %y
  463. %tmp3b = add i32 %tmp2b, %tmp1b
  464. %callb = tail call i32 @foo(i32 %tmp3b) #1
  465. %add3 = add nsw i32 %i.08, 3
  466. %exitcond = icmp eq i32 %add3, 500
  467. br i1 %exitcond, label %for.end, label %for.body
  468. ; CHECK-LABEL: @bar2
  469. ; CHECK: for.body:
  470. ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
  471. ; CHECK: %tmp1 = add i32 %indvar, %y
  472. ; CHECK: %tmp2 = mul i32 %indvar, %z
  473. ; CHECK: %tmp3 = add i32 %tmp2, %tmp1
  474. ; CHECK: %call = tail call i32 @foo(i32 %tmp3) #1
  475. ; CHECK: %indvar.next = add i32 %indvar, 1
  476. ; CHECK: %exitcond1 = icmp eq i32 %indvar, 497
  477. ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
  478. ; CHECK: ret
  479. for.end: ; preds = %for.body
  480. ret void
  481. }
  482. %struct.s = type { i32, i32 }
  483. ; Function Attrs: nounwind uwtable
  484. define void @gep1(%struct.s* nocapture %x) #0 {
  485. entry:
  486. %call = tail call i32 @foo(i32 0) #1
  487. br label %for.body
  488. for.body: ; preds = %for.body, %entry
  489. %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  490. %0 = mul nsw i64 %indvars.iv, 3
  491. %arrayidx = getelementptr inbounds %struct.s, %struct.s* %x, i64 %0, i32 0
  492. store i32 %call, i32* %arrayidx, align 4
  493. %1 = add nsw i64 %0, 1
  494. %arrayidx4 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %1, i32 0
  495. store i32 %call, i32* %arrayidx4, align 4
  496. %2 = add nsw i64 %0, 2
  497. %arrayidx9 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %2, i32 0
  498. store i32 %call, i32* %arrayidx9, align 4
  499. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  500. %exitcond = icmp eq i64 %indvars.iv.next, 500
  501. br i1 %exitcond, label %for.end, label %for.body
  502. ; CHECK-LABEL: @gep1
  503. ; This test is a crash test only.
  504. ; CHECK: ret
  505. for.end: ; preds = %for.body
  506. ret void
  507. }
  508. attributes #0 = { nounwind uwtable }
  509. attributes #1 = { nounwind }