Home | History | Annotate | Download | only in LICM
      1 ; RUN: opt < %s -basicaa -tbaa -licm -S | FileCheck %s
      2 ; RUN: opt -aa-pipeline=type-based-aa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
      3 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
      4 
      5 @X = global i32 7   ; <i32*> [#uses=4]
      6 
      7 define void @test1(i32 %i) {
      8 Entry:
      9   br label %Loop
     10 ; CHECK-LABEL: @test1(
     11 ; CHECK: Entry:
     12 ; CHECK-NEXT:   load i32, i32* @X
     13 ; CHECK-NEXT:   br label %Loop
     14 
     15 
     16 Loop:   ; preds = %Loop, %0
     17   %j = phi i32 [ 0, %Entry ], [ %Next, %Loop ]    ; <i32> [#uses=1]
     18   %x = load i32, i32* @X   ; <i32> [#uses=1]
     19   %x2 = add i32 %x, 1   ; <i32> [#uses=1]
     20   store i32 %x2, i32* @X
     21   %Next = add i32 %j, 1   ; <i32> [#uses=2]
     22   %cond = icmp eq i32 %Next, 0    ; <i1> [#uses=1]
     23   br i1 %cond, label %Out, label %Loop
     24 
     25 Out:
     26   ret void
     27 ; CHECK: Out:
     28 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %x2
     29 ; CHECK-NEXT:   store i32 %[[LCSSAPHI]], i32* @X
     30 ; CHECK-NEXT:   ret void
     31 
     32 }
     33 
     34 define void @test2(i32 %i) {
     35 Entry:
     36   br label %Loop
     37 ; CHECK-LABEL: @test2(
     38 ; CHECK: Entry:
     39 ; CHECK-NEXT:    %.promoted = load i32, i32* getelementptr inbounds (i32, i32* @X, i64 1)
     40 ; CHECK-NEXT:    br label %Loop
     41 
     42 Loop:   ; preds = %Loop, %0
     43   %X1 = getelementptr i32, i32* @X, i64 1    ; <i32*> [#uses=1]
     44   %A = load i32, i32* %X1    ; <i32> [#uses=1]
     45   %V = add i32 %A, 1    ; <i32> [#uses=1]
     46   %X2 = getelementptr i32, i32* @X, i64 1    ; <i32*> [#uses=1]
     47   store i32 %V, i32* %X2
     48   br i1 false, label %Loop, label %Exit
     49 
     50 Exit:   ; preds = %Loop
     51   ret void
     52 ; CHECK: Exit:
     53 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %V
     54 ; CHECK-NEXT:   store i32 %[[LCSSAPHI]], i32* getelementptr inbounds (i32, i32* @X, i64 1)
     55 ; CHECK-NEXT:   ret void
     56 }
     57 
     58 
     59 
     60 define void @test3(i32 %i) {
     61 ; CHECK-LABEL: @test3(
     62   br label %Loop
     63 Loop:
     64         ; Should not promote this to a register
     65   %x = load volatile i32, i32* @X
     66   %x2 = add i32 %x, 1
     67   store i32 %x2, i32* @X
     68   br i1 true, label %Out, label %Loop
     69 
     70 ; CHECK: Loop:
     71 ; CHECK-NEXT: load volatile
     72 
     73 Out:    ; preds = %Loop
     74   ret void
     75 }
     76 
     77 ; PR8041
     78 define void @test4(i8* %x, i8 %n) {
     79 ; CHECK-LABEL: @test4(
     80   %handle1 = alloca i8*
     81   %handle2 = alloca i8*
     82   store i8* %x, i8** %handle1
     83   br label %loop
     84 
     85 loop:
     86   %tmp = getelementptr i8, i8* %x, i64 8
     87   store i8* %tmp, i8** %handle2
     88   br label %subloop
     89 
     90 subloop:
     91   %count = phi i8 [ 0, %loop ], [ %nextcount, %subloop ]
     92   %offsetx2 = load i8*, i8** %handle2
     93   store i8 %n, i8* %offsetx2
     94   %newoffsetx2 = getelementptr i8, i8* %offsetx2, i64 -1
     95   store i8* %newoffsetx2, i8** %handle2
     96   %nextcount = add i8 %count, 1
     97   %innerexitcond = icmp sge i8 %nextcount, 8
     98   br i1 %innerexitcond, label %innerexit, label %subloop
     99 
    100 ; Should have promoted 'handle2' accesses.
    101 ; CHECK: subloop:
    102 ; CHECK-NEXT: phi i8* [
    103 ; CHECK-NEXT: %count = phi i8 [
    104 ; CHECK-NEXT: store i8 %n
    105 ; CHECK-NOT: store
    106 ; CHECK: br i1
    107 
    108 innerexit:
    109   %offsetx1 = load i8*, i8** %handle1
    110   %val = load i8, i8* %offsetx1
    111   %cond = icmp eq i8 %val, %n
    112   br i1 %cond, label %exit, label %loop
    113 
    114 ; Should not have promoted offsetx1 loads.
    115 ; CHECK: innerexit:
    116 ; CHECK: %val = load i8, i8* %offsetx1
    117 ; CHECK: %cond = icmp eq i8 %val, %n
    118 ; CHECK: br i1 %cond, label %exit, label %loop
    119 
    120 exit:
    121   ret void
    122 }
    123 
    124 define void @test5(i32 %i, i32** noalias %P2) {
    125 Entry:
    126   br label %Loop
    127 ; CHECK-LABEL: @test5(
    128 ; CHECK: Entry:
    129 ; CHECK-NEXT:   load i32, i32* @X
    130 ; CHECK-NEXT:   br label %Loop
    131 
    132 
    133 Loop:   ; preds = %Loop, %0
    134   %j = phi i32 [ 0, %Entry ], [ %Next, %Loop ]    ; <i32> [#uses=1]
    135   %x = load i32, i32* @X   ; <i32> [#uses=1]
    136   %x2 = add i32 %x, 1   ; <i32> [#uses=1]
    137   store i32 %x2, i32* @X
    138 
    139         store atomic i32* @X, i32** %P2 monotonic, align 8
    140 
    141   %Next = add i32 %j, 1   ; <i32> [#uses=2]
    142   %cond = icmp eq i32 %Next, 0    ; <i1> [#uses=1]
    143   br i1 %cond, label %Out, label %Loop
    144 
    145 Out:
    146   ret void
    147 ; CHECK: Out:
    148 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %x2
    149 ; CHECK-NEXT:   store i32 %[[LCSSAPHI]], i32* @X
    150 ; CHECK-NEXT:   ret void
    151 
    152 }
    153 
    154 
    155 ; PR14753 - Preserve TBAA tags when promoting values in a loop.
    156 define void @test6(i32 %n, float* nocapture %a, i32* %gi) {
    157 entry:
    158   store i32 0, i32* %gi, align 4, !tbaa !0
    159   %cmp1 = icmp slt i32 0, %n
    160   br i1 %cmp1, label %for.body.lr.ph, label %for.end
    161 
    162 for.body.lr.ph:                                   ; preds = %entry
    163   br label %for.body
    164 
    165 for.body:                                         ; preds = %for.body.lr.ph, %for.body
    166   %storemerge2 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
    167   %idxprom = sext i32 %storemerge2 to i64
    168   %arrayidx = getelementptr inbounds float, float* %a, i64 %idxprom
    169   store float 0.000000e+00, float* %arrayidx, align 4, !tbaa !3
    170   %0 = load i32, i32* %gi, align 4, !tbaa !0
    171   %inc = add nsw i32 %0, 1
    172   store i32 %inc, i32* %gi, align 4, !tbaa !0
    173   %cmp = icmp slt i32 %inc, %n
    174   br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
    175 
    176 for.cond.for.end_crit_edge:                       ; preds = %for.body
    177   br label %for.end
    178 
    179 for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
    180   ret void
    181 
    182 ; CHECK: for.body.lr.ph:
    183 ; CHECK-NEXT:  %gi.promoted = load i32, i32* %gi, align 4, !tbaa !0
    184 ; CHECK: for.cond.for.end_crit_edge:
    185 ; CHECK-NEXT:  %[[LCSSAPHI:.*]] = phi i32 [ %inc
    186 ; CHECK-NEXT:  store i32 %[[LCSSAPHI]], i32* %gi, align 4, !tbaa !0
    187 }
    188 
    189 declare i32 @opaque(i32) argmemonly
    190 declare void @capture(i32*)
    191 
    192 ; We can promote even if opaque may throw.
    193 define i32 @test7() {
    194 ; CHECK-LABEL: @test7(
    195 ; CHECK: entry:
    196 ; CHECK-NEXT: %local = alloca
    197 ; CHECK-NEXT: call void @capture(i32* %local)
    198 ; CHECK-NEXT: load i32, i32* %local
    199 ; CHECK-NEXT: br label %loop
    200 ; CHECK: exit:
    201 ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %x2, %loop ]
    202 ; CHECK-NEXT: store i32 %[[LCSSAPHI]], i32* %local
    203 ; CHECK-NEXT: %ret = load i32, i32* %local
    204 ; CHECK-NEXT: ret i32 %ret
    205 entry:
    206   %local = alloca i32
    207   call void @capture(i32* %local)
    208   br label %loop
    209 
    210 loop:
    211   %j = phi i32 [ 0, %entry ], [ %next, %loop ]
    212   %x = load i32, i32* %local
    213   %x2 = call i32 @opaque(i32 %x) ; Note this does not capture %local
    214   store i32 %x2, i32* %local
    215   %next = add i32 %j, 1
    216   %cond = icmp eq i32 %next, 0
    217   br i1 %cond, label %exit, label %loop
    218 
    219 exit:
    220   %ret = load i32, i32* %local
    221   ret i32 %ret
    222 }
    223 
    224 ; Make sure we don't promote if the store is really control-flow dependent.
    225 define i32 @test7bad() {
    226 ; CHECK-LABEL: @test7bad(
    227 ; CHECK: entry:
    228 ; CHECK-NEXT: %local = alloca
    229 ; CHECK-NEXT: call void @capture(i32* %local)
    230 ; CHECK-NEXT: br label %loop
    231 ; CHECK: if:
    232 ; CHECK-NEXT: store i32 %x2, i32* %local
    233 ; CHECK-NEXT: br label %else
    234 ; CHECK: exit:
    235 ; CHECK-NEXT: %ret = load i32, i32* %local
    236 ; CHECK-NEXT: ret i32 %ret
    237 entry:
    238   %local = alloca i32
    239   call void @capture(i32* %local)  
    240   br label %loop
    241 loop:
    242   %j = phi i32 [ 0, %entry ], [ %next, %else ]
    243   %x = load i32, i32* %local
    244   %x2 = call i32 @opaque(i32 %x) ; Note this does not capture %local
    245   %cmp = icmp eq i32 %x2, 0
    246   br i1 %cmp, label %if, label %else
    247 
    248 if:  
    249   store i32 %x2, i32* %local
    250   br label %else
    251 
    252 else:
    253   %next = add i32 %j, 1
    254   %cond = icmp eq i32 %next, 0
    255   br i1 %cond, label %exit, label %loop
    256 
    257 exit:
    258   %ret = load i32, i32* %local
    259   ret i32 %ret
    260 }
    261 
    262 ; Even if neither the load nor the store or guaranteed to execute because
    263 ; opaque() may throw, we can still promote - the load not being guaranteed
    264 ; doesn't block us, because %local is always dereferenceable.
    265 define i32 @test8() {
    266 ; CHECK-LABEL: @test8(
    267 ; CHECK: entry:
    268 ; CHECK-NEXT: %local = alloca
    269 ; CHECK-NEXT: call void @capture(i32* %local)
    270 ; CHECK-NEXT: load i32, i32* %local
    271 ; CHECK-NEXT: br label %loop
    272 ; CHECK: exit:
    273 ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %x2, %loop ]
    274 ; CHECK-NEXT: store i32 %[[LCSSAPHI]], i32* %local
    275 ; CHECK-NEXT: %ret = load i32, i32* %local
    276 ; CHECK-NEXT: ret i32 %ret
    277 entry:
    278   %local = alloca i32
    279   call void @capture(i32* %local)  
    280   br label %loop
    281 
    282 loop:
    283   %j = phi i32 [ 0, %entry ], [ %next, %loop ]
    284   %throwaway = call i32 @opaque(i32 %j)
    285   %x = load i32, i32* %local  
    286   %x2 = call i32 @opaque(i32 %x)
    287   store i32 %x2, i32* %local
    288   %next = add i32 %j, 1
    289   %cond = icmp eq i32 %next, 0
    290   br i1 %cond, label %exit, label %loop
    291 
    292 exit:
    293   %ret = load i32, i32* %local
    294   ret i32 %ret
    295 }
    296 
    297 
    298 ; If the store is "guaranteed modulo exceptions", and the load depends on
    299 ; control flow, we can only promote if the pointer is otherwise known to be
    300 ; dereferenceable
    301 define i32 @test9() {
    302 ; CHECK-LABEL: @test9(
    303 ; CHECK: entry:
    304 ; CHECK-NEXT: %local = alloca
    305 ; CHECK-NEXT: call void @capture(i32* %local)
    306 ; CHECK-NEXT: load i32, i32* %local
    307 ; CHECK-NEXT: br label %loop
    308 ; CHECK: exit:
    309 ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %x2, %else ]
    310 ; CHECK-NEXT: store i32 %[[LCSSAPHI]], i32* %local
    311 ; CHECK-NEXT: %ret = load i32, i32* %local
    312 ; CHECK-NEXT: ret i32 %ret
    313 entry:
    314   %local = alloca i32
    315   call void @capture(i32* %local)  
    316   br label %loop
    317 
    318 loop:
    319   %j = phi i32 [ 0, %entry ], [ %next, %else ]  
    320   %j2 = call i32 @opaque(i32 %j)
    321   %cmp = icmp eq i32 %j2, 0
    322   br i1 %cmp, label %if, label %else
    323 
    324 if:  
    325   %x = load i32, i32* %local
    326   br label %else
    327 
    328 else:
    329   %x2 = phi i32 [ 0, %loop ], [ %x, %if]
    330   store i32 %x2, i32* %local
    331   %next = add i32 %j, 1
    332   %cond = icmp eq i32 %next, 0
    333   br i1 %cond, label %exit, label %loop
    334 
    335 exit:
    336   %ret = load i32, i32* %local
    337   ret i32 %ret
    338 }
    339 
    340 define i32 @test9bad(i32 %i) {
    341 ; CHECK-LABEL: @test9bad(
    342 ; CHECK: entry:
    343 ; CHECK-NEXT: %local = alloca
    344 ; CHECK-NEXT: call void @capture(i32* %local)
    345 ; CHECK-NEXT: %notderef = getelementptr
    346 ; CHECK-NEXT: br label %loop
    347 ; CHECK: if:
    348 ; CHECK-NEXT: load i32, i32* %notderef
    349 ; CHECK-NEXT: br label %else
    350 ; CHECK: exit:
    351 ; CHECK-NEXT: %ret = load i32, i32* %notderef
    352 ; CHECK-NEXT: ret i32 %ret
    353 entry:
    354   %local = alloca i32
    355   call void @capture(i32* %local)  
    356   %notderef = getelementptr i32, i32* %local, i32 %i
    357   br label %loop
    358 
    359 loop:
    360   %j = phi i32 [ 0, %entry ], [ %next, %else ]  
    361   %j2 = call i32 @opaque(i32 %j)
    362   %cmp = icmp eq i32 %j2, 0
    363   br i1 %cmp, label %if, label %else
    364 
    365 if:  
    366   %x = load i32, i32* %notderef
    367   br label %else
    368 
    369 else:
    370   %x2 = phi i32 [ 0, %loop ], [ %x, %if]
    371   store i32 %x2, i32* %notderef
    372   %next = add i32 %j, 1
    373   %cond = icmp eq i32 %next, 0
    374   br i1 %cond, label %exit, label %loop
    375 
    376 exit:
    377   %ret = load i32, i32* %notderef
    378   ret i32 %ret
    379 }
    380 
    381 define void @test10(i32 %i) {
    382 Entry:
    383   br label %Loop
    384 ; CHECK-LABEL: @test10(
    385 ; CHECK: Entry:
    386 ; CHECK-NEXT:   load atomic i32, i32* @X unordered, align 4
    387 ; CHECK-NEXT:   br label %Loop
    388 
    389 
    390 Loop:   ; preds = %Loop, %0
    391   %j = phi i32 [ 0, %Entry ], [ %Next, %Loop ]    ; <i32> [#uses=1]
    392   %x = load atomic i32, i32* @X unordered, align 4
    393   %x2 = add i32 %x, 1
    394   store atomic i32 %x2, i32* @X unordered, align 4
    395   %Next = add i32 %j, 1
    396   %cond = icmp eq i32 %Next, 0
    397   br i1 %cond, label %Out, label %Loop
    398 
    399 Out:
    400   ret void
    401 ; CHECK: Out:
    402 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %x2
    403 ; CHECK-NEXT:   store atomic i32 %[[LCSSAPHI]], i32* @X unordered, align 4
    404 ; CHECK-NEXT:   ret void
    405 
    406 }
    407 
    408 ; Early exit is known not to be taken on first iteration and thus doesn't
    409 ; effect whether load is known to execute.
    410 define void @test11(i32 %i) {
    411 Entry:
    412   br label %Loop
    413 ; CHECK-LABEL: @test11(
    414 ; CHECK: Entry:
    415 ; CHECK-NEXT:   load i32, i32* @X
    416 ; CHECK-NEXT:   br label %Loop
    417 
    418 
    419 Loop:   ; preds = %Loop, %0
    420   %j = phi i32 [ 0, %Entry ], [ %Next, %body ]    ; <i32> [#uses=1]
    421   %early.test = icmp ult i32 %j, 32
    422   br i1 %early.test, label %body, label %Early
    423 body:
    424   %x = load i32, i32* @X   ; <i32> [#uses=1]
    425   %x2 = add i32 %x, 1   ; <i32> [#uses=1]
    426   store i32 %x2, i32* @X
    427   %Next = add i32 %j, 1   ; <i32> [#uses=2]
    428   %cond = icmp eq i32 %Next, 0    ; <i1> [#uses=1]
    429   br i1 %cond, label %Out, label %Loop
    430 
    431 Early:
    432 ; CHECK: Early:
    433 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %x2
    434 ; CHECK-NEXT:   store i32 %[[LCSSAPHI]], i32* @X
    435 ; CHECK-NEXT:   ret void
    436   ret void
    437 Out:
    438   ret void
    439 ; CHECK: Out:
    440 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %x2
    441 ; CHECK-NEXT:   store i32 %[[LCSSAPHI]], i32* @X
    442 ; CHECK-NEXT:   ret void
    443 
    444 }
    445 
    446 !0 = !{!4, !4, i64 0}
    447 !1 = !{!"omnipotent char", !2}
    448 !2 = !{!"Simple C/C++ TBAA"}
    449 !3 = !{!5, !5, i64 0}
    450 !4 = !{!"int", !1}
    451 !5 = !{!"float", !1}
    452