summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/InstCombine/atomic.ll
blob: 1d24248e73ee5746fa37143b0d2fc06680e0c577 (plain)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
; RUN: opt -S < %s -instcombine | 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"

; Check transforms involving atomic operations

define i32 @test1(i32* %p) {
; CHECK-LABEL: define i32 @test1(
; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4
; CHECK: shl i32 %x, 1
  %x = load atomic i32, i32* %p seq_cst, align 4
  %y = load i32, i32* %p, align 4
  %z = add i32 %x, %y
  ret i32 %z
}

define i32 @test2(i32* %p) {
; CHECK-LABEL: define i32 @test2(
; CHECK: %x = load volatile i32, i32* %p, align 4
; CHECK: %y = load volatile i32, i32* %p, align 4
  %x = load volatile i32, i32* %p, align 4
  %y = load volatile i32, i32* %p, align 4
  %z = add i32 %x, %y
  ret i32 %z
}

; The exact semantics of mixing volatile and non-volatile on the same
; memory location are a bit unclear, but conservatively, we know we don't
; want to remove the volatile.
define i32 @test3(i32* %p) {
; CHECK-LABEL: define i32 @test3(
; CHECK: %x = load volatile i32, i32* %p, align 4
  %x = load volatile i32, i32* %p, align 4
  %y = load i32, i32* %p, align 4
  %z = add i32 %x, %y
  ret i32 %z
}

; Forwarding from a stronger ordered atomic is fine
define i32 @test4(i32* %p) {
; CHECK-LABEL: define i32 @test4(
; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4
; CHECK: shl i32 %x, 1
  %x = load atomic i32, i32* %p seq_cst, align 4
  %y = load atomic i32, i32* %p unordered, align 4
  %z = add i32 %x, %y
  ret i32 %z
}

; Forwarding from a non-atomic is not.  (The earlier load 
; could in priciple be promoted to atomic and then forwarded, 
; but we can't just  drop the atomic from the load.)
define i32 @test5(i32* %p) {
; CHECK-LABEL: define i32 @test5(
; CHECK: %x = load atomic i32, i32* %p unordered, align 4
  %x = load atomic i32, i32* %p unordered, align 4
  %y = load i32, i32* %p, align 4
  %z = add i32 %x, %y
  ret i32 %z
}

; Forwarding atomic to atomic is fine
define i32 @test6(i32* %p) {
; CHECK-LABEL: define i32 @test6(
; CHECK: %x = load atomic i32, i32* %p unordered, align 4
; CHECK: shl i32 %x, 1
  %x = load atomic i32, i32* %p unordered, align 4
  %y = load atomic i32, i32* %p unordered, align 4
  %z = add i32 %x, %y
  ret i32 %z
}

; FIXME: we currently don't do anything for monotonic
define i32 @test7(i32* %p) {
; CHECK-LABEL: define i32 @test7(
; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4
; CHECK: %y = load atomic i32, i32* %p monotonic, align 4
  %x = load atomic i32, i32* %p seq_cst, align 4
  %y = load atomic i32, i32* %p monotonic, align 4
  %z = add i32 %x, %y
  ret i32 %z
}

; FIXME: We could forward in racy code
define i32 @test8(i32* %p) {
; CHECK-LABEL: define i32 @test8(
; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4
; CHECK: %y = load atomic i32, i32* %p acquire, align 4
  %x = load atomic i32, i32* %p seq_cst, align 4
  %y = load atomic i32, i32* %p acquire, align 4
  %z = add i32 %x, %y
  ret i32 %z
}

; An unordered access to null is still unreachable.  There's no
; ordering imposed.
define i32 @test9() {
; CHECK-LABEL: define i32 @test9(
; CHECK: store i32 undef, i32* null
  %x = load atomic i32, i32* null unordered, align 4
  ret i32 %x
}

; FIXME: Could also fold
define i32 @test10() {
; CHECK-LABEL: define i32 @test10(
; CHECK: load atomic i32, i32* null monotonic
  %x = load atomic i32, i32* null monotonic, align 4
  ret i32 %x
}

; Would this be legal to fold?  Probably?
define i32 @test11() {
; CHECK-LABEL: define i32 @test11(
; CHECK: load atomic i32, i32* null seq_cst
  %x = load atomic i32, i32* null seq_cst, align 4
  ret i32 %x
}

; An unordered access to null is still unreachable.  There's no
; ordering imposed.
define i32 @test12() {
; CHECK-LABEL: define i32 @test12(
; CHECK: store atomic i32 undef, i32* null
  store atomic i32 0, i32* null unordered, align 4
  ret i32 0
}

; FIXME: Could also fold
define i32 @test13() {
; CHECK-LABEL: define i32 @test13(
; CHECK: store atomic i32 0, i32* null monotonic
  store atomic i32 0, i32* null monotonic, align 4
  ret i32 0
}

; Would this be legal to fold?  Probably?
define i32 @test14() {
; CHECK-LABEL: define i32 @test14(
; CHECK: store atomic i32 0, i32* null seq_cst
  store atomic i32 0, i32* null seq_cst, align 4
  ret i32 0
}


OpenPOWER on IntegriCloud