llvm.org GIT mirror llvm / d6c8a46
[DSE] Add tests for atomic memory intrinsics (NFC) Summary: These tests show that DSE currently does nothing with the atomic memory intrinsics. Future work will teach DSE how to simplify these. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@329845 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Neilson 1 year, 5 months ago
4 changed file(s) with 706 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
2020 ret void
2121 }
2222
23 define void @write4to7_atomic(i32* nocapture %p) {
24 ; CHECK-LABEL: @write4to7_atomic(
25 ; CHECK-NEXT: entry:
26 ; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
27 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
28 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i32 4)
29 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
30 ; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
31 ; CHECK-NEXT: ret void
32 ;
33 entry:
34 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
35 %p3 = bitcast i32* %arrayidx0 to i8*
36 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
37 %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1
38 store atomic i32 1, i32* %arrayidx1 unordered, align 4
39 ret void
40 }
41
2342 define void @write0to3(i32* nocapture %p) {
2443 ; CHECK-LABEL: @write0to3(
2544 ; CHECK-NEXT: entry:
3251 entry:
3352 %p3 = bitcast i32* %p to i8*
3453 call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false)
54 store i32 1, i32* %p, align 4
55 ret void
56 }
57
58 define void @write0to3_atomic(i32* nocapture %p) {
59 ; CHECK-LABEL: @write0to3_atomic(
60 ; CHECK-NEXT: entry:
61 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
62 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i32 4)
63 ; CHECK-NEXT: store atomic i32 1, i32* [[P]] unordered, align 4
64 ; CHECK-NEXT: ret void
65 ;
66 entry:
67 %p3 = bitcast i32* %p to i8*
68 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
69 store atomic i32 1, i32* %p unordered, align 4
70 ret void
71 }
72
73 ; Atomicity of the store is weaker from the memset
74 define void @write0to3_atomic_weaker(i32* nocapture %p) {
75 ; CHECK-LABEL: @write0to3_atomic_weaker(
76 ; CHECK-NEXT: entry:
77 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
78 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i32 4)
79 ; CHECK-NEXT: store i32 1, i32* [[P]], align 4
80 ; CHECK-NEXT: ret void
81 ;
82 entry:
83 %p3 = bitcast i32* %p to i8*
84 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
3585 store i32 1, i32* %p, align 4
3686 ret void
3787 }
54104 ret void
55105 }
56106
107 ; Changing the memset start and length is okay here because the
108 ; store is a multiple of the memset element size
109 define void @write0to7_atomic(i32* nocapture %p) {
110 ; CHECK-LABEL: @write0to7_atomic(
111 ; CHECK-NEXT: entry:
112 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
113 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i32 4)
114 ; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64*
115 ; CHECK-NEXT: store atomic i64 1, i64* [[P4]] unordered, align 8
116 ; CHECK-NEXT: ret void
117 ;
118 entry:
119 %p3 = bitcast i32* %p to i8*
120 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
121 %p4 = bitcast i32* %p to i64*
122 store atomic i64 1, i64* %p4 unordered, align 8
123 ret void
124 }
125
57126 define void @write0to7_2(i32* nocapture %p) {
58127 ; CHECK-LABEL: @write0to7_2(
59128 ; CHECK-NEXT: entry:
74143 ret void
75144 }
76145
146 define void @write0to7_2_atomic(i32* nocapture %p) {
147 ; CHECK-LABEL: @write0to7_2_atomic(
148 ; CHECK-NEXT: entry:
149 ; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
150 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
151 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i32 4)
152 ; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64*
153 ; CHECK-NEXT: store atomic i64 1, i64* [[P4]] unordered, align 8
154 ; CHECK-NEXT: ret void
155 ;
156 entry:
157 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
158 %p3 = bitcast i32* %arrayidx0 to i8*
159 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
160 %p4 = bitcast i32* %p to i64*
161 store atomic i64 1, i64* %p4 unordered, align 8
162 ret void
163 }
164
77165 ; We do not trim the beginning of the eariler write if the alignment of the
78166 ; start pointer is changed.
79167 define void @dontwrite0to3_align8(i32* nocapture %p) {
91179 ret void
92180 }
93181
182 define void @dontwrite0to3_align8_atomic(i32* nocapture %p) {
183 ; CHECK-LABEL: @dontwrite0to3_align8_atomic(
184 ; CHECK-NEXT: entry:
185 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
186 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[P3]], i8 0, i64 32, i32 4)
187 ; CHECK-NEXT: store atomic i32 1, i32* [[P]] unordered, align 4
188 ; CHECK-NEXT: ret void
189 ;
190 entry:
191 %p3 = bitcast i32* %p to i8*
192 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %p3, i8 0, i64 32, i32 4)
193 store atomic i32 1, i32* %p unordered, align 4
194 ret void
195 }
196
94197 define void @dontwrite0to1(i32* nocapture %p) {
95198 ; CHECK-LABEL: @dontwrite0to1(
96199 ; CHECK-NEXT: entry:
105208 call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false)
106209 %p4 = bitcast i32* %p to i16*
107210 store i16 1, i16* %p4, align 4
211 ret void
212 }
213
214 define void @dontwrite0to1_atomic(i32* nocapture %p) {
215 ; CHECK-LABEL: @dontwrite0to1_atomic(
216 ; CHECK-NEXT: entry:
217 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
218 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i32 4)
219 ; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16*
220 ; CHECK-NEXT: store atomic i16 1, i16* [[P4]] unordered, align 4
221 ; CHECK-NEXT: ret void
222 ;
223 entry:
224 %p3 = bitcast i32* %p to i8*
225 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
226 %p4 = bitcast i32* %p to i16*
227 store atomic i16 1, i16* %p4 unordered, align 4
108228 ret void
109229 }
110230
128248 %arrayidx2 = getelementptr inbounds i16, i16* %p4, i64 1
129249 %p5 = bitcast i16* %arrayidx2 to i64*
130250 store i64 1, i64* %p5, align 8
251 ret void
252 }
253
254 define void @dontwrite2to9_atomic(i32* nocapture %p) {
255 ; CHECK-LABEL: @dontwrite2to9_atomic(
256 ; CHECK-NEXT: entry:
257 ; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
258 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
259 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i32 4)
260 ; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16*
261 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i16, i16* [[P4]], i64 1
262 ; CHECK-NEXT: [[P5:%.*]] = bitcast i16* [[ARRAYIDX2]] to i64*
263 ; CHECK-NEXT: store atomic i64 1, i64* [[P5]] unordered, align 8
264 ; CHECK-NEXT: ret void
265 ;
266 entry:
267 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
268 %p3 = bitcast i32* %arrayidx0 to i8*
269 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
270 %p4 = bitcast i32* %p to i16*
271 %arrayidx2 = getelementptr inbounds i16, i16* %p4, i64 1
272 %p5 = bitcast i16* %arrayidx2 to i64*
273 store atomic i64 1, i64* %p5 unordered, align 8
131274 ret void
132275 }
133276
158301 ret void
159302 }
160303
304 define void @write8To15AndThen0To7_atomic(i64* nocapture %P) {
305 ; CHECK-LABEL: @write8To15AndThen0To7_atomic(
306 ; CHECK-NEXT: entry:
307 ; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
308 ; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
309 ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 32, i32 8)
310 ; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
311 ; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
312 ; CHECK-NEXT: store atomic i64 1, i64* [[BASE64_1]] unordered, align 8
313 ; CHECK-NEXT: store atomic i64 2, i64* [[BASE64_0]] unordered, align 8
314 ; CHECK-NEXT: ret void
315 ;
316 entry:
317
318 %base0 = bitcast i64* %P to i8*
319 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
320 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
321
322 %base64_0 = getelementptr inbounds i64, i64* %P, i64 0
323 %base64_1 = getelementptr inbounds i64, i64* %P, i64 1
324
325 store atomic i64 1, i64* %base64_1 unordered, align 8
326 store atomic i64 2, i64* %base64_0 unordered, align 8
327 ret void
328 }
329
330 define void @write8To15AndThen0To7_atomic_weaker(i64* nocapture %P) {
331 ; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker(
332 ; CHECK-NEXT: entry:
333 ; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
334 ; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
335 ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 32, i32 8)
336 ; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
337 ; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
338 ; CHECK-NEXT: store atomic i64 1, i64* [[BASE64_1]] unordered, align 8
339 ; CHECK-NEXT: store i64 2, i64* [[BASE64_0]], align 8
340 ; CHECK-NEXT: ret void
341 ;
342 entry:
343
344 %base0 = bitcast i64* %P to i8*
345 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
346 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
347
348 %base64_0 = getelementptr inbounds i64, i64* %P, i64 0
349 %base64_1 = getelementptr inbounds i64, i64* %P, i64 1
350
351 store atomic i64 1, i64* %base64_1 unordered, align 8
352 store i64 2, i64* %base64_0, align 8
353 ret void
354 }
355
356 define void @write8To15AndThen0To7_atomic_weaker_2(i64* nocapture %P) {
357 ; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker_2(
358 ; CHECK-NEXT: entry:
359 ; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
360 ; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
361 ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 32, i32 8)
362 ; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
363 ; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
364 ; CHECK-NEXT: store i64 1, i64* [[BASE64_1]], align 8
365 ; CHECK-NEXT: store atomic i64 2, i64* [[BASE64_0]] unordered, align 8
366 ; CHECK-NEXT: ret void
367 ;
368 entry:
369
370 %base0 = bitcast i64* %P to i8*
371 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
372 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
373
374 %base64_0 = getelementptr inbounds i64, i64* %P, i64 0
375 %base64_1 = getelementptr inbounds i64, i64* %P, i64 1
376
377 store i64 1, i64* %base64_1, align 8
378 store atomic i64 2, i64* %base64_0 unordered, align 8
379 ret void
380 }
381
161382 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
162
383 declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture, i8, i64, i32) nounwind
384
2626 ret void
2727 }
2828
29 define void @write24to28_atomic(i32* nocapture %p) nounwind uwtable ssp {
30 ; CHECK-LABEL: @write24to28_atomic(
31 ; CHECK-NEXT: entry:
32 ; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
33 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
34 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i32 4)
35 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
36 ; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
37 ; CHECK-NEXT: ret void
38 ;
39 entry:
40 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
41 %p3 = bitcast i32* %arrayidx0 to i8*
42 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
43 %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
44 store atomic i32 1, i32* %arrayidx1 unordered, align 4
45 ret void
46 }
47
48 ; Atomicity of the store is weaker from the memset
49 define void @write24to28_atomic_weaker(i32* nocapture %p) nounwind uwtable ssp {
50 ; CHECK-LABEL: @write24to28_atomic_weaker(
51 ; CHECK-NEXT: entry:
52 ; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
53 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
54 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i32 4)
55 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
56 ; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
57 ; CHECK-NEXT: ret void
58 ;
59 entry:
60 %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
61 %p3 = bitcast i32* %arrayidx0 to i8*
62 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
63 %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
64 store i32 1, i32* %arrayidx1, align 4
65 ret void
66 }
67
2968 define void @write28to32(i32* nocapture %p) nounwind uwtable ssp {
3069 ; CHECK-LABEL: @write28to32(
3170 ; CHECK-NEXT: entry:
4382 ret void
4483 }
4584
85 define void @write28to32_atomic(i32* nocapture %p) nounwind uwtable ssp {
86 ; CHECK-LABEL: @write28to32_atomic(
87 ; CHECK-NEXT: entry:
88 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
89 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i32 4)
90 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
91 ; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
92 ; CHECK-NEXT: ret void
93 ;
94 entry:
95 %p3 = bitcast i32* %p to i8*
96 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
97 %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
98 store atomic i32 1, i32* %arrayidx1 unordered, align 4
99 ret void
100 }
101
46102 define void @dontwrite28to32memset(i32* nocapture %p) nounwind uwtable ssp {
47103 ; CHECK-LABEL: @dontwrite28to32memset(
48104 ; CHECK-NEXT: entry:
57113 call void @llvm.memset.p0i8.i64(i8* align 16 %p3, i8 0, i64 32, i1 false)
58114 %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
59115 store i32 1, i32* %arrayidx1, align 4
116 ret void
117 }
118
119 define void @dontwrite28to32memset_atomic(i32* nocapture %p) nounwind uwtable ssp {
120 ; CHECK-LABEL: @dontwrite28to32memset_atomic(
121 ; CHECK-NEXT: entry:
122 ; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
123 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 16 [[P3]], i8 0, i64 32, i32 4)
124 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
125 ; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
126 ; CHECK-NEXT: ret void
127 ;
128 entry:
129 %p3 = bitcast i32* %p to i8*
130 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 16 %p3, i8 0, i64 32, i32 4)
131 %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
132 store atomic i32 1, i32* %arrayidx1 unordered, align 4
60133 ret void
61134 }
62135
77150 ret void
78151 }
79152
153 define void @write32to36_atomic(%struct.vec2plusi* nocapture %p) nounwind uwtable ssp {
154 ; CHECK-LABEL: @write32to36_atomic(
155 ; CHECK-NEXT: entry:
156 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2plusi* [[P:%.*]] to i8*
157 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 36, i32 4)
158 ; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2PLUSI:%.*]], %struct.vec2plusi* [[P]], i64 0, i32 2
159 ; CHECK-NEXT: store atomic i32 1, i32* [[C]] unordered, align 4
160 ; CHECK-NEXT: ret void
161 ;
162 entry:
163 %0 = bitcast %struct.vec2plusi* %p to i8*
164 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 36, i32 4)
165 %c = getelementptr inbounds %struct.vec2plusi, %struct.vec2plusi* %p, i64 0, i32 2
166 store atomic i32 1, i32* %c unordered, align 4
167 ret void
168 }
169
170 ; Atomicity of the store is weaker than the memcpy
171 define void @write32to36_atomic_weaker(%struct.vec2plusi* nocapture %p) nounwind uwtable ssp {
172 ; CHECK-LABEL: @write32to36_atomic_weaker(
173 ; CHECK-NEXT: entry:
174 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2plusi* [[P:%.*]] to i8*
175 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 36, i32 4)
176 ; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2PLUSI:%.*]], %struct.vec2plusi* [[P]], i64 0, i32 2
177 ; CHECK-NEXT: store i32 1, i32* [[C]], align 4
178 ; CHECK-NEXT: ret void
179 ;
180 entry:
181 %0 = bitcast %struct.vec2plusi* %p to i8*
182 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 36, i32 4)
183 %c = getelementptr inbounds %struct.vec2plusi, %struct.vec2plusi* %p, i64 0, i32 2
184 store i32 1, i32* %c, align 4
185 ret void
186 }
187
80188 define void @write16to32(%struct.vec2* nocapture %p) nounwind uwtable ssp {
81189 ; CHECK-LABEL: @write16to32(
82190 ; CHECK-NEXT: entry:
94202 ret void
95203 }
96204
205 define void @write16to32_atomic(%struct.vec2* nocapture %p) nounwind uwtable ssp {
206 ; CHECK-LABEL: @write16to32_atomic(
207 ; CHECK-NEXT: entry:
208 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2* [[P:%.*]] to i8*
209 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 4)
210 ; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], %struct.vec2* [[P]], i64 0, i32 1
211 ; CHECK-NEXT: store <4 x i32> , <4 x i32>* [[C]], align 4
212 ; CHECK-NEXT: ret void
213 ;
214 entry:
215 %0 = bitcast %struct.vec2* %p to i8*
216 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 4)
217 %c = getelementptr inbounds %struct.vec2, %struct.vec2* %p, i64 0, i32 1
218 store <4 x i32> , <4 x i32>* %c, align 4
219 ret void
220 }
221
97222 define void @dontwrite28to32memcpy(%struct.vec2* nocapture %p) nounwind uwtable ssp {
98223 ; CHECK-LABEL: @dontwrite28to32memcpy(
99224 ; CHECK-NEXT: entry:
111236 ret void
112237 }
113238
239 define void @dontwrite28to32memcpy_atomic(%struct.vec2* nocapture %p) nounwind uwtable ssp {
240 ; CHECK-LABEL: @dontwrite28to32memcpy_atomic(
241 ; CHECK-NEXT: entry:
242 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2* [[P:%.*]] to i8*
243 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 4)
244 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], %struct.vec2* [[P]], i64 0, i32 0, i64 7
245 ; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
246 ; CHECK-NEXT: ret void
247 ;
248 entry:
249 %0 = bitcast %struct.vec2* %p to i8*
250 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 4)
251 %arrayidx1 = getelementptr inbounds %struct.vec2, %struct.vec2* %p, i64 0, i32 0, i64 7
252 store atomic i32 1, i32* %arrayidx1 unordered, align 4
253 ret void
254 }
255
114256 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
257 declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
115258 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
259 declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture, i8, i64, i32) nounwind
116260
117261 %struct.trapframe = type { i64, i64, i64 }
118262
165309 store i64 3, i64* %base64_3
166310 ret void
167311 }
312
313 define void @write16To23AndThen24To31_atomic(i64* nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
314 ; CHECK-LABEL: @write16To23AndThen24To31_atomic(
315 ; CHECK-NEXT: entry:
316 ; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
317 ; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
318 ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 32, i32 8)
319 ; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 2
320 ; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 3
321 ; CHECK-NEXT: store atomic i64 3, i64* [[BASE64_2]] unordered, align 8
322 ; CHECK-NEXT: store atomic i64 3, i64* [[BASE64_3]] unordered, align 8
323 ; CHECK-NEXT: ret void
324 ;
325 entry:
326
327 %base0 = bitcast i64* %P to i8*
328 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
329 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
330
331 %base64_2 = getelementptr inbounds i64, i64* %P, i64 2
332 %base64_3 = getelementptr inbounds i64, i64* %P, i64 3
333
334 store atomic i64 3, i64* %base64_2 unordered, align 8
335 store atomic i64 3, i64* %base64_3 unordered, align 8
336 ret void
337 }
338
339 define void @write16To23AndThen24To31_atomic_weaker1(i64* nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
340 ; CHECK-LABEL: @write16To23AndThen24To31_atomic_weaker1(
341 ; CHECK-NEXT: entry:
342 ; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
343 ; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
344 ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 32, i32 8)
345 ; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 2
346 ; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 3
347 ; CHECK-NEXT: store i64 3, i64* [[BASE64_2]], align 8
348 ; CHECK-NEXT: store atomic i64 3, i64* [[BASE64_3]] unordered, align 8
349 ; CHECK-NEXT: ret void
350 ;
351 entry:
352
353 %base0 = bitcast i64* %P to i8*
354 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
355 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
356
357 %base64_2 = getelementptr inbounds i64, i64* %P, i64 2
358 %base64_3 = getelementptr inbounds i64, i64* %P, i64 3
359
360 store i64 3, i64* %base64_2, align 8
361 store atomic i64 3, i64* %base64_3 unordered, align 8
362 ret void
363 }
364
365 define void @write16To23AndThen24To31_atomic_weaker2(i64* nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
366 ; CHECK-LABEL: @write16To23AndThen24To31_atomic_weaker2(
367 ; CHECK-NEXT: entry:
368 ; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
369 ; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
370 ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 32, i32 8)
371 ; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 2
372 ; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 3
373 ; CHECK-NEXT: store atomic i64 3, i64* [[BASE64_2]] unordered, align 8
374 ; CHECK-NEXT: store i64 3, i64* [[BASE64_3]], align 8
375 ; CHECK-NEXT: ret void
376 ;
377 entry:
378
379 %base0 = bitcast i64* %P to i8*
380 %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
381 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
382
383 %base64_2 = getelementptr inbounds i64, i64* %P, i64 2
384 %base64_3 = getelementptr inbounds i64, i64* %P, i64 3
385
386 store atomic i64 3, i64* %base64_2 unordered, align 8
387 store i64 3, i64* %base64_3, align 8
388 ret void
389 }
4545
4646 ret void
4747 }
48
49 declare void @llvm.memcpy.element.unordered.atomic.p0i16.p0i16.i16(i16* nocapture, i16* nocapture, i16, i32) nounwind
50 declare void @llvm.memmove.element.unordered.atomic.p0i16.p0i16.i16(i16* nocapture, i16* nocapture, i16, i32) nounwind
51 declare void @llvm.memset.element.unordered.atomic.p0i16.i16(i16* nocapture, i8, i16, i32) nounwind
52
53
54 define void @test4() {
55 ; CHECK-LABEL: @test4(
56 ; CHECK-NEXT: [[A:%.*]] = alloca i16, i16 1024, align 2
57 ; CHECK-NEXT: [[B:%.*]] = alloca i16, i16 1024, align 2
58 ; CHECK-NEXT: store atomic i16 0, i16* [[B]] unordered, align 2
59 ; CHECK-NEXT: call void @llvm.memcpy.element.unordered.atomic.p0i16.p0i16.i16(i16* align 2 [[A]], i16* align 2 [[B]], i16 1024, i32 2)
60 ; CHECK-NEXT: ret void
61 ;
62 %A = alloca i16, i16 1024, align 2
63 %B = alloca i16, i16 1024, align 2
64
65 store atomic i16 0, i16* %A unordered, align 2 ;; Written to by memcpy
66 store atomic i16 0, i16* %B unordered, align 2 ;; Read by memcpy
67
68 call void @llvm.memcpy.element.unordered.atomic.p0i16.p0i16.i16(i16* align 2 %A, i16* align 2 %B, i16 1024, i32 2)
69
70 ret void
71 }
72
73 define void @test5() {
74 ; CHECK-LABEL: @test5(
75 ; CHECK-NEXT: [[A:%.*]] = alloca i16, i16 1024, align 2
76 ; CHECK-NEXT: [[B:%.*]] = alloca i16, i16 1024, align 2
77 ; CHECK-NEXT: store atomic i16 0, i16* [[B]] unordered, align 2
78 ; CHECK-NEXT: call void @llvm.memmove.element.unordered.atomic.p0i16.p0i16.i16(i16* align 2 [[A]], i16* align 2 [[B]], i16 1024, i32 2)
79 ; CHECK-NEXT: ret void
80 ;
81 %A = alloca i16, i16 1024, align 2
82 %B = alloca i16, i16 1024, align 2
83
84 store atomic i16 0, i16* %A unordered, align 2 ;; Written to by memmove
85 store atomic i16 0, i16* %B unordered, align 2 ;; Read by memmove
86
87 call void @llvm.memmove.element.unordered.atomic.p0i16.p0i16.i16(i16* align 2 %A, i16* align 2 %B, i16 1024, i32 2)
88
89 ret void
90 }
91
92 define void @test6() {
93 ; CHECK-LABEL: @test6(
94 ; CHECK-NEXT: [[A:%.*]] = alloca i16, i16 1024, align 2
95 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i16.i16(i16* align 2 [[A]], i8 0, i16 1024, i32 2)
96 ; CHECK-NEXT: ret void
97 ;
98 %A = alloca i16, i16 1024, align 2
99 %B = alloca i16, i16 1024, align 2
100
101 store atomic i16 0, i16* %A unordered, align 2 ;; Written to by memset
102
103 call void @llvm.memset.element.unordered.atomic.p0i16.i16(i16* align 2 %A, i8 0, i16 1024, i32 2)
104
105 ret void
106 }
33 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
44
55 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
6 declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture, i8, i64, i32) nounwind
67 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
8 declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
79 declare void @llvm.init.trampoline(i8*, i8*, i8*)
810
911 define void @test1(i32* %Q, i32* %P) {
8587 ret void
8688 }
8789
90 ; Should delete store of 10 even though memset is a may-store to P (P and Q may
91 ; alias).
92 define void @test6_atomic(i32* align 4 %p, i8* align 4 %q) {
93 ; CHECK-LABEL: @test6_atomic(
94 ; CHECK-NEXT: store atomic i32 10, i32* [[P:%.*]] unordered, align 4
95 ; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[Q:%.*]], i8 42, i64 900, i32 4)
96 ; CHECK-NEXT: store atomic i32 30, i32* [[P]] unordered, align 4
97 ; CHECK-NEXT: ret void
98 ;
99 store atomic i32 10, i32* %p unordered, align 4 ;; dead.
100 call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %q, i8 42, i64 900, i32 4)
101 store atomic i32 30, i32* %p unordered, align 4
102 ret void
103 }
104
88105 ; Should delete store of 10 even though memcpy is a may-store to P (P and Q may
89106 ; alias).
90107 define void @test7(i32 *%p, i8 *%q, i8* noalias %r) {
96113 store i32 10, i32* %p, align 4 ;; dead.
97114 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %q, i8* %r, i64 900, i1 false)
98115 store i32 30, i32* %p, align 4
116 ret void
117 }
118
119 ; Should delete store of 10 even though memcpy is a may-store to P (P and Q may
120 ; alias).
121 define void @test7_atomic(i32* align 4 %p, i8* align 4 %q, i8* noalias align 4 %r) {
122 ; CHECK-LABEL: @test7_atomic(
123 ; CHECK-NEXT: store atomic i32 10, i32* [[P:%.*]] unordered, align 4
124 ; CHECK-NEXT: call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 4 [[Q:%.*]], i8* align 4 [[R:%.*]], i64 900, i32 4)
125 ; CHECK-NEXT: store atomic i32 30, i32* [[P]] unordered, align 4
126 ; CHECK-NEXT: ret void
127 ;
128 store atomic i32 10, i32* %p unordered, align 4 ;; dead.
129 call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 4 %q, i8* align 4 %r, i64 900, i32 4)
130 store atomic i32 30, i32* %p unordered, align 4
99131 ret void
100132 }
101133
255287 ret void
256288 }
257289
290 ;; Fully dead overwrite of memcpy.
291 define void @test15_atomic(i8* %P, i8* %Q) nounwind ssp {
292 ; CHECK-LABEL: @test15_atomic(
293 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
294 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q]], i64 12, i32 1)
295 ; CHECK-NEXT: ret void
296 ;
297 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
298 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
299 ret void
300 }
301
302 ; It would only be valid to remove the non-atomic memcpy
303 define void @test15_atomic_weaker(i8* %P, i8* %Q) nounwind ssp {
304 ; CHECK-LABEL: @test15_atomic_weaker(
305 ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
306 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q]], i64 12, i32 1)
307 ; CHECK-NEXT: ret void
308 ;
309 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
310 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
311 ret void
312 }
313
314 ; It would only be valid to remove the non-atomic memcpy
315 define void @test15_atomic_weaker_2(i8* %P, i8* %Q) nounwind ssp {
316 ; CHECK-LABEL: @test15_atomic_weaker_2(
317 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
318 ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q]], i64 12, i1 false)
319 ; CHECK-NEXT: ret void
320 ;
321 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
322 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
323 ret void
324 }
325
258326 ;; Full overwrite of smaller memcpy.
259327 define void @test16(i8* %P, i8* %Q) nounwind ssp {
260328 ; CHECK-LABEL: @test16(
266334 ret void
267335 }
268336
337 ;; Full overwrite of smaller memcpy.
338 define void @test16_atomic(i8* %P, i8* %Q) nounwind ssp {
339 ; CHECK-LABEL: @test16_atomic(
340 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 8, i32 1)
341 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q]], i64 12, i32 1)
342 ; CHECK-NEXT: ret void
343 ;
344 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 8, i32 1)
345 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
346 ret void
347 }
348
349 ;; Full overwrite of smaller memory where overwrite has stronger atomicity
350 define void @test16_atomic_weaker(i8* %P, i8* %Q) nounwind ssp {
351 ; CHECK-LABEL: @test16_atomic_weaker(
352 ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 8, i1 false)
353 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q]], i64 12, i32 1)
354 ; CHECK-NEXT: ret void
355 ;
356 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 8, i1 false)
357 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
358 ret void
359 }
360
361 ;; Full overwrite of smaller memory where overwrite has weaker atomicity.
362 define void @test16_atomic_weaker_2(i8* %P, i8* %Q) nounwind ssp {
363 ; CHECK-LABEL: @test16_atomic_weaker_2(
364 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 8, i32 1)
365 ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q]], i64 12, i1 false)
366 ; CHECK-NEXT: ret void
367 ;
368 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 8, i32 1)
369 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
370 ret void
371 }
372
269373 ;; Overwrite of memset by memcpy.
270374 define void @test17(i8* %P, i8* noalias %Q) nounwind ssp {
271375 ; CHECK-LABEL: @test17(
274378 ;
275379 tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
276380 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
381 ret void
382 }
383
384 ;; Overwrite of memset by memcpy.
385 define void @test17_atomic(i8* %P, i8* noalias %Q) nounwind ssp {
386 ; CHECK-LABEL: @test17_atomic(
387 ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 [[P:%.*]], i8 42, i64 8, i32 1)
388 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
389 ; CHECK-NEXT: ret void
390 ;
391 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i32 1)
392 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
393 ret void
394 }
395
396 ;; Overwrite of memset by memcpy. Overwrite is stronger atomicity. We can
397 ;; remove the memset.
398 define void @test17_atomic_weaker(i8* %P, i8* noalias %Q) nounwind ssp {
399 ; CHECK-LABEL: @test17_atomic_weaker(
400 ; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* align 1 [[P:%.*]], i8 42, i64 8, i1 false)
401 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
402 ; CHECK-NEXT: ret void
403 ;
404 tail call void @llvm.memset.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i1 false)
405 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
406 ret void
407 }
408
409 ;; Overwrite of memset by memcpy. Overwrite is weaker atomicity. We can remove
410 ;; the memset.
411 define void @test17_atomic_weaker_2(i8* %P, i8* noalias %Q) nounwind ssp {
412 ; CHECK-LABEL: @test17_atomic_weaker_2(
413 ; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 [[P:%.*]], i8 42, i64 8, i32 1)
414 ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
415 ; CHECK-NEXT: ret void
416 ;
417 tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i32 1)
418 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
277419 ret void
278420 }
279421
304446 ;
305447 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
306448 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
449 ret void
450 }
451
452 define void @test18_atomic(i8* %P, i8* %Q, i8* %R) nounwind ssp {
453 ; CHECK-LABEL: @test18_atomic(
454 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
455 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 12, i32 1)
456 ; CHECK-NEXT: ret void
457 ;
458 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
459 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 12, i32 1)
307460 ret void
308461 }
309462
665818 ret void
666819 }
667820
821 define void @test36_atomic(i8* %P, i8* %Q) {
822 ; CHECK-LABEL: @test36_atomic(
823 ; CHECK-NEXT: tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
824 ; CHECK-NEXT: tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q]], i64 12, i32 1)
825 ; CHECK-NEXT: ret void
826 ;
827
828 tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
829 tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
830 ret void
831 }
832
668833 define void @test37(i8* %P, i8* %Q, i8* %R) {
669834 ; CHECK-LABEL: @test37(
670835 ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
674839
675840 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
676841 tail call void @llvm.memmove.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
842 ret void
843 }
844
845 define void @test37_atomic(i8* %P, i8* %Q, i8* %R) {
846 ; CHECK-LABEL: @test37_atomic(
847 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
848 ; CHECK-NEXT: tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 12, i32 1)
849 ; CHECK-NEXT: ret void
850 ;
851
852 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
853 tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 12, i32 1)
677854 ret void
678855 }
679856
690867 ret void
691868 }
692869
870 define void @test38_atomic(i8* %P, i8* %Q, i8* %R) {
871 ; CHECK-LABEL: @test38_atomic(
872 ; CHECK-NEXT: tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
873 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 12, i32 1)
874 ; CHECK-NEXT: ret void
875 ;
876
877 tail call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
878 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 12, i32 1)
879 ret void
880 }
881
693882 define void @test39(i8* %P, i8* %Q, i8* %R) {
694883 ; CHECK-LABEL: @test39(
695884 ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
702891 ret void
703892 }
704893
894 define void @test39_atomic(i8* %P, i8* %Q, i8* %R) {
895 ; CHECK-LABEL: @test39_atomic(
896 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
897 ; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 8, i32 1)
898 ; CHECK-NEXT: ret void
899 ;
900
901 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
902 tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 8, i32 1)
903 ret void
904 }
905
705906 declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1)
907 declare void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32)