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