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