Home | History | Annotate | Download | only in LICM
      1 ; RUN: opt -S -licm < %s | FileCheck %s
      2 ; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
      3 
      4 declare void @use_nothrow(i64 %a) nounwind
      5 declare void @use(i64 %a)
      6 declare void @maythrow()
      7 
      8 define void @nothrow(i64 %x, i64 %y, i1* %cond) {
      9 ; CHECK-LABEL: nothrow
     10 ; CHECK-LABEL: entry
     11 ; CHECK: %div = udiv i64 %x, %y
     12 ; CHECK-LABEL: loop
     13 ; CHECK: call void @use_nothrow(i64 %div)
     14 entry:
     15   br label %loop
     16 
     17 loop:                                         ; preds = %entry, %for.inc
     18   %div = udiv i64 %x, %y
     19   br label %loop2
     20 
     21 loop2:
     22   call void @use_nothrow(i64 %div)
     23   br label %loop
     24 }
     25 
     26 ; The udiv is guarantee to execute if the loop is
     27 define void @throw_header_after(i64 %x, i64 %y, i1* %cond) {
     28 ; CHECK-LABEL: throw_header_after
     29 ; CHECK: %div = udiv i64 %x, %y
     30 ; CHECK-LABEL: loop
     31 ; CHECK: call void @use(i64 %div)
     32 entry:
     33   br label %loop
     34 
     35 loop:                                         ; preds = %entry, %for.inc
     36   %div = udiv i64 %x, %y
     37   call void @use(i64 %div)
     38   br label %loop
     39 }
     40 define void @throw_header_after_rec(i64* %xp, i64* %yp, i1* %cond) {
     41 ; CHECK-LABEL: throw_header_after_rec
     42 ; CHECK: %x = load i64, i64* %xp
     43 ; CHECK: %y = load i64, i64* %yp
     44 ; CHECK: %div = udiv i64 %x, %y
     45 ; CHECK-LABEL: loop
     46 ; CHECK: call void @use(i64 %div)
     47 entry:
     48   br label %loop
     49 
     50 loop:                                         ; preds = %entry, %for.inc
     51   %x = load i64, i64* %xp
     52   %y = load i64, i64* %yp
     53   %div = udiv i64 %x, %y
     54   call void @use(i64 %div) readonly
     55   br label %loop
     56 }
     57 
     58 ; Similiar to the above, but the hoistable instruction (%y in this case)
     59 ; happens not to be the first instruction in the block.
     60 define void @throw_header_after_nonfirst(i64* %xp, i64* %yp, i1* %cond) {
     61 ; CHECK-LABEL: throw_header_after_nonfirst
     62 ; CHECK: %y = load i64, i64* %yp
     63 ; CHECK-LABEL: loop
     64 ; CHECK: %x = load i64, i64* %gep
     65 ; CHECK: %div = udiv i64 %x, %y
     66 ; CHECK: call void @use(i64 %div)
     67 entry:
     68   br label %loop
     69 
     70 loop:                                         ; preds = %entry, %for.inc
     71   %iv = phi i64 [0, %entry], [%div, %loop]
     72   %gep = getelementptr i64, i64* %xp, i64 %iv
     73   %x = load i64, i64* %gep
     74   %y = load i64, i64* %yp
     75   %div = udiv i64 %x, %y
     76   call void @use(i64 %div) readonly
     77   br label %loop
     78 }
     79 
     80 ; Negative test
     81 define void @throw_header_before(i64 %x, i64 %y, i1* %cond) {
     82 ; CHECK-LABEL: throw_header_before
     83 ; CHECK-LABEL: loop
     84 ; CHECK: %div = udiv i64 %x, %y
     85 ; CHECK: call void @use(i64 %div)
     86 entry:
     87   br label %loop
     88 
     89 loop:                                         ; preds = %entry, %for.inc
     90   call void @maythrow()
     91   %div = udiv i64 %x, %y
     92   call void @use(i64 %div)
     93   br label %loop
     94 }
     95 
     96 ; The header is known no throw, but the loop is not.  We can
     97 ; still lift out of the header.
     98 define void @nothrow_header(i64 %x, i64 %y, i1 %cond) {
     99 ; CHECK-LABEL: nothrow_header
    100 ; CHECK-LABEL: entry
    101 ; CHECK: %div = udiv i64 %x, %y
    102 ; CHECK-LABEL: loop
    103   ; CHECK: call void @use(i64 %div)
    104 entry:
    105   br label %loop
    106 loop:                                         ; preds = %entry, %for.inc
    107   %div = udiv i64 %x, %y
    108   br i1 %cond, label %loop-if, label %exit
    109 loop-if:
    110   call void @use(i64 %div)
    111   br label %loop
    112 exit:
    113   ret void
    114 }
    115 ; Negative test - can't move out of throwing block
    116 define void @nothrow_header_neg(i64 %x, i64 %y, i1 %cond) {
    117 ; CHECK-LABEL: nothrow_header_neg
    118 ; CHECK-LABEL: entry
    119 ; CHECK-LABEL: loop
    120 ; CHECK: %div = udiv i64 %x, %y
    121 ; CHECK: call void @use(i64 %div)
    122 entry:
    123   br label %loop
    124 loop:                                         ; preds = %entry, %for.inc
    125   br label %loop-if
    126 loop-if:
    127   %div = udiv i64 %x, %y
    128   call void @use(i64 %div)
    129   br label %loop
    130 }
    131