Home | History | Annotate | Download | only in LICM
      1 ; RUN: opt < %s -basicaa -tbaa -licm -S | FileCheck %s
      2 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"
      3 
      4 @X = global i32 7   ; <i32*> [#uses=4]
      5 
      6 define void @test1(i32 %i) {
      7 Entry:
      8   br label %Loop
      9 ; CHECK-LABEL: @test1(
     10 ; CHECK: Entry:
     11 ; CHECK-NEXT:   load i32, i32* @X
     12 ; CHECK-NEXT:   br label %Loop
     13 
     14 
     15 Loop:   ; preds = %Loop, %0
     16   %j = phi i32 [ 0, %Entry ], [ %Next, %Loop ]    ; <i32> [#uses=1]
     17   %x = load i32, i32* @X   ; <i32> [#uses=1]
     18   %x2 = add i32 %x, 1   ; <i32> [#uses=1]
     19   store i32 %x2, i32* @X
     20   %Next = add i32 %j, 1   ; <i32> [#uses=2]
     21   %cond = icmp eq i32 %Next, 0    ; <i1> [#uses=1]
     22   br i1 %cond, label %Out, label %Loop
     23 
     24 Out:
     25   ret void
     26 ; CHECK: Out:
     27 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %x2
     28 ; CHECK-NEXT:   store i32 %[[LCSSAPHI]], i32* @X
     29 ; CHECK-NEXT:   ret void
     30 
     31 }
     32 
     33 define void @test2(i32 %i) {
     34 Entry:
     35   br label %Loop
     36 ; CHECK-LABEL: @test2(
     37 ; CHECK: Entry:
     38 ; CHECK-NEXT:    %.promoted = load i32, i32* getelementptr inbounds (i32, i32* @X, i64 1)
     39 ; CHECK-NEXT:    br label %Loop
     40 
     41 Loop:   ; preds = %Loop, %0
     42   %X1 = getelementptr i32, i32* @X, i64 1    ; <i32*> [#uses=1]
     43   %A = load i32, i32* %X1    ; <i32> [#uses=1]
     44   %V = add i32 %A, 1    ; <i32> [#uses=1]
     45   %X2 = getelementptr i32, i32* @X, i64 1    ; <i32*> [#uses=1]
     46   store i32 %V, i32* %X2
     47   br i1 false, label %Loop, label %Exit
     48 
     49 Exit:   ; preds = %Loop
     50   ret void
     51 ; CHECK: Exit:
     52 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %V
     53 ; CHECK-NEXT:   store i32 %[[LCSSAPHI]], i32* getelementptr inbounds (i32, i32* @X, i64 1)
     54 ; CHECK-NEXT:   ret void
     55 }
     56 
     57 
     58 
     59 define void @test3(i32 %i) {
     60 ; CHECK-LABEL: @test3(
     61   br label %Loop
     62 Loop:
     63         ; Should not promote this to a register
     64   %x = load volatile i32, i32* @X
     65   %x2 = add i32 %x, 1
     66   store i32 %x2, i32* @X
     67   br i1 true, label %Out, label %Loop
     68 
     69 ; CHECK: Loop:
     70 ; CHECK-NEXT: load volatile
     71 
     72 Out:    ; preds = %Loop
     73   ret void
     74 }
     75 
     76 ; PR8041
     77 define void @test4(i8* %x, i8 %n) {
     78 ; CHECK-LABEL: @test4(
     79   %handle1 = alloca i8*
     80   %handle2 = alloca i8*
     81   store i8* %x, i8** %handle1
     82   br label %loop
     83 
     84 loop:
     85   %tmp = getelementptr i8, i8* %x, i64 8
     86   store i8* %tmp, i8** %handle2
     87   br label %subloop
     88 
     89 subloop:
     90   %count = phi i8 [ 0, %loop ], [ %nextcount, %subloop ]
     91   %offsetx2 = load i8*, i8** %handle2
     92   store i8 %n, i8* %offsetx2
     93   %newoffsetx2 = getelementptr i8, i8* %offsetx2, i64 -1
     94   store i8* %newoffsetx2, i8** %handle2
     95   %nextcount = add i8 %count, 1
     96   %innerexitcond = icmp sge i8 %nextcount, 8
     97   br i1 %innerexitcond, label %innerexit, label %subloop
     98 
     99 ; Should have promoted 'handle2' accesses.
    100 ; CHECK: subloop:
    101 ; CHECK-NEXT: phi i8* [
    102 ; CHECK-NEXT: %count = phi i8 [
    103 ; CHECK-NEXT: store i8 %n
    104 ; CHECK-NOT: store
    105 ; CHECK: br i1
    106 
    107 innerexit:
    108   %offsetx1 = load i8*, i8** %handle1
    109   %val = load i8, i8* %offsetx1
    110   %cond = icmp eq i8 %val, %n
    111   br i1 %cond, label %exit, label %loop
    112 
    113 ; Should not have promoted offsetx1 loads.
    114 ; CHECK: innerexit:
    115 ; CHECK: %val = load i8, i8* %offsetx1
    116 ; CHECK: %cond = icmp eq i8 %val, %n
    117 ; CHECK: br i1 %cond, label %exit, label %loop
    118 
    119 exit:
    120   ret void
    121 }
    122 
    123 define void @test5(i32 %i, i32** noalias %P2) {
    124 Entry:
    125   br label %Loop
    126 ; CHECK-LABEL: @test5(
    127 ; CHECK: Entry:
    128 ; CHECK-NEXT:   load i32, i32* @X
    129 ; CHECK-NEXT:   br label %Loop
    130 
    131 
    132 Loop:   ; preds = %Loop, %0
    133   %j = phi i32 [ 0, %Entry ], [ %Next, %Loop ]    ; <i32> [#uses=1]
    134   %x = load i32, i32* @X   ; <i32> [#uses=1]
    135   %x2 = add i32 %x, 1   ; <i32> [#uses=1]
    136   store i32 %x2, i32* @X
    137 
    138         store volatile i32* @X, i32** %P2
    139 
    140   %Next = add i32 %j, 1   ; <i32> [#uses=2]
    141   %cond = icmp eq i32 %Next, 0    ; <i1> [#uses=1]
    142   br i1 %cond, label %Out, label %Loop
    143 
    144 Out:
    145   ret void
    146 ; CHECK: Out:
    147 ; CHECK-NEXT:   %[[LCSSAPHI:.*]] = phi i32 [ %x2
    148 ; CHECK-NEXT:   store i32 %[[LCSSAPHI]], i32* @X
    149 ; CHECK-NEXT:   ret void
    150 
    151 }
    152 
    153 
    154 ; PR14753 - Preserve TBAA tags when promoting values in a loop.
    155 define void @test6(i32 %n, float* nocapture %a, i32* %gi) {
    156 entry:
    157   store i32 0, i32* %gi, align 4, !tbaa !0
    158   %cmp1 = icmp slt i32 0, %n
    159   br i1 %cmp1, label %for.body.lr.ph, label %for.end
    160 
    161 for.body.lr.ph:                                   ; preds = %entry
    162   br label %for.body
    163 
    164 for.body:                                         ; preds = %for.body.lr.ph, %for.body
    165   %storemerge2 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
    166   %idxprom = sext i32 %storemerge2 to i64
    167   %arrayidx = getelementptr inbounds float, float* %a, i64 %idxprom
    168   store float 0.000000e+00, float* %arrayidx, align 4, !tbaa !3
    169   %0 = load i32, i32* %gi, align 4, !tbaa !0
    170   %inc = add nsw i32 %0, 1
    171   store i32 %inc, i32* %gi, align 4, !tbaa !0
    172   %cmp = icmp slt i32 %inc, %n
    173   br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
    174 
    175 for.cond.for.end_crit_edge:                       ; preds = %for.body
    176   br label %for.end
    177 
    178 for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
    179   ret void
    180 
    181 ; CHECK: for.body.lr.ph:
    182 ; CHECK-NEXT:  %gi.promoted = load i32, i32* %gi, align 4, !tbaa !0
    183 ; CHECK: for.cond.for.end_crit_edge:
    184 ; CHECK-NEXT:  %[[LCSSAPHI:.*]] = phi i32 [ %inc
    185 ; CHECK-NEXT:  store i32 %[[LCSSAPHI]], i32* %gi, align 4, !tbaa !0
    186 }
    187 
    188 !0 = !{!4, !4, i64 0}
    189 !1 = !{!"omnipotent char", !2}
    190 !2 = !{!"Simple C/C++ TBAA"}
    191 !3 = !{!5, !5, i64 0}
    192 !4 = !{!"int", !1}
    193 !5 = !{!"float", !1}
    194