lftr-reuse.ll 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. ; RUN: opt < %s -indvars -S | FileCheck %s
  2. ;
  3. ; Make sure that indvars can perform LFTR without a canonical IV.
  4. 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"
  5. ; Perform LFTR using the original pointer-type IV.
  6. ; for(char* p = base; p < base + n; ++p) {
  7. ; *p = p-base;
  8. ; }
  9. define void @ptriv(i8* %base, i32 %n) nounwind {
  10. entry:
  11. %idx.ext = sext i32 %n to i64
  12. %add.ptr = getelementptr inbounds i8, i8* %base, i64 %idx.ext
  13. %cmp1 = icmp ult i8* %base, %add.ptr
  14. br i1 %cmp1, label %for.body, label %for.end
  15. ; CHECK: for.body:
  16. ; CHECK: phi i8*
  17. ; CHECK-NOT: phi
  18. ; CHECK-NOT: add
  19. ; CHECK: icmp ne i8*
  20. ; CHECK: br i1
  21. for.body:
  22. %p.02 = phi i8* [ %base, %entry ], [ %incdec.ptr, %for.body ]
  23. ; cruft to make the IV useful
  24. %sub.ptr.lhs.cast = ptrtoint i8* %p.02 to i64
  25. %sub.ptr.rhs.cast = ptrtoint i8* %base to i64
  26. %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
  27. %conv = trunc i64 %sub.ptr.sub to i8
  28. store i8 %conv, i8* %p.02
  29. %incdec.ptr = getelementptr inbounds i8, i8* %p.02, i32 1
  30. %cmp = icmp ult i8* %incdec.ptr, %add.ptr
  31. br i1 %cmp, label %for.body, label %for.end
  32. for.end:
  33. ret void
  34. }
  35. ; This test checks that SCEVExpander can handle an outer loop that has been
  36. ; simplified, and as a result the inner loop's exit test will be rewritten.
  37. define void @expandOuterRecurrence(i32 %arg) nounwind {
  38. entry:
  39. %sub1 = sub nsw i32 %arg, 1
  40. %cmp1 = icmp slt i32 0, %sub1
  41. br i1 %cmp1, label %outer, label %exit
  42. ; CHECK: outer:
  43. ; CHECK: icmp slt
  44. outer:
  45. %i = phi i32 [ 0, %entry ], [ %i.inc, %outer.inc ]
  46. %sub2 = sub nsw i32 %arg, %i
  47. %sub3 = sub nsw i32 %sub2, 1
  48. %cmp2 = icmp slt i32 0, %sub3
  49. br i1 %cmp2, label %inner.ph, label %outer.inc
  50. inner.ph:
  51. br label %inner
  52. ; CHECK: inner:
  53. ; CHECK: br i1
  54. inner:
  55. %j = phi i32 [ 0, %inner.ph ], [ %j.inc, %inner ]
  56. %j.inc = add nsw i32 %j, 1
  57. %cmp3 = icmp slt i32 %j.inc, %sub3
  58. br i1 %cmp3, label %inner, label %outer.inc
  59. ; CHECK: outer.inc:
  60. ; CHECK: icmp ne
  61. ; CHECK: br i1
  62. outer.inc:
  63. %i.inc = add nsw i32 %i, 1
  64. %cmp4 = icmp slt i32 %i.inc, %sub1
  65. br i1 %cmp4, label %outer, label %exit
  66. exit:
  67. ret void
  68. }
  69. ; Force SCEVExpander to look for an existing well-formed phi.
  70. ; Perform LFTR without generating extra preheader code.
  71. define void @guardedloop([0 x double]* %matrix, [0 x double]* %vector,
  72. i32 %irow, i32 %ilead) nounwind {
  73. ; CHECK: entry:
  74. ; CHECK-NOT: zext
  75. ; CHECK-NOT: add
  76. ; CHECK: loop:
  77. ; CHECK: phi i64
  78. ; CHECK: phi i64
  79. ; CHECK-NOT: phi
  80. ; CHECK: icmp ne
  81. ; CHECK: br i1
  82. entry:
  83. %cmp = icmp slt i32 1, %irow
  84. br i1 %cmp, label %loop, label %return
  85. loop:
  86. %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
  87. %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
  88. %diagidx = add nsw i32 %rowidx, %i
  89. %diagidxw = sext i32 %diagidx to i64
  90. %matrixp = getelementptr inbounds [0 x double], [0 x double]* %matrix, i32 0, i64 %diagidxw
  91. %v1 = load double, double* %matrixp
  92. %iw = sext i32 %i to i64
  93. %vectorp = getelementptr inbounds [0 x double], [0 x double]* %vector, i32 0, i64 %iw
  94. %v2 = load double, double* %vectorp
  95. %row.inc = add nsw i32 %rowidx, %ilead
  96. %i.inc = add nsw i32 %i, 1
  97. %cmp196 = icmp slt i32 %i.inc, %irow
  98. br i1 %cmp196, label %loop, label %return
  99. return:
  100. ret void
  101. }
  102. ; Avoid generating extra code to materialize a trip count. Skip LFTR.
  103. define void @unguardedloop([0 x double]* %matrix, [0 x double]* %vector,
  104. i32 %irow, i32 %ilead) nounwind {
  105. entry:
  106. br label %loop
  107. ; CHECK: entry:
  108. ; CHECK-NOT: zext
  109. ; CHECK-NOT: add
  110. ; CHECK: loop:
  111. ; CHECK: phi i64
  112. ; CHECK: phi i64
  113. ; CHECK-NOT: phi
  114. ; CHECK: icmp slt
  115. ; CHECK: br i1
  116. loop:
  117. %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ]
  118. %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
  119. %diagidx = add nsw i32 %rowidx, %i
  120. %diagidxw = sext i32 %diagidx to i64
  121. %matrixp = getelementptr inbounds [0 x double], [0 x double]* %matrix, i32 0, i64 %diagidxw
  122. %v1 = load double, double* %matrixp
  123. %iw = sext i32 %i to i64
  124. %vectorp = getelementptr inbounds [0 x double], [0 x double]* %vector, i32 0, i64 %iw
  125. %v2 = load double, double* %vectorp
  126. %row.inc = add nsw i32 %rowidx, %ilead
  127. %i.inc = add nsw i32 %i, 1
  128. %cmp196 = icmp slt i32 %i.inc, %irow
  129. br i1 %cmp196, label %loop, label %return
  130. return:
  131. ret void
  132. }
  133. ; Remove %i which is only used by the exit test.
  134. ; Verify that SCEV can still compute a backedge count from the sign
  135. ; extended %n, used for pointer comparison by LFTR.
  136. ;
  137. ; TODO: Fix for PR13371 currently makes this impossible. See
  138. ; IndVarSimplify.cpp hasConcreteDef(). We may want to change to undef rules.
  139. define void @geplftr(i8* %base, i32 %x, i32 %y, i32 %n) nounwind {
  140. entry:
  141. %x.ext = sext i32 %x to i64
  142. %add.ptr = getelementptr inbounds i8, i8* %base, i64 %x.ext
  143. %y.ext = sext i32 %y to i64
  144. %add.ptr10 = getelementptr inbounds i8, i8* %add.ptr, i64 %y.ext
  145. %lim = add i32 %x, %n
  146. %cmp.ph = icmp ult i32 %x, %lim
  147. br i1 %cmp.ph, label %loop, label %exit
  148. ; CHECK-LABEL: @geplftr(
  149. ; CHECK: loop:
  150. ; CHECK: phi i8*
  151. ; DISABLE-NOT: phi // This check is currently disabled
  152. ; CHECK: getelementptr
  153. ; CHECK: store
  154. ; DISABLE: icmp ne i8* // This check is currently disabled
  155. ; CHECK: br i1
  156. loop:
  157. %i = phi i32 [ %x, %entry ], [ %inc, %loop ]
  158. %aptr = phi i8* [ %add.ptr10, %entry ], [ %incdec.ptr, %loop ]
  159. %incdec.ptr = getelementptr inbounds i8, i8* %aptr, i32 1
  160. store i8 3, i8* %aptr
  161. %inc = add i32 %i, 1
  162. %cmp = icmp ult i32 %inc, %lim
  163. br i1 %cmp, label %loop, label %exit
  164. exit:
  165. ret void
  166. }
  167. ; Exercise backedge taken count verification with a never-taken loop.
  168. define void @nevertaken() nounwind uwtable ssp {
  169. entry:
  170. br label %loop
  171. ; CHECK-LABEL: @nevertaken(
  172. ; CHECK: loop:
  173. ; CHECK-NOT: phi
  174. ; CHECK-NOT: add
  175. ; CHECK-NOT: icmp
  176. ; CHECK: exit:
  177. loop:
  178. %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
  179. %inc = add nsw i32 %i, 1
  180. %cmp = icmp sle i32 %inc, 0
  181. br i1 %cmp, label %loop, label %exit
  182. exit:
  183. ret void
  184. }
  185. ; Test LFTR on an IV whose recurrence start is a non-unit pointer type.
  186. define void @aryptriv([256 x i8]* %base, i32 %n) nounwind {
  187. entry:
  188. %ivstart = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 0
  189. %ivend = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 %n
  190. %cmp.ph = icmp ult i8* %ivstart, %ivend
  191. br i1 %cmp.ph, label %loop, label %exit
  192. ; CHECK: loop:
  193. ; CHECK: phi i8*
  194. ; CHECK-NOT: phi
  195. ; CHECK: getelementptr
  196. ; CHECK: store
  197. ; CHECK: icmp ne i8*
  198. ; CHECK: br i1
  199. loop:
  200. %aptr = phi i8* [ %ivstart, %entry ], [ %incdec.ptr, %loop ]
  201. %incdec.ptr = getelementptr inbounds i8, i8* %aptr, i32 1
  202. store i8 3, i8* %aptr
  203. %cmp = icmp ult i8* %incdec.ptr, %ivend
  204. br i1 %cmp, label %loop, label %exit
  205. exit:
  206. ret void
  207. }