Home | History | Annotate | Download | only in LICM
      1 ; RUN: opt -S -basicaa -licm < %s | FileCheck %s
      2 ; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
      3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
      4 target triple = "x86_64-unknown-linux-gnu"
      5 
      6 declare void @f() nounwind
      7 
      8 ; constant fold on first ieration
      9 define i32 @test1(i32* noalias nocapture readonly %a) nounwind uwtable {
     10 ; CHECK-LABEL: @test1(
     11 entry:
     12 ; CHECK: %i1 = load i32, i32* %a, align 4
     13 ; CHECK-NEXT: br label %for.body
     14   br label %for.body
     15 
     16 for.body:
     17   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
     18   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
     19   %r.chk = icmp ult i32 %iv, 2000
     20   br i1 %r.chk, label %continue, label %fail
     21 continue:
     22   %i1 = load i32, i32* %a, align 4
     23   %add = add nsw i32 %i1, %acc
     24   %inc = add nuw nsw i32 %iv, 1
     25   %exitcond = icmp eq i32 %inc, 1000
     26   br i1 %exitcond, label %for.cond.cleanup, label %for.body
     27 
     28 for.cond.cleanup:
     29   ret i32 %add
     30 
     31 fail:
     32   call void @f()
     33   ret i32 -1
     34 }
     35 
     36 ; Same as test1, but with a floating point IR and fcmp
     37 define i32 @test_fcmp(i32* noalias nocapture readonly %a) nounwind uwtable {
     38 ; CHECK-LABEL: @test_fcmp(
     39 entry:
     40 ; CHECK: %i1 = load i32, i32* %a, align 4
     41 ; CHECK-NEXT: br label %for.body
     42   br label %for.body
     43 
     44 for.body:
     45   %iv = phi float [ 0.0, %entry ], [ %inc, %continue ]
     46   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
     47   %r.chk = fcmp olt float %iv, 2000.0
     48   br i1 %r.chk, label %continue, label %fail
     49 continue:
     50   %i1 = load i32, i32* %a, align 4
     51   %add = add nsw i32 %i1, %acc
     52   %inc = fadd float %iv, 1.0
     53   %exitcond = fcmp ogt float %inc, 1000.0
     54   br i1 %exitcond, label %for.cond.cleanup, label %for.body
     55 
     56 for.cond.cleanup:
     57   ret i32 %add
     58 
     59 fail:
     60   call void @f()
     61   ret i32 -1
     62 }
     63 
     64 ; Count down from a.length w/entry guard
     65 ; TODO: currently unable to prove the following:
     66 ; ule i32 (add nsw i32 %len, -1), %len where len is [0, 512]
     67 define i32 @test2(i32* noalias nocapture readonly %a) nounwind uwtable {
     68 ; CHECK-LABEL: @test2(
     69 entry:
     70   %len = load i32, i32* %a, align 4, !range !{i32 0, i32 512}
     71   %is.non.pos = icmp eq i32 %len, 0
     72   br i1 %is.non.pos, label %fail, label %preheader
     73 preheader:
     74   %lenminusone = add nsw i32 %len, -1
     75   br label %for.body
     76 for.body:
     77   %iv = phi i32 [ %lenminusone, %preheader ], [ %dec, %continue ]
     78   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
     79   %r.chk = icmp ule i32 %iv, %len
     80   br i1 %r.chk, label %continue, label %fail
     81 continue:
     82 ; CHECK-LABEL: continue
     83 ; CHECK: %i1 = load i32, i32* %a, align 4
     84   %i1 = load i32, i32* %a, align 4
     85   %add = add nsw i32 %i1, %acc
     86   %dec = add nsw i32 %iv, -1
     87   %exitcond = icmp eq i32 %dec, 0
     88   br i1 %exitcond, label %for.cond.cleanup, label %for.body
     89 
     90 for.cond.cleanup:
     91   ret i32 %add
     92 
     93 fail:
     94   call void @f()
     95   ret i32 -1
     96 }
     97 
     98 ; trivially true for zero
     99 define i32 @test3(i32* noalias nocapture readonly %a) nounwind uwtable {
    100 ; CHECK-LABEL: @test3(
    101 entry:
    102   %len = load i32, i32* %a, align 4, !range !{i32 0, i32 512}
    103   %is.zero = icmp eq i32 %len, 0
    104   br i1 %is.zero, label %fail, label %preheader
    105 preheader:
    106 ; CHECK: %i1 = load i32, i32* %a, align 4
    107 ; CHECK-NEXT: br label %for.body
    108   br label %for.body
    109 for.body:
    110   %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]
    111   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
    112   %r.chk = icmp ule i32 %iv, %len
    113   br i1 %r.chk, label %continue, label %fail
    114 continue:
    115   %i1 = load i32, i32* %a, align 4
    116   %add = add nsw i32 %i1, %acc
    117   %inc = add nuw nsw i32 %iv, 1
    118   %exitcond = icmp eq i32 %inc, 1000
    119   br i1 %exitcond, label %for.cond.cleanup, label %for.body
    120 
    121 for.cond.cleanup:
    122   ret i32 %add
    123 
    124 fail:
    125   call void @f()
    126   ret i32 -1
    127 }
    128 
    129 ; requires fact length is non-zero
    130 ; TODO: IsKnownNonNullFromDominatingConditions is currently only be done for
    131 ; pointers; should handle integers too
    132 define i32 @test4(i32* noalias nocapture readonly %a) nounwind uwtable {
    133 ; CHECK-LABEL: @test4(
    134 entry:
    135   %len = load i32, i32* %a, align 4, !range !{i32 0, i32 512}
    136   %is.zero = icmp eq i32 %len, 0
    137   br i1 %is.zero, label %fail, label %preheader
    138 preheader:
    139   br label %for.body
    140 for.body:
    141   %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]
    142   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
    143   %r.chk = icmp ult i32 %iv, %len
    144   br i1 %r.chk, label %continue, label %fail
    145 continue:
    146 ; CHECK-LABEL: continue
    147 ; CHECK: %i1 = load i32, i32* %a, align 4
    148   %i1 = load i32, i32* %a, align 4
    149   %add = add nsw i32 %i1, %acc
    150   %inc = add nuw nsw i32 %iv, 1
    151   %exitcond = icmp eq i32 %inc, 1000
    152   br i1 %exitcond, label %for.cond.cleanup, label %for.body
    153 
    154 for.cond.cleanup:
    155   ret i32 %add
    156 
    157 fail:
    158   call void @f()
    159   ret i32 -1
    160 }
    161 
    162 ; variation on test1 with branch swapped
    163 define i32 @test-brswap(i32* noalias nocapture readonly %a) nounwind uwtable {
    164 ; CHECK-LABEL: @test-brswap(
    165 entry:
    166 ; CHECK: %i1 = load i32, i32* %a, align 4
    167 ; CHECK-NEXT: br label %for.body
    168   br label %for.body
    169 
    170 for.body:
    171   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
    172   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
    173   %r.chk = icmp ugt i32 %iv, 2000
    174   br i1 %r.chk, label %fail, label %continue
    175 continue:
    176   %i1 = load i32, i32* %a, align 4
    177   %add = add nsw i32 %i1, %acc
    178   %inc = add nuw nsw i32 %iv, 1
    179   %exitcond = icmp eq i32 %inc, 1000
    180   br i1 %exitcond, label %for.cond.cleanup, label %for.body
    181 
    182 for.cond.cleanup:
    183   ret i32 %add
    184 
    185 fail:
    186   call void @f()
    187   ret i32 -1
    188 }
    189 
    190 define i32 @test-nonphi(i32* noalias nocapture readonly %a) nounwind uwtable {
    191 ; CHECK-LABEL: @test-nonphi(
    192 entry:
    193   br label %for.body
    194 
    195 for.body:
    196 ; CHECK-LABEL: continue
    197 ; CHECK: %i1 = load i32, i32* %a, align 4
    198   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
    199   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
    200   %xor = xor i32 %iv, 72
    201   %r.chk = icmp ugt i32 %xor, 2000
    202   br i1 %r.chk, label %fail, label %continue
    203 continue:
    204   %i1 = load i32, i32* %a, align 4
    205   %add = add nsw i32 %i1, %acc
    206   %inc = add nuw nsw i32 %iv, 1
    207   %exitcond = icmp eq i32 %inc, 1000
    208   br i1 %exitcond, label %for.cond.cleanup, label %for.body
    209 
    210 for.cond.cleanup:
    211   ret i32 %add
    212 
    213 fail:
    214   call void @f()
    215   ret i32 -1
    216 }
    217 
    218 define i32 @test-wrongphi(i32* noalias nocapture readonly %a) nounwind uwtable {
    219 ; CHECK-LABEL: @test-wrongphi(
    220 entry:
    221   br label %for.body
    222   
    223 for.body:
    224   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
    225   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
    226   %cond = icmp ult i32 %iv, 500
    227   br i1 %cond, label %dummy_block1, label %dummy_block2
    228 
    229 dummy_block1:
    230   br label %dummy_block2
    231 
    232 dummy_block2:
    233   %wrongphi = phi i32 [11, %for.body], [12, %dummy_block1]
    234   %r.chk = icmp ugt i32 %wrongphi, 2000
    235   br i1 %r.chk, label %fail, label %continue
    236 continue:
    237 ; CHECK-LABEL: continue
    238 ; CHECK: %i1 = load i32, i32* %a, align 4
    239   %i1 = load i32, i32* %a, align 4
    240   %add = add nsw i32 %i1, %acc
    241   %inc = add nuw nsw i32 %iv, 1
    242   %exitcond = icmp eq i32 %inc, 1000
    243   br i1 %exitcond, label %for.cond.cleanup, label %for.body
    244 
    245 for.cond.cleanup:
    246   ret i32 %add
    247 
    248 fail:
    249   call void @f()
    250   ret i32 -1
    251 }
    252 
    253 ; This works because loop-simplify is run implicitly, but test for it anyways
    254 define i32 @test-multiple-latch(i32* noalias nocapture readonly %a) nounwind uwtable {
    255 ; CHECK-LABEL: @test-multiple-latch(
    256 entry:
    257 ; CHECK: %i1 = load i32, i32* %a, align 4
    258 ; CHECK-NEXT: br label %for.body
    259   br label %for.body
    260 
    261 for.body:
    262   %iv = phi i32 [ 0, %entry ], [ %inc, %continue1 ], [ %inc, %continue2 ]
    263   %acc = phi i32 [ 0, %entry ], [ %add, %continue1 ], [ %add, %continue2 ]
    264   %r.chk = icmp ult i32 %iv, 2000
    265   br i1 %r.chk, label %continue1, label %fail
    266 continue1:
    267   %i1 = load i32, i32* %a, align 4
    268   %add = add nsw i32 %i1, %acc
    269   %inc = add nuw nsw i32 %iv, 1
    270   %cmp = icmp eq i32 %add, 0
    271   br i1 %cmp, label %continue2, label %for.body
    272 continue2:
    273   %exitcond = icmp eq i32 %inc, 1000
    274   br i1 %exitcond, label %for.cond.cleanup, label %for.body
    275 
    276 for.cond.cleanup:
    277   ret i32 %add
    278 
    279 fail:
    280   call void @f()
    281   ret i32 -1
    282 }
    283