elim-extend.ll 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. ; RUN: opt < %s -indvars -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"
  3. ; IV with constant start, preinc and postinc sign extends, with and without NSW.
  4. ; IV rewrite only removes one sext. WidenIVs removes all three.
  5. define void @postincConstIV(i8* %base, i32 %limit) nounwind {
  6. entry:
  7. br label %loop
  8. ; CHECK: loop:
  9. ; CHECK-NOT: sext
  10. ; CHECK: exit:
  11. loop:
  12. %iv = phi i32 [ %postiv, %loop ], [ 0, %entry ]
  13. %ivnsw = phi i32 [ %postivnsw, %loop ], [ 0, %entry ]
  14. %preofs = sext i32 %iv to i64
  15. %preadr = getelementptr i8, i8* %base, i64 %preofs
  16. store i8 0, i8* %preadr
  17. %postiv = add i32 %iv, 1
  18. %postofs = sext i32 %postiv to i64
  19. %postadr = getelementptr i8, i8* %base, i64 %postofs
  20. store i8 0, i8* %postadr
  21. %postivnsw = add nsw i32 %ivnsw, 1
  22. %postofsnsw = sext i32 %postivnsw to i64
  23. %postadrnsw = getelementptr i8, i8* %base, i64 %postofsnsw
  24. store i8 0, i8* %postadrnsw
  25. %cond = icmp sgt i32 %limit, %iv
  26. br i1 %cond, label %loop, label %exit
  27. exit:
  28. br label %return
  29. return:
  30. ret void
  31. }
  32. ; IV with nonconstant start, preinc and postinc sign extends,
  33. ; with and without NSW.
  34. ; As with postincConstIV, WidenIVs removes all three sexts.
  35. define void @postincVarIV(i8* %base, i32 %init, i32 %limit) nounwind {
  36. entry:
  37. %precond = icmp sgt i32 %limit, %init
  38. br i1 %precond, label %loop, label %return
  39. ; CHECK: loop:
  40. ; CHECK-NOT: sext
  41. ; CHECK: exit:
  42. loop:
  43. %iv = phi i32 [ %postiv, %loop ], [ %init, %entry ]
  44. %ivnsw = phi i32 [ %postivnsw, %loop ], [ %init, %entry ]
  45. %preofs = sext i32 %iv to i64
  46. %preadr = getelementptr i8, i8* %base, i64 %preofs
  47. store i8 0, i8* %preadr
  48. %postiv = add i32 %iv, 1
  49. %postofs = sext i32 %postiv to i64
  50. %postadr = getelementptr i8, i8* %base, i64 %postofs
  51. store i8 0, i8* %postadr
  52. %postivnsw = add nsw i32 %ivnsw, 1
  53. %postofsnsw = sext i32 %postivnsw to i64
  54. %postadrnsw = getelementptr i8, i8* %base, i64 %postofsnsw
  55. store i8 0, i8* %postadrnsw
  56. %cond = icmp sgt i32 %limit, %postiv
  57. br i1 %cond, label %loop, label %exit
  58. exit:
  59. br label %return
  60. return:
  61. ret void
  62. }
  63. ; Test sign extend elimination in the inner and outer loop.
  64. ; %outercount is straightforward to widen, besides being in an outer loop.
  65. ; %innercount is currently blocked by lcssa, so is not widened.
  66. ; %inneriv can be widened only after proving it has no signed-overflow
  67. ; based on the loop test.
  68. define void @nestedIV(i8* %address, i32 %limit) nounwind {
  69. entry:
  70. %limitdec = add i32 %limit, -1
  71. br label %outerloop
  72. ; CHECK: outerloop:
  73. ;
  74. ; Eliminate %ofs1 after widening outercount.
  75. ; CHECK-NOT: sext
  76. ; CHECK: getelementptr
  77. ;
  78. ; IV rewriting hoists a gep into this block. We don't like that.
  79. ; CHECK-NOT: getelementptr
  80. outerloop:
  81. %outercount = phi i32 [ %outerpostcount, %outermerge ], [ 0, %entry ]
  82. %innercount = phi i32 [ %innercount.merge, %outermerge ], [ 0, %entry ]
  83. %outercountdec = add i32 %outercount, -1
  84. %ofs1 = sext i32 %outercountdec to i64
  85. %adr1 = getelementptr i8, i8* %address, i64 %ofs1
  86. store i8 0, i8* %adr1
  87. br label %innerpreheader
  88. innerpreheader:
  89. %innerprecmp = icmp sgt i32 %limitdec, %innercount
  90. br i1 %innerprecmp, label %innerloop, label %outermerge
  91. ; CHECK: innerloop:
  92. ;
  93. ; Eliminate %ofs2 after widening inneriv.
  94. ; Eliminate %ofs3 after normalizing sext(innerpostiv)
  95. ; CHECK-NOT: sext
  96. ; CHECK: getelementptr
  97. ;
  98. ; FIXME: We should check that indvars does not increase the number of
  99. ; IVs in this loop. sext elimination plus LFTR currently results in 2 final
  100. ; IVs. Waiting to remove LFTR.
  101. innerloop:
  102. %inneriv = phi i32 [ %innerpostiv, %innerloop ], [ %innercount, %innerpreheader ]
  103. %innerpostiv = add i32 %inneriv, 1
  104. %ofs2 = sext i32 %inneriv to i64
  105. %adr2 = getelementptr i8, i8* %address, i64 %ofs2
  106. store i8 0, i8* %adr2
  107. %ofs3 = sext i32 %innerpostiv to i64
  108. %adr3 = getelementptr i8, i8* %address, i64 %ofs3
  109. store i8 0, i8* %adr3
  110. %innercmp = icmp sgt i32 %limitdec, %innerpostiv
  111. br i1 %innercmp, label %innerloop, label %innerexit
  112. innerexit:
  113. %innercount.lcssa = phi i32 [ %innerpostiv, %innerloop ]
  114. br label %outermerge
  115. ; CHECK: outermerge:
  116. ;
  117. ; Eliminate %ofs4 after widening outercount
  118. ; CHECK-NOT: sext
  119. ; CHECK: getelementptr
  120. ;
  121. ; TODO: Eliminate %ofs5 after removing lcssa
  122. outermerge:
  123. %innercount.merge = phi i32 [ %innercount.lcssa, %innerexit ], [ %innercount, %innerpreheader ]
  124. %ofs4 = sext i32 %outercount to i64
  125. %adr4 = getelementptr i8, i8* %address, i64 %ofs4
  126. store i8 0, i8* %adr4
  127. %ofs5 = sext i32 %innercount.merge to i64
  128. %adr5 = getelementptr i8, i8* %address, i64 %ofs5
  129. store i8 0, i8* %adr5
  130. %outerpostcount = add i32 %outercount, 1
  131. %tmp47 = icmp slt i32 %outerpostcount, %limit
  132. br i1 %tmp47, label %outerloop, label %return
  133. return:
  134. ret void
  135. }