1; RUN: opt -basicaa -dse -S < %s | FileCheck %s 2 3target 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" 4target 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 13declare void @randomop(i32*) 14 15; DSE across unordered store (allowed) 16define 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) 27define 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) 37define 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) 46define 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). 57define 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). 67define 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) 79define 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) 90define 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) 101define 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) 112define 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. 123define 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