scev-aa.ll 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. ; RUN: opt < %s -scev-aa -aa-eval -print-all-alias-modref-info \
  2. ; RUN: 2>&1 | FileCheck %s
  3. ; At the time of this writing, -basicaa misses the example of the form
  4. ; A[i+(j+1)] != A[i+j], which can arise from multi-dimensional array references,
  5. ; and the example of the form A[0] != A[i+1], where i+1 is known to be positive.
  6. target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64"
  7. ; p[i] and p[i+1] don't alias.
  8. ; CHECK: Function: loop: 3 pointers, 0 call sites
  9. ; CHECK: NoAlias: double* %pi, double* %pi.next
  10. define void @loop(double* nocapture %p, i64 %n) nounwind {
  11. entry:
  12. %j = icmp sgt i64 %n, 0
  13. br i1 %j, label %bb, label %return
  14. bb:
  15. %i = phi i64 [ 0, %entry ], [ %i.next, %bb ]
  16. %pi = getelementptr double, double* %p, i64 %i
  17. %i.next = add i64 %i, 1
  18. %pi.next = getelementptr double, double* %p, i64 %i.next
  19. %x = load double, double* %pi
  20. %y = load double, double* %pi.next
  21. %z = fmul double %x, %y
  22. store double %z, double* %pi
  23. %exitcond = icmp eq i64 %i.next, %n
  24. br i1 %exitcond, label %return, label %bb
  25. return:
  26. ret void
  27. }
  28. ; Slightly more involved: p[j][i], p[j][i+1], and p[j+1][i] don't alias.
  29. ; CHECK: Function: nestedloop: 4 pointers, 0 call sites
  30. ; CHECK: NoAlias: double* %pi.j, double* %pi.next.j
  31. ; CHECK: NoAlias: double* %pi.j, double* %pi.j.next
  32. ; CHECK: NoAlias: double* %pi.j.next, double* %pi.next.j
  33. define void @nestedloop(double* nocapture %p, i64 %m) nounwind {
  34. entry:
  35. %k = icmp sgt i64 %m, 0
  36. br i1 %k, label %guard, label %return
  37. guard:
  38. %l = icmp sgt i64 91, 0
  39. br i1 %l, label %outer.loop, label %return
  40. outer.loop:
  41. %j = phi i64 [ 0, %guard ], [ %j.next, %outer.latch ]
  42. br label %bb
  43. bb:
  44. %i = phi i64 [ 0, %outer.loop ], [ %i.next, %bb ]
  45. %i.next = add i64 %i, 1
  46. %e = add i64 %i, %j
  47. %pi.j = getelementptr double, double* %p, i64 %e
  48. %f = add i64 %i.next, %j
  49. %pi.next.j = getelementptr double, double* %p, i64 %f
  50. %x = load double, double* %pi.j
  51. %y = load double, double* %pi.next.j
  52. %z = fmul double %x, %y
  53. store double %z, double* %pi.j
  54. %o = add i64 %j, 91
  55. %g = add i64 %i, %o
  56. %pi.j.next = getelementptr double, double* %p, i64 %g
  57. %a = load double, double* %pi.j.next
  58. %b = fmul double %x, %a
  59. store double %b, double* %pi.j.next
  60. %exitcond = icmp eq i64 %i.next, 91
  61. br i1 %exitcond, label %outer.latch, label %bb
  62. outer.latch:
  63. %j.next = add i64 %j, 91
  64. %h = icmp eq i64 %j.next, %m
  65. br i1 %h, label %return, label %outer.loop
  66. return:
  67. ret void
  68. }
  69. ; Even more involved: same as nestedloop, but with a variable extent.
  70. ; When n is 1, p[j+1][i] does alias p[j][i+1], and there's no way to
  71. ; prove whether n will be greater than 1, so that relation will always
  72. ; by MayAlias. The loop is guarded by a n > 0 test though, so
  73. ; p[j+1][i] and p[j][i] can theoretically be determined to be NoAlias,
  74. ; however the analysis currently doesn't do that.
  75. ; TODO: Make the analysis smarter and turn that MayAlias into a NoAlias.
  76. ; CHECK: Function: nestedloop_more: 4 pointers, 0 call sites
  77. ; CHECK: NoAlias: double* %pi.j, double* %pi.next.j
  78. ; CHECK: MayAlias: double* %pi.j, double* %pi.j.next
  79. define void @nestedloop_more(double* nocapture %p, i64 %n, i64 %m) nounwind {
  80. entry:
  81. %k = icmp sgt i64 %m, 0
  82. br i1 %k, label %guard, label %return
  83. guard:
  84. %l = icmp sgt i64 %n, 0
  85. br i1 %l, label %outer.loop, label %return
  86. outer.loop:
  87. %j = phi i64 [ 0, %guard ], [ %j.next, %outer.latch ]
  88. br label %bb
  89. bb:
  90. %i = phi i64 [ 0, %outer.loop ], [ %i.next, %bb ]
  91. %i.next = add i64 %i, 1
  92. %e = add i64 %i, %j
  93. %pi.j = getelementptr double, double* %p, i64 %e
  94. %f = add i64 %i.next, %j
  95. %pi.next.j = getelementptr double, double* %p, i64 %f
  96. %x = load double, double* %pi.j
  97. %y = load double, double* %pi.next.j
  98. %z = fmul double %x, %y
  99. store double %z, double* %pi.j
  100. %o = add i64 %j, %n
  101. %g = add i64 %i, %o
  102. %pi.j.next = getelementptr double, double* %p, i64 %g
  103. %a = load double, double* %pi.j.next
  104. %b = fmul double %x, %a
  105. store double %b, double* %pi.j.next
  106. %exitcond = icmp eq i64 %i.next, %n
  107. br i1 %exitcond, label %outer.latch, label %bb
  108. outer.latch:
  109. %j.next = add i64 %j, %n
  110. %h = icmp eq i64 %j.next, %m
  111. br i1 %h, label %return, label %outer.loop
  112. return:
  113. ret void
  114. }
  115. ; ScalarEvolution expands field offsets into constants, which allows it to
  116. ; do aggressive analysis. Contrast this with BasicAA, which works by
  117. ; recognizing GEP idioms.
  118. %struct.A = type { %struct.B, i32, i32 }
  119. %struct.B = type { double }
  120. ; CHECK: Function: foo: 7 pointers, 0 call sites
  121. ; CHECK: NoAlias: %struct.B* %B, i32* %Z
  122. ; CHECK: NoAlias: %struct.B* %B, %struct.B* %C
  123. ; CHECK: MustAlias: %struct.B* %C, i32* %Z
  124. ; CHECK: NoAlias: %struct.B* %B, i32* %X
  125. ; CHECK: MustAlias: i32* %X, i32* %Z
  126. ; CHECK: MustAlias: %struct.B* %C, i32* %Y
  127. ; CHECK: MustAlias: i32* %X, i32* %Y
  128. define void @foo() {
  129. entry:
  130. %A = alloca %struct.A
  131. %B = getelementptr %struct.A, %struct.A* %A, i32 0, i32 0
  132. %Q = bitcast %struct.B* %B to %struct.A*
  133. %Z = getelementptr %struct.A, %struct.A* %Q, i32 0, i32 1
  134. %C = getelementptr %struct.B, %struct.B* %B, i32 1
  135. %X = bitcast %struct.B* %C to i32*
  136. %Y = getelementptr %struct.A, %struct.A* %A, i32 0, i32 1
  137. ret void
  138. }
  139. ; CHECK: Function: bar: 7 pointers, 0 call sites
  140. ; CHECK: NoAlias: %struct.B* %N, i32* %P
  141. ; CHECK: NoAlias: %struct.B* %N, %struct.B* %R
  142. ; CHECK: MustAlias: %struct.B* %R, i32* %P
  143. ; CHECK: NoAlias: %struct.B* %N, i32* %W
  144. ; CHECK: MustAlias: i32* %P, i32* %W
  145. ; CHECK: MustAlias: %struct.B* %R, i32* %V
  146. ; CHECK: MustAlias: i32* %V, i32* %W
  147. define void @bar() {
  148. %M = alloca %struct.A
  149. %N = getelementptr %struct.A, %struct.A* %M, i32 0, i32 0
  150. %O = bitcast %struct.B* %N to %struct.A*
  151. %P = getelementptr %struct.A, %struct.A* %O, i32 0, i32 1
  152. %R = getelementptr %struct.B, %struct.B* %N, i32 1
  153. %W = bitcast %struct.B* %R to i32*
  154. %V = getelementptr %struct.A, %struct.A* %M, i32 0, i32 1
  155. ret void
  156. }
  157. ; CHECK: Function: nonnegative: 2 pointers, 0 call sites
  158. ; CHECK: NoAlias: i64* %arrayidx, i64* %p
  159. define void @nonnegative(i64* %p) nounwind {
  160. entry:
  161. br label %for.body
  162. for.body: ; preds = %entry, %for.body
  163. %i = phi i64 [ %inc, %for.body ], [ 0, %entry ] ; <i64> [#uses=2]
  164. %inc = add nsw i64 %i, 1 ; <i64> [#uses=2]
  165. %arrayidx = getelementptr inbounds i64, i64* %p, i64 %inc
  166. store i64 0, i64* %arrayidx
  167. %tmp6 = load i64, i64* %p ; <i64> [#uses=1]
  168. %cmp = icmp slt i64 %inc, %tmp6 ; <i1> [#uses=1]
  169. br i1 %cmp, label %for.body, label %for.end
  170. for.end: ; preds = %for.body, %entry
  171. ret void
  172. }
  173. ; CHECK: 14 no alias responses
  174. ; CHECK: 26 may alias responses
  175. ; CHECK: 18 must alias responses