|
| 1 | +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
1 | 2 | ; RUN: opt -passes=atomic-expand -codegen-opt-level=1 -S -mtriple=thumbv7s-apple-ios7.0 %s | FileCheck %s
|
2 | 3 |
|
3 |
| -define i32 @test_cmpxchg_seq_cst(ptr %addr, i32 %desired, i32 %new) { |
4 |
| -; CHECK-LABEL: @test_cmpxchg_seq_cst |
5 | 4 | ; Intrinsic for "dmb ishst" is then expected
|
6 |
| -; CHECK: br label %[[START:.*]] |
7 |
| - |
8 |
| -; CHECK: [[START]]: |
9 |
| -; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) %addr) |
10 |
| -; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired |
11 |
| -; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] |
12 |
| - |
13 |
| -; CHECK: [[FENCED_STORE]]: |
14 |
| -; CHECK: call void @llvm.arm.dmb(i32 10) |
15 |
| -; CHECK: br label %[[TRY_STORE:.*]] |
16 |
| - |
17 |
| -; CHECK: [[TRY_STORE]]: |
18 |
| -; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ] |
19 |
| -; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0(i32 %new, ptr elementtype(i32) %addr) |
20 |
| -; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0 |
21 |
| -; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]] |
22 |
| - |
23 |
| -; CHECK: [[SUCCESS_BB]]: |
24 |
| -; CHECK: call void @llvm.arm.dmb(i32 11) |
25 |
| -; CHECK: br label %[[END:.*]] |
26 |
| - |
27 |
| -; CHECK: [[NO_STORE_BB]]: |
28 |
| -; CHECK: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[LOADED]], %[[START]] ] |
29 |
| -; CHECK: call void @llvm.arm.clrex() |
30 |
| -; CHECK: br label %[[FAILURE_BB]] |
31 |
| - |
32 |
| -; CHECK: [[FAILURE_BB]]: |
33 |
| -; CHECK: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ], [ [[LOADED_TRYSTORE]], %[[TRY_STORE]] ] |
34 |
| -; CHECK: call void @llvm.arm.dmb(i32 11) |
35 |
| -; CHECK: br label %[[END]] |
36 |
| - |
37 |
| -; CHECK: [[END]]: |
38 |
| -; CHECK: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ] |
39 |
| -; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ] |
40 |
| -; CHECK: ret i32 [[LOADED_EXIT]] |
41 |
| - |
| 5 | +define i32 @test_cmpxchg_seq_cst(ptr %addr, i32 %desired, i32 %new) { |
| 6 | +; CHECK-LABEL: define i32 @test_cmpxchg_seq_cst( |
| 7 | +; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) { |
| 8 | +; CHECK-NEXT: br label %[[CMPXCHG_START:.*]] |
| 9 | +; CHECK: [[CMPXCHG_START]]: |
| 10 | +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]]) |
| 11 | +; CHECK-NEXT: [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]] |
| 12 | +; CHECK-NEXT: br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]] |
| 13 | +; CHECK: [[CMPXCHG_FENCEDSTORE]]: |
| 14 | +; CHECK-NEXT: call void @llvm.arm.dmb(i32 10) |
| 15 | +; CHECK-NEXT: br label %[[CMPXCHG_TRYSTORE:.*]] |
| 16 | +; CHECK: [[CMPXCHG_TRYSTORE]]: |
| 17 | +; CHECK-NEXT: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ] |
| 18 | +; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]]) |
| 19 | +; CHECK-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0 |
| 20 | +; CHECK-NEXT: br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]] |
| 21 | +; CHECK: [[CMPXCHG_RELEASEDLOAD:.*:]] |
| 22 | +; CHECK-NEXT: unreachable |
| 23 | +; CHECK: [[CMPXCHG_SUCCESS]]: |
| 24 | +; CHECK-NEXT: call void @llvm.arm.dmb(i32 11) |
| 25 | +; CHECK-NEXT: br label %[[CMPXCHG_END:.*]] |
| 26 | +; CHECK: [[CMPXCHG_NOSTORE]]: |
| 27 | +; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ] |
| 28 | +; CHECK-NEXT: call void @llvm.arm.clrex() |
| 29 | +; CHECK-NEXT: br label %[[CMPXCHG_FAILURE]] |
| 30 | +; CHECK: [[CMPXCHG_FAILURE]]: |
| 31 | +; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ] |
| 32 | +; CHECK-NEXT: call void @llvm.arm.dmb(i32 11) |
| 33 | +; CHECK-NEXT: br label %[[CMPXCHG_END]] |
| 34 | +; CHECK: [[CMPXCHG_END]]: |
| 35 | +; CHECK-NEXT: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ] |
| 36 | +; CHECK-NEXT: [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ] |
| 37 | +; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } poison, i32 [[LOADED_EXIT]], 0 |
| 38 | +; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { i32, i1 } [[TMP3]], i1 [[SUCCESS1]], 1 |
| 39 | +; CHECK-NEXT: [[OLDVAL:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0 |
| 40 | +; CHECK-NEXT: ret i32 [[LOADED_EXIT]] |
| 41 | +; |
42 | 42 | %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst seq_cst
|
43 | 43 | %oldval = extractvalue { i32, i1 } %pair, 0
|
44 | 44 | ret i32 %oldval
|
45 | 45 | }
|
46 | 46 |
|
47 | 47 | define i1 @test_cmpxchg_weak_fail(ptr %addr, i32 %desired, i32 %new) {
|
48 |
| -; CHECK-LABEL: @test_cmpxchg_weak_fail |
49 |
| -; CHECK: br label %[[START:.*]] |
50 |
| - |
51 |
| -; CHECK: [[START]]: |
52 |
| -; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) %addr) |
53 |
| -; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired |
54 |
| -; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] |
55 |
| - |
56 |
| -; CHECK: [[FENCED_STORE]]: |
57 |
| -; CHECK: call void @llvm.arm.dmb(i32 10) |
58 |
| -; CHECK: br label %[[TRY_STORE:.*]] |
59 |
| - |
60 |
| -; CHECK: [[TRY_STORE]]: |
61 |
| -; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0(i32 %new, ptr elementtype(i32) %addr) |
62 |
| -; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0 |
63 |
| -; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]] |
64 |
| - |
65 |
| -; CHECK: [[SUCCESS_BB]]: |
66 |
| -; CHECK: call void @llvm.arm.dmb(i32 11) |
67 |
| -; CHECK: br label %[[END:.*]] |
68 |
| - |
69 |
| -; CHECK: [[NO_STORE_BB]]: |
70 |
| -; CHECK: call void @llvm.arm.clrex() |
71 |
| -; CHECK: br label %[[FAILURE_BB]] |
72 |
| - |
73 |
| -; CHECK: [[FAILURE_BB]]: |
74 |
| -; CHECK-NOT: dmb |
75 |
| -; CHECK: br label %[[END]] |
76 |
| - |
77 |
| -; CHECK: [[END]]: |
78 |
| -; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ] |
79 |
| -; CHECK: ret i1 [[SUCCESS]] |
80 |
| - |
| 48 | +; CHECK-LABEL: define i1 @test_cmpxchg_weak_fail( |
| 49 | +; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) { |
| 50 | +; CHECK-NEXT: br label %[[CMPXCHG_START:.*]] |
| 51 | +; CHECK: [[CMPXCHG_START]]: |
| 52 | +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]]) |
| 53 | +; CHECK-NEXT: [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]] |
| 54 | +; CHECK-NEXT: br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]] |
| 55 | +; CHECK: [[CMPXCHG_FENCEDSTORE]]: |
| 56 | +; CHECK-NEXT: call void @llvm.arm.dmb(i32 10) |
| 57 | +; CHECK-NEXT: br label %[[CMPXCHG_TRYSTORE:.*]] |
| 58 | +; CHECK: [[CMPXCHG_TRYSTORE]]: |
| 59 | +; CHECK-NEXT: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ] |
| 60 | +; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]]) |
| 61 | +; CHECK-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0 |
| 62 | +; CHECK-NEXT: br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]] |
| 63 | +; CHECK: [[CMPXCHG_RELEASEDLOAD:.*:]] |
| 64 | +; CHECK-NEXT: unreachable |
| 65 | +; CHECK: [[CMPXCHG_SUCCESS]]: |
| 66 | +; CHECK-NEXT: call void @llvm.arm.dmb(i32 11) |
| 67 | +; CHECK-NEXT: br label %[[CMPXCHG_END:.*]] |
| 68 | +; CHECK: [[CMPXCHG_NOSTORE]]: |
| 69 | +; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ] |
| 70 | +; CHECK-NEXT: call void @llvm.arm.clrex() |
| 71 | +; CHECK-NEXT: br label %[[CMPXCHG_FAILURE]] |
| 72 | +; CHECK: [[CMPXCHG_FAILURE]]: |
| 73 | +; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ] |
| 74 | +; CHECK-NEXT: br label %[[CMPXCHG_END]] |
| 75 | +; CHECK: [[CMPXCHG_END]]: |
| 76 | +; CHECK-NEXT: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ] |
| 77 | +; CHECK-NEXT: [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ] |
| 78 | +; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } poison, i32 [[LOADED_EXIT]], 0 |
| 79 | +; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { i32, i1 } [[TMP3]], i1 [[SUCCESS1]], 1 |
| 80 | +; CHECK-NEXT: [[OLDVAL:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1 |
| 81 | +; CHECK-NEXT: ret i1 [[SUCCESS1]] |
| 82 | +; |
81 | 83 | %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst monotonic
|
82 | 84 | %oldval = extractvalue { i32, i1 } %pair, 1
|
83 | 85 | ret i1 %oldval
|
84 | 86 | }
|
85 | 87 |
|
86 | 88 | define i32 @test_cmpxchg_monotonic(ptr %addr, i32 %desired, i32 %new) {
|
87 |
| -; CHECK-LABEL: @test_cmpxchg_monotonic |
88 |
| -; CHECK-NOT: dmb |
89 |
| -; CHECK: br label %[[START:.*]] |
90 |
| - |
91 |
| -; CHECK: [[START]]: |
92 |
| -; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) %addr) |
93 |
| -; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired |
94 |
| -; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] |
95 |
| - |
96 |
| -; CHECK: [[FENCED_STORE]]: |
97 |
| -; CHECK-NEXT: br label %[[TRY_STORE]] |
98 |
| - |
99 |
| -; CHECK: [[TRY_STORE]]: |
100 |
| -; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ] |
101 |
| -; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0(i32 %new, ptr elementtype(i32) %addr) |
102 |
| -; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0 |
103 |
| -; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]] |
104 |
| - |
105 |
| -; CHECK: [[SUCCESS_BB]]: |
106 |
| -; CHECK-NOT: dmb |
107 |
| -; CHECK: br label %[[END:.*]] |
108 |
| - |
109 |
| -; CHECK: [[NO_STORE_BB]]: |
110 |
| -; CHECK: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[LOADED]], %[[START]] ] |
111 |
| -; CHECK: call void @llvm.arm.clrex() |
112 |
| -; CHECK: br label %[[FAILURE_BB]] |
113 |
| - |
114 |
| -; CHECK: [[FAILURE_BB]]: |
115 |
| -; CHECK: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ], [ [[LOADED_TRYSTORE]], %[[TRY_STORE]] ] |
116 |
| -; CHECK-NOT: dmb |
117 |
| -; CHECK: br label %[[END]] |
118 |
| - |
119 |
| -; CHECK: [[END]]: |
120 |
| -; CHECK: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ] |
121 |
| -; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ] |
122 |
| -; CHECK: ret i32 [[LOADED_EXIT]] |
123 |
| - |
| 89 | +; CHECK-LABEL: define i32 @test_cmpxchg_monotonic( |
| 90 | +; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) { |
| 91 | +; CHECK-NEXT: br label %[[CMPXCHG_START:.*]] |
| 92 | +; CHECK: [[CMPXCHG_START]]: |
| 93 | +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]]) |
| 94 | +; CHECK-NEXT: [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]] |
| 95 | +; CHECK-NEXT: br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]] |
| 96 | +; CHECK: [[CMPXCHG_FENCEDSTORE]]: |
| 97 | +; CHECK-NEXT: br label %[[CMPXCHG_TRYSTORE:.*]] |
| 98 | +; CHECK: [[CMPXCHG_TRYSTORE]]: |
| 99 | +; CHECK-NEXT: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ] |
| 100 | +; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]]) |
| 101 | +; CHECK-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0 |
| 102 | +; CHECK-NEXT: br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]] |
| 103 | +; CHECK: [[CMPXCHG_RELEASEDLOAD:.*:]] |
| 104 | +; CHECK-NEXT: unreachable |
| 105 | +; CHECK: [[CMPXCHG_SUCCESS]]: |
| 106 | +; CHECK-NEXT: br label %[[CMPXCHG_END:.*]] |
| 107 | +; CHECK: [[CMPXCHG_NOSTORE]]: |
| 108 | +; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ] |
| 109 | +; CHECK-NEXT: call void @llvm.arm.clrex() |
| 110 | +; CHECK-NEXT: br label %[[CMPXCHG_FAILURE]] |
| 111 | +; CHECK: [[CMPXCHG_FAILURE]]: |
| 112 | +; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ] |
| 113 | +; CHECK-NEXT: br label %[[CMPXCHG_END]] |
| 114 | +; CHECK: [[CMPXCHG_END]]: |
| 115 | +; CHECK-NEXT: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ] |
| 116 | +; CHECK-NEXT: [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ] |
| 117 | +; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } poison, i32 [[LOADED_EXIT]], 0 |
| 118 | +; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { i32, i1 } [[TMP3]], i1 [[SUCCESS1]], 1 |
| 119 | +; CHECK-NEXT: [[OLDVAL:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0 |
| 120 | +; CHECK-NEXT: ret i32 [[LOADED_EXIT]] |
| 121 | +; |
124 | 122 | %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new monotonic monotonic
|
125 | 123 | %oldval = extractvalue { i32, i1 } %pair, 0
|
126 | 124 | ret i32 %oldval
|
127 | 125 | }
|
128 | 126 |
|
129 | 127 | define i32 @test_cmpxchg_seq_cst_minsize(ptr %addr, i32 %desired, i32 %new) minsize {
|
130 |
| -; CHECK-LABEL: @test_cmpxchg_seq_cst_minsize |
131 |
| -; CHECK: br label %[[START:.*]] |
132 |
| - |
133 |
| -; CHECK: [[START]]: |
134 |
| -; CHECK: [[LOADED:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) %addr) |
135 |
| -; CHECK: [[SHOULD_STORE:%.*]] = icmp eq i32 [[LOADED]], %desired |
136 |
| -; CHECK: br i1 [[SHOULD_STORE]], label %[[FENCED_STORE:.*]], label %[[NO_STORE_BB:.*]] |
137 |
| - |
138 |
| -; CHECK: [[FENCED_STORE]]: |
139 |
| -; CHECK: call void @llvm.arm.dmb(i32 10) |
140 |
| -; CHECK: br label %[[TRY_STORE:.*]] |
141 |
| - |
142 |
| -; CHECK: [[TRY_STORE]]: |
143 |
| -; CHECK: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[LOADED]], %[[FENCED_STORE]] ] |
144 |
| -; CHECK: [[STREX:%.*]] = call i32 @llvm.arm.strex.p0(i32 %new, ptr elementtype(i32) %addr) |
145 |
| -; CHECK: [[SUCCESS:%.*]] = icmp eq i32 [[STREX]], 0 |
146 |
| -; CHECK: br i1 [[SUCCESS]], label %[[SUCCESS_BB:.*]], label %[[FAILURE_BB:.*]] |
147 |
| - |
148 |
| -; CHECK: [[SUCCESS_BB]]: |
149 |
| -; CHECK: call void @llvm.arm.dmb(i32 11) |
150 |
| -; CHECK: br label %[[END:.*]] |
151 |
| - |
152 |
| -; CHECK: [[NO_STORE_BB]]: |
153 |
| -; CHECK: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[LOADED]], %[[START]] ] |
154 |
| -; CHECK: call void @llvm.arm.clrex() |
155 |
| -; CHECK: br label %[[FAILURE_BB]] |
156 |
| - |
157 |
| -; CHECK: [[FAILURE_BB]]: |
158 |
| -; CHECK: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[NO_STORE_BB]] ], [ [[LOADED_TRYSTORE]], %[[TRY_STORE]] ] |
159 |
| -; CHECK: call void @llvm.arm.dmb(i32 11) |
160 |
| -; CHECK: br label %[[END]] |
161 |
| - |
162 |
| -; CHECK: [[END]]: |
163 |
| -; CHECK: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[SUCCESS_BB]] ], [ [[LOADED_FAILURE]], %[[FAILURE_BB]] ] |
164 |
| -; CHECK: [[SUCCESS:%.*]] = phi i1 [ true, %[[SUCCESS_BB]] ], [ false, %[[FAILURE_BB]] ] |
165 |
| -; CHECK: ret i32 [[LOADED_EXIT]] |
166 |
| - |
| 128 | +; CHECK-LABEL: define i32 @test_cmpxchg_seq_cst_minsize( |
| 129 | +; CHECK-SAME: ptr [[ADDR:%.*]], i32 [[DESIRED:%.*]], i32 [[NEW:%.*]]) #[[ATTR0:[0-9]+]] { |
| 130 | +; CHECK-NEXT: br label %[[CMPXCHG_START:.*]] |
| 131 | +; CHECK: [[CMPXCHG_START]]: |
| 132 | +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[ADDR]]) |
| 133 | +; CHECK-NEXT: [[SHOULD_STORE:%.*]] = icmp eq i32 [[TMP1]], [[DESIRED]] |
| 134 | +; CHECK-NEXT: br i1 [[SHOULD_STORE]], label %[[CMPXCHG_FENCEDSTORE:.*]], label %[[CMPXCHG_NOSTORE:.*]] |
| 135 | +; CHECK: [[CMPXCHG_FENCEDSTORE]]: |
| 136 | +; CHECK-NEXT: call void @llvm.arm.dmb(i32 10) |
| 137 | +; CHECK-NEXT: br label %[[CMPXCHG_TRYSTORE:.*]] |
| 138 | +; CHECK: [[CMPXCHG_TRYSTORE]]: |
| 139 | +; CHECK-NEXT: [[LOADED_TRYSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_FENCEDSTORE]] ] |
| 140 | +; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[NEW]], ptr elementtype(i32) [[ADDR]]) |
| 141 | +; CHECK-NEXT: [[SUCCESS:%.*]] = icmp eq i32 [[TMP2]], 0 |
| 142 | +; CHECK-NEXT: br i1 [[SUCCESS]], label %[[CMPXCHG_SUCCESS:.*]], label %[[CMPXCHG_FAILURE:.*]] |
| 143 | +; CHECK: [[CMPXCHG_RELEASEDLOAD:.*:]] |
| 144 | +; CHECK-NEXT: unreachable |
| 145 | +; CHECK: [[CMPXCHG_SUCCESS]]: |
| 146 | +; CHECK-NEXT: call void @llvm.arm.dmb(i32 11) |
| 147 | +; CHECK-NEXT: br label %[[CMPXCHG_END:.*]] |
| 148 | +; CHECK: [[CMPXCHG_NOSTORE]]: |
| 149 | +; CHECK-NEXT: [[LOADED_NOSTORE:%.*]] = phi i32 [ [[TMP1]], %[[CMPXCHG_START]] ] |
| 150 | +; CHECK-NEXT: call void @llvm.arm.clrex() |
| 151 | +; CHECK-NEXT: br label %[[CMPXCHG_FAILURE]] |
| 152 | +; CHECK: [[CMPXCHG_FAILURE]]: |
| 153 | +; CHECK-NEXT: [[LOADED_FAILURE:%.*]] = phi i32 [ [[LOADED_NOSTORE]], %[[CMPXCHG_NOSTORE]] ], [ [[LOADED_TRYSTORE]], %[[CMPXCHG_TRYSTORE]] ] |
| 154 | +; CHECK-NEXT: call void @llvm.arm.dmb(i32 11) |
| 155 | +; CHECK-NEXT: br label %[[CMPXCHG_END]] |
| 156 | +; CHECK: [[CMPXCHG_END]]: |
| 157 | +; CHECK-NEXT: [[LOADED_EXIT:%.*]] = phi i32 [ [[LOADED_TRYSTORE]], %[[CMPXCHG_SUCCESS]] ], [ [[LOADED_FAILURE]], %[[CMPXCHG_FAILURE]] ] |
| 158 | +; CHECK-NEXT: [[SUCCESS1:%.*]] = phi i1 [ true, %[[CMPXCHG_SUCCESS]] ], [ false, %[[CMPXCHG_FAILURE]] ] |
| 159 | +; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i32, i1 } poison, i32 [[LOADED_EXIT]], 0 |
| 160 | +; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { i32, i1 } [[TMP3]], i1 [[SUCCESS1]], 1 |
| 161 | +; CHECK-NEXT: [[OLDVAL:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0 |
| 162 | +; CHECK-NEXT: ret i32 [[LOADED_EXIT]] |
| 163 | +; |
167 | 164 | %pair = cmpxchg weak ptr %addr, i32 %desired, i32 %new seq_cst seq_cst
|
168 | 165 | %oldval = extractvalue { i32, i1 } %pair, 0
|
169 | 166 | ret i32 %oldval
|
|
0 commit comments