Home | History | Annotate | Download | only in LICM
      1 ; RUN: opt < %s -S -basicaa -licm | FileCheck %s
      2 ; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
      3 
      4 ; Check that we can hoist unordered loads
      5 define i32 @test1(i32* nocapture %y) nounwind uwtable ssp {
      6 entry:
      7   br label %loop
      8 
      9 loop:
     10   %i = phi i32 [ %inc, %loop ], [ 0, %entry ]
     11   %val = load atomic i32, i32* %y unordered, align 4
     12   %inc = add nsw i32 %i, 1
     13   %exitcond = icmp eq i32 %inc, %val
     14   br i1 %exitcond, label %end, label %loop
     15 
     16 end:
     17   ret i32 %val
     18 ; CHECK-LABEL: define i32 @test1(
     19 ; CHECK: load atomic
     20 ; CHECK-NEXT: br label %loop
     21 }
     22 
     23 ; Check that we don't sink/hoist monotonic loads
     24 ; (Strictly speaking, it's not forbidden, but it's supposed to be possible to
     25 ; use monotonic for spinlock-like constructs.)
     26 define i32 @test2(i32* nocapture %y) nounwind uwtable ssp {
     27 entry:
     28   br label %loop
     29 
     30 loop:
     31   %val = load atomic i32, i32* %y monotonic, align 4
     32   %exitcond = icmp ne i32 %val, 0
     33   br i1 %exitcond, label %end, label %loop
     34 
     35 end:
     36   ret i32 %val
     37 ; CHECK-LABEL: define i32 @test2(
     38 ; CHECK: load atomic
     39 ; CHECK-NEXT: %exitcond = icmp ne
     40 ; CHECK-NEXT: br i1 %exitcond, label %end, label %loop
     41 }
     42 
     43 ; Check that we hoist unordered around monotonic.
     44 ; (The noalias shouldn't be necessary in theory, but LICM isn't quite that
     45 ; smart yet.)
     46 define i32 @test3(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
     47 entry:
     48   br label %loop
     49 
     50 loop:
     51   %vala = load atomic i32, i32* %y monotonic, align 4
     52   %valb = load atomic i32, i32* %x unordered, align 4
     53   %exitcond = icmp ne i32 %vala, %valb
     54   br i1 %exitcond, label %end, label %loop
     55 
     56 end:
     57   ret i32 %vala
     58 ; CHECK-LABEL: define i32 @test3(
     59 ; CHECK: load atomic i32, i32* %x unordered
     60 ; CHECK-NEXT: br label %loop
     61 }
     62 
     63 ; We can sink an unordered store
     64 define i32 @test4(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
     65 entry:
     66   br label %loop
     67 
     68 loop:
     69   %vala = load atomic i32, i32* %y monotonic, align 4
     70   store atomic i32 %vala, i32* %x unordered, align 4
     71   %exitcond = icmp ne i32 %vala, 0
     72   br i1 %exitcond, label %end, label %loop
     73 
     74 end:
     75   ret i32 %vala
     76 ; CHECK-LABEL: define i32 @test4(
     77 ; CHECK-LABEL: loop:
     78 ; CHECK: load atomic i32, i32* %y monotonic
     79 ; CHECK-NOT: store
     80 ; CHECK-LABEL: end:
     81 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %vala
     82 ; CHECK:   store atomic i32 %[[LCSSAPHI]], i32* %x unordered, align 4
     83 }
     84 
     85 ; We currently don't handle ordered atomics.
     86 define i32 @test5(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
     87 entry:
     88   br label %loop
     89 
     90 loop:
     91   %vala = load atomic i32, i32* %y monotonic, align 4
     92   store atomic i32 %vala, i32* %x release, align 4
     93   %exitcond = icmp ne i32 %vala, 0
     94   br i1 %exitcond, label %end, label %loop
     95 
     96 end:
     97   ret i32 %vala
     98 ; CHECK-LABEL: define i32 @test5(
     99 ; CHECK: load atomic i32, i32* %y monotonic
    100 ; CHECK-NEXT: store atomic
    101 }
    102 
    103 ; We currently don't touch volatiles
    104 define i32 @test6(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
    105 entry:
    106   br label %loop
    107 
    108 loop:
    109   %vala = load atomic i32, i32* %y monotonic, align 4
    110   store volatile i32 %vala, i32* %x, align 4
    111   %exitcond = icmp ne i32 %vala, 0
    112   br i1 %exitcond, label %end, label %loop
    113 
    114 end:
    115   ret i32 %vala
    116 ; CHECK-LABEL: define i32 @test6(
    117 ; CHECK: load atomic i32, i32* %y monotonic
    118 ; CHECK-NEXT: store volatile
    119 }
    120 
    121 ; We currently don't touch volatiles
    122 define i32 @test6b(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
    123 entry:
    124   br label %loop
    125 
    126 loop:
    127   %vala = load atomic i32, i32* %y monotonic, align 4
    128   store atomic volatile i32 %vala, i32* %x unordered, align 4
    129   %exitcond = icmp ne i32 %vala, 0
    130   br i1 %exitcond, label %end, label %loop
    131 
    132 end:
    133   ret i32 %vala
    134 ; CHECK-LABEL: define i32 @test6b(
    135 ; CHECK: load atomic i32, i32* %y monotonic
    136 ; CHECK-NEXT: store atomic volatile
    137 }
    138 
    139 ; Mixing unorder atomics and normal loads/stores is
    140 ; current unimplemented
    141 define i32 @test7(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp {
    142 entry:
    143   br label %loop
    144 
    145 loop:
    146   store i32 5, i32* %x
    147   %vala = load atomic i32, i32* %y monotonic, align 4
    148   store atomic i32 %vala, i32* %x unordered, align 4
    149   %exitcond = icmp ne i32 %vala, 0
    150   br i1 %exitcond, label %end, label %loop
    151 
    152 end:
    153   ret i32 %vala
    154 ; CHECK-LABEL: define i32 @test7(
    155 ; CHECK: store i32 5, i32* %x
    156 ; CHECK-NEXT: load atomic i32, i32* %y
    157 ; CHECK-NEXT: store atomic i32
    158 }
    159 
    160 ; Three provably noalias locations - we can sink normal and unordered, but
    161 ;  not monotonic
    162 define i32 @test7b(i32* nocapture noalias %x, i32* nocapture %y, i32* noalias nocapture %z) nounwind uwtable ssp {
    163 entry:
    164   br label %loop
    165 
    166 loop:
    167   store i32 5, i32* %x
    168   %vala = load atomic i32, i32* %y monotonic, align 4
    169   store atomic i32 %vala, i32* %z unordered, align 4
    170   %exitcond = icmp ne i32 %vala, 0
    171   br i1 %exitcond, label %end, label %loop
    172 
    173 end:
    174   ret i32 %vala
    175 ; CHECK-LABEL: define i32 @test7b(
    176 ; CHECK: load atomic i32, i32* %y monotonic
    177 
    178 ; CHECK-LABEL: end:
    179 ; CHECK: store i32 5, i32* %x
    180 ; CHECK: store atomic i32 %{{.+}}, i32* %z unordered, align 4
    181 }
    182 
    183 
    184 define i32 @test8(i32* nocapture noalias %x, i32* nocapture %y) {
    185 entry:
    186   br label %loop
    187 
    188 loop:
    189   %vala = load atomic i32, i32* %y monotonic, align 4
    190   store atomic i32 %vala, i32* %x unordered, align 4
    191   fence release
    192   %exitcond = icmp ne i32 %vala, 0
    193   br i1 %exitcond, label %end, label %loop
    194 
    195 end:
    196   ret i32 %vala
    197 ; CHECK-LABEL: define i32 @test8(
    198 ; CHECK-LABEL: loop:
    199 ; CHECK: load atomic i32, i32* %y monotonic
    200 ; CHECK-NEXT: store atomic
    201 ; CHECK-NEXT: fence
    202 }
    203 
    204 ; Exact semantics of monotonic accesses are a bit vague in the C++ spec,
    205 ; for the moment, be conservative and don't touch them.
    206 define i32 @test9(i32* nocapture noalias %x, i32* nocapture %y) {
    207 entry:
    208   br label %loop
    209 
    210 loop:
    211   %vala = load atomic i32, i32* %y monotonic, align 4
    212   store atomic i32 %vala, i32* %x monotonic, align 4
    213   %exitcond = icmp ne i32 %vala, 0
    214   br i1 %exitcond, label %end, label %loop
    215 
    216 end:
    217   ret i32 %vala
    218 ; CHECK-LABEL: define i32 @test9(
    219 ; CHECK-LABEL: loop:
    220 ; CHECK: load atomic i32, i32* %y monotonic
    221 ; CHECK-NEXT:   store atomic i32 %vala, i32* %x monotonic, align 4
    222 }
    223