Home | History | Annotate | Download | only in EarlyCSE
      1 ; RUN: opt < %s -S -early-cse | FileCheck %s
      2 ; RUN: opt < %s -S -passes=early-cse | FileCheck %s
      3 
      4 declare void @llvm.assume(i1) nounwind
      5 
      6 ; CHECK-LABEL: @test1(
      7 define void @test1(i8 %V, i32 *%P) {
      8   %A = bitcast i64 42 to double  ;; dead
      9   %B = add i32 4, 19             ;; constant folds
     10   store i32 %B, i32* %P
     11   ; CHECK-NEXT: store i32 23, i32* %P
     12   
     13   %C = zext i8 %V to i32
     14   %D = zext i8 %V to i32  ;; CSE
     15   store volatile i32 %C, i32* %P
     16   store volatile i32 %D, i32* %P
     17   ; CHECK-NEXT: %C = zext i8 %V to i32
     18   ; CHECK-NEXT: store volatile i32 %C
     19   ; CHECK-NEXT: store volatile i32 %C
     20   
     21   %E = add i32 %C, %C
     22   %F = add i32 %C, %C
     23   store volatile i32 %E, i32* %P
     24   store volatile i32 %F, i32* %P
     25   ; CHECK-NEXT: %E = add i32 %C, %C
     26   ; CHECK-NEXT: store volatile i32 %E
     27   ; CHECK-NEXT: store volatile i32 %E
     28 
     29   %G = add nuw i32 %C, %C
     30   store volatile i32 %G, i32* %P
     31   ; CHECK-NEXT: store volatile i32 %E
     32   ret void
     33 }
     34 
     35 
     36 ;; Simple load value numbering.
     37 ; CHECK-LABEL: @test2(
     38 define i32 @test2(i32 *%P) {
     39   %V1 = load i32, i32* %P
     40   %V2 = load i32, i32* %P
     41   %Diff = sub i32 %V1, %V2
     42   ret i32 %Diff
     43   ; CHECK: ret i32 0
     44 }
     45 
     46 ; CHECK-LABEL: @test2a(
     47 define i32 @test2a(i32 *%P, i1 %b) {
     48   %V1 = load i32, i32* %P
     49   tail call void @llvm.assume(i1 %b)
     50   %V2 = load i32, i32* %P
     51   %Diff = sub i32 %V1, %V2
     52   ret i32 %Diff
     53   ; CHECK: ret i32 0
     54 }
     55 
     56 ;; Cross block load value numbering.
     57 ; CHECK-LABEL: @test3(
     58 define i32 @test3(i32 *%P, i1 %Cond) {
     59   %V1 = load i32, i32* %P
     60   br i1 %Cond, label %T, label %F
     61 T:
     62   store i32 4, i32* %P
     63   ret i32 42
     64 F:
     65   %V2 = load i32, i32* %P
     66   %Diff = sub i32 %V1, %V2
     67   ret i32 %Diff
     68   ; CHECK: F:
     69   ; CHECK: ret i32 0
     70 }
     71 
     72 ; CHECK-LABEL: @test3a(
     73 define i32 @test3a(i32 *%P, i1 %Cond, i1 %b) {
     74   %V1 = load i32, i32* %P
     75   br i1 %Cond, label %T, label %F
     76 T:
     77   store i32 4, i32* %P
     78   ret i32 42
     79 F:
     80   tail call void @llvm.assume(i1 %b)
     81   %V2 = load i32, i32* %P
     82   %Diff = sub i32 %V1, %V2
     83   ret i32 %Diff
     84   ; CHECK: F:
     85   ; CHECK: ret i32 0
     86 }
     87 
     88 ;; Cross block load value numbering stops when stores happen.
     89 ; CHECK-LABEL: @test4(
     90 define i32 @test4(i32 *%P, i1 %Cond) {
     91   %V1 = load i32, i32* %P
     92   br i1 %Cond, label %T, label %F
     93 T:
     94   ret i32 42
     95 F:
     96   ; Clobbers V1
     97   store i32 42, i32* %P
     98   
     99   %V2 = load i32, i32* %P
    100   %Diff = sub i32 %V1, %V2
    101   ret i32 %Diff
    102   ; CHECK: F:
    103   ; CHECK: ret i32 %Diff
    104 }
    105 
    106 declare i32 @func(i32 *%P) readonly
    107 
    108 ;; Simple call CSE'ing.
    109 ; CHECK-LABEL: @test5(
    110 define i32 @test5(i32 *%P) {
    111   %V1 = call i32 @func(i32* %P)
    112   %V2 = call i32 @func(i32* %P)
    113   %Diff = sub i32 %V1, %V2
    114   ret i32 %Diff
    115   ; CHECK: ret i32 0
    116 }
    117 
    118 ;; Trivial Store->load forwarding
    119 ; CHECK-LABEL: @test6(
    120 define i32 @test6(i32 *%P) {
    121   store i32 42, i32* %P
    122   %V1 = load i32, i32* %P
    123   ret i32 %V1
    124   ; CHECK: ret i32 42
    125 }
    126 
    127 ; CHECK-LABEL: @test6a(
    128 define i32 @test6a(i32 *%P, i1 %b) {
    129   store i32 42, i32* %P
    130   tail call void @llvm.assume(i1 %b)
    131   %V1 = load i32, i32* %P
    132   ret i32 %V1
    133   ; CHECK: ret i32 42
    134 }
    135 
    136 ;; Trivial dead store elimination.
    137 ; CHECK-LABEL: @test7(
    138 define void @test7(i32 *%P) {
    139   store i32 42, i32* %P
    140   store i32 45, i32* %P
    141   ret void
    142   ; CHECK-NEXT: store i32 45
    143   ; CHECK-NEXT: ret void
    144 }
    145 
    146 ;; Readnone functions aren't invalidated by stores.
    147 ; CHECK-LABEL: @test8(
    148 define i32 @test8(i32 *%P) {
    149   %V1 = call i32 @func(i32* %P) readnone
    150   store i32 4, i32* %P
    151   %V2 = call i32 @func(i32* %P) readnone
    152   %Diff = sub i32 %V1, %V2
    153   ret i32 %Diff
    154   ; CHECK: ret i32 0
    155 }
    156 
    157 ;; Trivial DSE can't be performed across a readonly call.  The call
    158 ;; can observe the earlier write.
    159 ; CHECK-LABEL: @test9(
    160 define i32 @test9(i32 *%P) {
    161   store i32 4, i32* %P
    162   %V1 = call i32 @func(i32* %P) readonly
    163   store i32 5, i32* %P        
    164   ret i32 %V1
    165   ; CHECK: store i32 4, i32* %P        
    166   ; CHECK-NEXT: %V1 = call i32 @func(i32* %P)
    167   ; CHECK-NEXT: store i32 5, i32* %P        
    168   ; CHECK-NEXT: ret i32 %V1
    169 }
    170 
    171 ;; Trivial DSE can be performed across a readnone call.
    172 ; CHECK-LABEL: @test10
    173 define i32 @test10(i32 *%P) {
    174   store i32 4, i32* %P
    175   %V1 = call i32 @func(i32* %P) readnone
    176   store i32 5, i32* %P        
    177   ret i32 %V1
    178   ; CHECK-NEXT: %V1 = call i32 @func(i32* %P)
    179   ; CHECK-NEXT: store i32 5, i32* %P        
    180   ; CHECK-NEXT: ret i32 %V1
    181 }
    182 
    183 ;; Trivial dead store elimination - should work for an entire series of dead stores too.
    184 ; CHECK-LABEL: @test11(
    185 define void @test11(i32 *%P) {
    186   store i32 42, i32* %P
    187   store i32 43, i32* %P
    188   store i32 44, i32* %P
    189   store i32 45, i32* %P
    190   ret void
    191   ; CHECK-NEXT: store i32 45
    192   ; CHECK-NEXT: ret void
    193 }
    194 
    195 ; CHECK-LABEL: @test12(
    196 define i32 @test12(i1 %B, i32* %P1, i32* %P2) {
    197   %load0 = load i32, i32* %P1
    198   %1 = load atomic i32, i32* %P2 seq_cst, align 4
    199   %load1 = load i32, i32* %P1
    200   %sel = select i1 %B, i32 %load0, i32 %load1
    201   ret i32 %sel
    202   ; CHECK: load i32, i32* %P1
    203   ; CHECK: load i32, i32* %P1
    204 }
    205 
    206 define void @dse1(i32 *%P) {
    207 ; CHECK-LABEL: @dse1
    208 ; CHECK-NOT: store
    209   %v = load i32, i32* %P
    210   store i32 %v, i32* %P
    211   ret void
    212 }
    213 
    214 define void @dse2(i32 *%P) {
    215 ; CHECK-LABEL: @dse2
    216 ; CHECK-NOT: store
    217   %v = load atomic i32, i32* %P seq_cst, align 4
    218   store i32 %v, i32* %P
    219   ret void
    220 }
    221 
    222 define void @dse3(i32 *%P) {
    223 ; CHECK-LABEL: @dse3
    224 ; CHECK-NOT: store
    225   %v = load atomic i32, i32* %P seq_cst, align 4
    226   store atomic i32 %v, i32* %P unordered, align 4
    227   ret void
    228 }
    229 
    230 define i32 @dse4(i32 *%P, i32 *%Q) {
    231 ; CHECK-LABEL: @dse4
    232 ; CHECK-NOT: store
    233 ; CHECK: ret i32 0
    234   %a = load i32, i32* %Q
    235   %v = load atomic i32, i32* %P unordered, align 4
    236   store atomic i32 %v, i32* %P unordered, align 4
    237   %b = load i32, i32* %Q
    238   %res = sub i32 %a, %b
    239   ret i32 %res
    240 }
    241 
    242 ; Note that in this example, %P and %Q could in fact be the same
    243 ; pointer.  %v could be different than the value observed for %a
    244 ; and that's okay because we're using relaxed memory ordering.  
    245 ; The only guarantee we have to provide is that each of the loads 
    246 ; has to observe some value written to that location.  We  do 
    247 ; not have to respect the order in which those writes were done.  
    248 define i32 @dse5(i32 *%P, i32 *%Q) {
    249 ; CHECK-LABEL: @dse5
    250 ; CHECK-NOT: store
    251 ; CHECK: ret i32 0
    252   %v = load atomic i32, i32* %P unordered, align 4
    253   %a = load atomic i32, i32* %Q unordered, align 4
    254   store atomic i32 %v, i32* %P unordered, align 4
    255   %b = load atomic i32, i32* %Q unordered, align 4
    256   %res = sub i32 %a, %b
    257   ret i32 %res
    258 }
    259 
    260 
    261 define void @dse_neg1(i32 *%P) {
    262 ; CHECK-LABEL: @dse_neg1
    263 ; CHECK: store
    264   %v = load i32, i32* %P
    265   store i32 5, i32* %P
    266   ret void
    267 }
    268 
    269 ; Could remove the store, but only if ordering was somehow
    270 ; encoded.
    271 define void @dse_neg2(i32 *%P) {
    272 ; CHECK-LABEL: @dse_neg2
    273 ; CHECK: store
    274   %v = load i32, i32* %P
    275   store atomic i32 %v, i32* %P seq_cst, align 4
    276   ret void
    277 }
    278 
    279