hoist-deref-load.ll 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. ; RUN: opt -S -basicaa -licm < %s | FileCheck %s
  2. target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
  3. target triple = "x86_64-unknown-linux-gnu"
  4. ; This test represents the following function:
  5. ; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) {
  6. ; for (int i = 0; i < n; ++i)
  7. ; if (a[i] > 0)
  8. ; a[i] = c*b[i];
  9. ; }
  10. ; and we want to hoist the load of %c out of the loop. This can be done only
  11. ; because the dereferenceable attribute is on %c.
  12. ; CHECK-LABEL: @test1
  13. ; CHECK: load i32, i32* %c, align 4
  14. ; CHECK: for.body:
  15. define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 {
  16. entry:
  17. %cmp11 = icmp sgt i32 %n, 0
  18. br i1 %cmp11, label %for.body, label %for.end
  19. for.body: ; preds = %entry, %for.inc
  20. %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
  21. %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
  22. %0 = load i32, i32* %arrayidx, align 4
  23. %cmp1 = icmp sgt i32 %0, 0
  24. br i1 %cmp1, label %if.then, label %for.inc
  25. if.then: ; preds = %for.body
  26. %1 = load i32, i32* %c, align 4
  27. %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
  28. %2 = load i32, i32* %arrayidx3, align 4
  29. %mul = mul nsw i32 %2, %1
  30. store i32 %mul, i32* %arrayidx, align 4
  31. br label %for.inc
  32. for.inc: ; preds = %for.body, %if.then
  33. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  34. %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  35. %exitcond = icmp eq i32 %lftr.wideiv, %n
  36. br i1 %exitcond, label %for.end, label %for.body
  37. for.end: ; preds = %for.inc, %entry
  38. ret void
  39. }
  40. ; This is the same as @test1, but without the dereferenceable attribute on %c.
  41. ; Without this attribute, we should not hoist the load of %c.
  42. ; CHECK-LABEL: @test2
  43. ; CHECK: if.then:
  44. ; CHECK: load i32, i32* %c, align 4
  45. define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 {
  46. entry:
  47. %cmp11 = icmp sgt i32 %n, 0
  48. br i1 %cmp11, label %for.body, label %for.end
  49. for.body: ; preds = %entry, %for.inc
  50. %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
  51. %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
  52. %0 = load i32, i32* %arrayidx, align 4
  53. %cmp1 = icmp sgt i32 %0, 0
  54. br i1 %cmp1, label %if.then, label %for.inc
  55. if.then: ; preds = %for.body
  56. %1 = load i32, i32* %c, align 4
  57. %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
  58. %2 = load i32, i32* %arrayidx3, align 4
  59. %mul = mul nsw i32 %2, %1
  60. store i32 %mul, i32* %arrayidx, align 4
  61. br label %for.inc
  62. for.inc: ; preds = %for.body, %if.then
  63. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  64. %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  65. %exitcond = icmp eq i32 %lftr.wideiv, %n
  66. br i1 %exitcond, label %for.end, label %for.body
  67. for.end: ; preds = %for.inc, %entry
  68. ret void
  69. }
  70. ; This test represents the following function:
  71. ; void test3(int * restrict a, int * restrict b, int c[static 3], int n) {
  72. ; for (int i = 0; i < n; ++i)
  73. ; if (a[i] > 0)
  74. ; a[i] = c[2]*b[i];
  75. ; }
  76. ; and we want to hoist the load of c[2] out of the loop. This can be done only
  77. ; because the dereferenceable attribute is on %c.
  78. ; CHECK-LABEL: @test3
  79. ; CHECK: load i32, i32* %c2, align 4
  80. ; CHECK: for.body:
  81. define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 {
  82. entry:
  83. %cmp11 = icmp sgt i32 %n, 0
  84. br i1 %cmp11, label %for.body, label %for.end
  85. for.body: ; preds = %entry, %for.inc
  86. %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
  87. %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
  88. %0 = load i32, i32* %arrayidx, align 4
  89. %cmp1 = icmp sgt i32 %0, 0
  90. br i1 %cmp1, label %if.then, label %for.inc
  91. if.then: ; preds = %for.body
  92. %c2 = getelementptr inbounds i32, i32* %c, i64 2
  93. %1 = load i32, i32* %c2, align 4
  94. %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
  95. %2 = load i32, i32* %arrayidx3, align 4
  96. %mul = mul nsw i32 %2, %1
  97. store i32 %mul, i32* %arrayidx, align 4
  98. br label %for.inc
  99. for.inc: ; preds = %for.body, %if.then
  100. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  101. %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  102. %exitcond = icmp eq i32 %lftr.wideiv, %n
  103. br i1 %exitcond, label %for.end, label %for.body
  104. for.end: ; preds = %for.inc, %entry
  105. ret void
  106. }
  107. ; This is the same as @test3, but with a dereferenceable attribute on %c with a
  108. ; size too small to cover c[2] (and so we should not hoist it).
  109. ; CHECK-LABEL: @test4
  110. ; CHECK: if.then:
  111. ; CHECK: load i32, i32* %c2, align 4
  112. define void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 {
  113. entry:
  114. %cmp11 = icmp sgt i32 %n, 0
  115. br i1 %cmp11, label %for.body, label %for.end
  116. for.body: ; preds = %entry, %for.inc
  117. %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
  118. %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
  119. %0 = load i32, i32* %arrayidx, align 4
  120. %cmp1 = icmp sgt i32 %0, 0
  121. br i1 %cmp1, label %if.then, label %for.inc
  122. if.then: ; preds = %for.body
  123. %c2 = getelementptr inbounds i32, i32* %c, i64 2
  124. %1 = load i32, i32* %c2, align 4
  125. %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
  126. %2 = load i32, i32* %arrayidx3, align 4
  127. %mul = mul nsw i32 %2, %1
  128. store i32 %mul, i32* %arrayidx, align 4
  129. br label %for.inc
  130. for.inc: ; preds = %for.body, %if.then
  131. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  132. %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  133. %exitcond = icmp eq i32 %lftr.wideiv, %n
  134. br i1 %exitcond, label %for.end, label %for.body
  135. for.end: ; preds = %for.inc, %entry
  136. ret void
  137. }
  138. ; This test represents the following function:
  139. ; void test1(int * __restrict__ a, int *b, int &c, int n) {
  140. ; if (c != null)
  141. ; for (int i = 0; i < n; ++i)
  142. ; if (a[i] > 0)
  143. ; a[i] = c*b[i];
  144. ; }
  145. ; and we want to hoist the load of %c out of the loop. This can be done only
  146. ; because the dereferenceable_or_null attribute is on %c and there is a null
  147. ; check on %c.
  148. ; CHECK-LABEL: @test5
  149. ; CHECK: load i32, i32* %c, align 4
  150. ; CHECK: for.body:
  151. define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
  152. entry:
  153. %not_null = icmp ne i32* %c, null
  154. br i1 %not_null, label %not.null, label %for.end
  155. not.null:
  156. %cmp11 = icmp sgt i32 %n, 0
  157. br i1 %cmp11, label %for.body, label %for.end
  158. for.body: ; preds = %not.null, %for.inc
  159. %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
  160. %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
  161. %0 = load i32, i32* %arrayidx, align 4
  162. %cmp1 = icmp sgt i32 %0, 0
  163. br i1 %cmp1, label %if.then, label %for.inc
  164. if.then: ; preds = %for.body
  165. %1 = load i32, i32* %c, align 4
  166. %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
  167. %2 = load i32, i32* %arrayidx3, align 4
  168. %mul = mul nsw i32 %2, %1
  169. store i32 %mul, i32* %arrayidx, align 4
  170. br label %for.inc
  171. for.inc: ; preds = %for.body, %if.then
  172. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  173. %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  174. %exitcond = icmp eq i32 %lftr.wideiv, %n
  175. br i1 %exitcond, label %for.end, label %for.body
  176. for.end: ; preds = %for.inc, %entry, %not.null
  177. ret void
  178. }
  179. ; This is the same as @test5, but without the null check on %c.
  180. ; Without this check, we should not hoist the load of %c.
  181. ; This test case has an icmp on c but the use of this comparison is
  182. ; not a branch.
  183. ; CHECK-LABEL: @test6
  184. ; CHECK: if.then:
  185. ; CHECK: load i32, i32* %c, align 4
  186. define i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 {
  187. entry:
  188. %not_null = icmp ne i32* %c, null
  189. %cmp11 = icmp sgt i32 %n, 0
  190. br i1 %cmp11, label %for.body, label %for.end
  191. for.body: ; preds = %entry, %for.inc
  192. %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
  193. %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
  194. %0 = load i32, i32* %arrayidx, align 4
  195. %cmp1 = icmp sgt i32 %0, 0
  196. br i1 %cmp1, label %if.then, label %for.inc
  197. if.then: ; preds = %for.body
  198. %1 = load i32, i32* %c, align 4
  199. %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
  200. %2 = load i32, i32* %arrayidx3, align 4
  201. %mul = mul nsw i32 %2, %1
  202. store i32 %mul, i32* %arrayidx, align 4
  203. br label %for.inc
  204. for.inc: ; preds = %for.body, %if.then
  205. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  206. %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  207. %exitcond = icmp eq i32 %lftr.wideiv, %n
  208. br i1 %exitcond, label %for.end, label %for.body
  209. for.end: ; preds = %for.inc, %entry
  210. ret i1 %not_null
  211. }
  212. ; This test represents the following function:
  213. ; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
  214. ; c = *cptr;
  215. ; for (int i = 0; i < n; ++i)
  216. ; if (a[i] > 0)
  217. ; a[i] = (*c)*b[i];
  218. ; }
  219. ; and we want to hoist the load of %c out of the loop. This can be done only
  220. ; because the dereferenceable meatdata on the c = *cptr load.
  221. ; CHECK-LABEL: @test7
  222. ; CHECK: load i32, i32* %c, align 4
  223. ; CHECK: for.body:
  224. define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
  225. entry:
  226. %c = load i32*, i32** %cptr, !dereferenceable !0
  227. %cmp11 = icmp sgt i32 %n, 0
  228. br i1 %cmp11, label %for.body, label %for.end
  229. for.body: ; preds = %entry, %for.inc
  230. %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
  231. %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
  232. %0 = load i32, i32* %arrayidx, align 4
  233. %cmp1 = icmp sgt i32 %0, 0
  234. br i1 %cmp1, label %if.then, label %for.inc
  235. if.then: ; preds = %for.body
  236. %1 = load i32, i32* %c, align 4
  237. %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
  238. %2 = load i32, i32* %arrayidx3, align 4
  239. %mul = mul nsw i32 %2, %1
  240. store i32 %mul, i32* %arrayidx, align 4
  241. br label %for.inc
  242. for.inc: ; preds = %for.body, %if.then
  243. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  244. %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  245. %exitcond = icmp eq i32 %lftr.wideiv, %n
  246. br i1 %exitcond, label %for.end, label %for.body
  247. for.end: ; preds = %for.inc, %entry
  248. ret void
  249. }
  250. ; This test represents the following function:
  251. ; void test1(int * __restrict__ a, int *b, int **cptr, int n) {
  252. ; c = *cptr;
  253. ; if (c != null)
  254. ; for (int i = 0; i < n; ++i)
  255. ; if (a[i] > 0)
  256. ; a[i] = (*c)*b[i];
  257. ; }
  258. ; and we want to hoist the load of %c out of the loop. This can be done only
  259. ; because the dereferenceable_or_null meatdata on the c = *cptr load and there
  260. ; is a null check on %c.
  261. ; CHECK-LABEL: @test8
  262. ; CHECK: load i32, i32* %c, align 4
  263. ; CHECK: for.body:
  264. define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
  265. entry:
  266. %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
  267. %not_null = icmp ne i32* %c, null
  268. br i1 %not_null, label %not.null, label %for.end
  269. not.null:
  270. %cmp11 = icmp sgt i32 %n, 0
  271. br i1 %cmp11, label %for.body, label %for.end
  272. for.body: ; preds = %not.null, %for.inc
  273. %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]
  274. %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
  275. %0 = load i32, i32* %arrayidx, align 4
  276. %cmp1 = icmp sgt i32 %0, 0
  277. br i1 %cmp1, label %if.then, label %for.inc
  278. if.then: ; preds = %for.body
  279. %1 = load i32, i32* %c, align 4
  280. %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
  281. %2 = load i32, i32* %arrayidx3, align 4
  282. %mul = mul nsw i32 %2, %1
  283. store i32 %mul, i32* %arrayidx, align 4
  284. br label %for.inc
  285. for.inc: ; preds = %for.body, %if.then
  286. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  287. %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  288. %exitcond = icmp eq i32 %lftr.wideiv, %n
  289. br i1 %exitcond, label %for.end, label %for.body
  290. for.end: ; preds = %for.inc, %entry, %not.null
  291. ret void
  292. }
  293. ; This is the same as @test8, but without the null check on %c.
  294. ; Without this check, we should not hoist the load of %c.
  295. ; CHECK-LABEL: @test9
  296. ; CHECK: if.then:
  297. ; CHECK: load i32, i32* %c, align 4
  298. define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 {
  299. entry:
  300. %c = load i32*, i32** %cptr, !dereferenceable_or_null !0
  301. %cmp11 = icmp sgt i32 %n, 0
  302. br i1 %cmp11, label %for.body, label %for.end
  303. for.body: ; preds = %entry, %for.inc
  304. %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
  305. %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
  306. %0 = load i32, i32* %arrayidx, align 4
  307. %cmp1 = icmp sgt i32 %0, 0
  308. br i1 %cmp1, label %if.then, label %for.inc
  309. if.then: ; preds = %for.body
  310. %1 = load i32, i32* %c, align 4
  311. %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
  312. %2 = load i32, i32* %arrayidx3, align 4
  313. %mul = mul nsw i32 %2, %1
  314. store i32 %mul, i32* %arrayidx, align 4
  315. br label %for.inc
  316. for.inc: ; preds = %for.body, %if.then
  317. %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  318. %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  319. %exitcond = icmp eq i32 %lftr.wideiv, %n
  320. br i1 %exitcond, label %for.end, label %for.body
  321. for.end: ; preds = %for.inc, %entry
  322. ret void
  323. }
  324. attributes #0 = { nounwind uwtable }
  325. !0 = !{i64 4}