Home | History | Annotate | Download | only in DeadStoreElimination
      1 ; RUN: opt -basicaa -dse -S < %s | FileCheck %s
      2 
      3 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
      4 target triple = "x86_64-apple-macosx10.7.0"
      5 
      6 ; Sanity tests for atomic stores.
      7 ; Note that it turns out essentially every transformation DSE does is legal on
      8 ; atomic ops, just some transformations are not allowed across release-acquire pairs.
      9 
     10 @x = common global i32 0, align 4
     11 @y = common global i32 0, align 4
     12 
     13 declare void @randomop(i32*)
     14 
     15 ; DSE across unordered store (allowed)
     16 define void @test1() {
     17 ; CHECK-LABEL: test1
     18 ; CHECK-NOT: store i32 0
     19 ; CHECK: store i32 1
     20   store i32 0, i32* @x
     21   store atomic i32 0, i32* @y unordered, align 4
     22   store i32 1, i32* @x
     23   ret void
     24 }
     25 
     26 ; DSE remove unordered store (allowed)
     27 define void @test4() {
     28 ; CHECK-LABEL: test4
     29 ; CHECK-NOT: store atomic
     30 ; CHECK: store i32 1
     31   store atomic i32 0, i32* @x unordered, align 4
     32   store i32 1, i32* @x
     33   ret void
     34 }
     35 
     36 ; DSE unordered store overwriting non-atomic store (allowed)
     37 define void @test5() {
     38 ; CHECK-LABEL: test5
     39 ; CHECK: store atomic i32 1
     40   store i32 0, i32* @x
     41   store atomic i32 1, i32* @x unordered, align 4
     42   ret void
     43 }
     44 
     45 ; DSE no-op unordered atomic store (allowed)
     46 define void @test6() {
     47 ; CHECK-LABEL: test6
     48 ; CHECK-NOT: store
     49 ; CHECK: ret void
     50   %x = load atomic i32, i32* @x unordered, align 4
     51   store atomic i32 %x, i32* @x unordered, align 4
     52   ret void
     53 }
     54 
     55 ; DSE seq_cst store (be conservative; DSE doesn't have infrastructure
     56 ; to reason about atomic operations).
     57 define void @test7() {
     58 ; CHECK-LABEL: test7
     59 ; CHECK: store atomic
     60   %a = alloca i32
     61   store atomic i32 0, i32* %a seq_cst, align 4
     62   ret void
     63 }
     64 
     65 ; DSE and seq_cst load (be conservative; DSE doesn't have infrastructure
     66 ; to reason about atomic operations).
     67 define i32 @test8() {
     68 ; CHECK-LABEL: test8
     69 ; CHECK: store
     70 ; CHECK: load atomic
     71   %a = alloca i32
     72   call void @randomop(i32* %a)
     73   store i32 0, i32* %a, align 4
     74   %x = load atomic i32, i32* @x seq_cst, align 4
     75   ret i32 %x
     76 }
     77 
     78 ; DSE across monotonic load (allowed as long as the eliminated store isUnordered)
     79 define i32 @test9() {
     80 ; CHECK-LABEL: test9
     81 ; CHECK-NOT: store i32 0
     82 ; CHECK: store i32 1
     83   store i32 0, i32* @x
     84   %x = load atomic i32, i32* @y monotonic, align 4
     85   store i32 1, i32* @x
     86   ret i32 %x
     87 }
     88 
     89 ; DSE across monotonic store (allowed as long as the eliminated store isUnordered)
     90 define void @test10() {
     91 ; CHECK-LABEL: test10
     92 ; CHECK-NOT: store i32 0
     93 ; CHECK: store i32 1
     94   store i32 0, i32* @x
     95   store atomic i32 42, i32* @y monotonic, align 4
     96   store i32 1, i32* @x
     97   ret void
     98 }
     99 
    100 ; DSE across monotonic load (forbidden since the eliminated store is atomic)
    101 define i32 @test11() {
    102 ; CHECK-LABEL: test11
    103 ; CHECK: store atomic i32 0
    104 ; CHECK: store atomic i32 1
    105   store atomic i32 0, i32* @x monotonic, align 4
    106   %x = load atomic i32, i32* @y monotonic, align 4
    107   store atomic i32 1, i32* @x monotonic, align 4
    108   ret i32 %x
    109 }
    110 
    111 ; DSE across monotonic store (forbidden since the eliminated store is atomic)
    112 define void @test12() {
    113 ; CHECK-LABEL: test12
    114 ; CHECK: store atomic i32 0
    115 ; CHECK: store atomic i32 1
    116   store atomic i32 0, i32* @x monotonic, align 4
    117   store atomic i32 42, i32* @y monotonic, align 4
    118   store atomic i32 1, i32* @x monotonic, align 4
    119   ret void
    120 }
    121 
    122 ; But DSE is not allowed across a release-acquire pair.
    123 define i32 @test15() {
    124 ; CHECK-LABEL: test15
    125 ; CHECK: store i32 0
    126 ; CHECK: store i32 1
    127   store i32 0, i32* @x
    128   store atomic i32 0, i32* @y release, align 4
    129   %x = load atomic i32, i32* @y acquire, align 4
    130   store i32 1, i32* @x
    131   ret i32 %x
    132 }
    133