1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
3
4define void @write4to7(i32* nocapture %p) {
5; CHECK-LABEL: @write4to7(
6; CHECK-NEXT:  entry:
7; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
8; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
9; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
10; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
11; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
12; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
13; CHECK-NEXT:    ret void
14;
15entry:
16  %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
17  %p3 = bitcast i32* %arrayidx0 to i8*
18  call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false)
19  %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1
20  store i32 1, i32* %arrayidx1, align 4
21  ret void
22}
23
24define void @write4to7_weird_element_type(i32* nocapture %p) {
25; CHECK-LABEL: @write4to7_weird_element_type(
26; CHECK-NEXT:  entry:
27; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
28; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
29; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4
30; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
31; CHECK-NEXT:    call void @llvm.memset.p0i32.i64(i32* align 4 [[TMP2]], i8 0, i64 24, i1 false)
32; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
33; CHECK-NEXT:    store i32 1, i32* [[ARRAYIDX1]], align 4
34; CHECK-NEXT:    ret void
35;
36entry:
37  %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
38  call void @llvm.memset.p0i32.i64(i32* align 4 %arrayidx0, i8 0, i64 28, i1 false)
39  %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1
40  store i32 1, i32* %arrayidx1, align 4
41  ret void
42}
43
44define void @write4to7_addrspace(i32 addrspace(1)* nocapture %p) {
45; CHECK-LABEL: @write4to7_addrspace(
46; CHECK-NEXT:  entry:
47; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32 addrspace(1)* [[P:%.*]], i64 1
48; CHECK-NEXT:    [[P3:%.*]] = bitcast i32 addrspace(1)* [[ARRAYIDX0]] to i8 addrspace(1)*
49; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[P3]], i64 4
50; CHECK-NEXT:    call void @llvm.memset.p1i8.i64(i8 addrspace(1)* align 4 [[TMP0]], i8 0, i64 24, i1 false)
51; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32 addrspace(1)* [[P]], i64 1
52; CHECK-NEXT:    store i32 1, i32 addrspace(1)* [[ARRAYIDX1]], align 4
53; CHECK-NEXT:    ret void
54;
55entry:
56  %arrayidx0 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 1
57  %p3 = bitcast i32 addrspace(1)* %arrayidx0 to i8 addrspace(1)*
58  call void @llvm.memset.p1i8.i64(i8 addrspace(1)* align 4 %p3, i8 0, i64 28, i1 false)
59  %arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 1
60  store i32 1, i32 addrspace(1)* %arrayidx1, align 4
61  ret void
62}
63
64define void @write4to7_atomic(i32* nocapture %p) {
65; CHECK-LABEL: @write4to7_atomic(
66; CHECK-NEXT:  entry:
67; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
68; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
69; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
70; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
71; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
72; CHECK-NEXT:    store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
73; CHECK-NEXT:    ret void
74;
75entry:
76  %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
77  %p3 = bitcast i32* %arrayidx0 to i8*
78  call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
79  %arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1
80  store atomic i32 1, i32* %arrayidx1 unordered, align 4
81  ret void
82}
83
84define void @write0to3(i32* nocapture %p) {
85; CHECK-LABEL: @write0to3(
86; CHECK-NEXT:  entry:
87; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
88; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
89; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
90; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
91; CHECK-NEXT:    ret void
92;
93entry:
94  %p3 = bitcast i32* %p to i8*
95  call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false)
96  store i32 1, i32* %p, align 4
97  ret void
98}
99
100define void @write0to3_atomic(i32* nocapture %p) {
101; CHECK-LABEL: @write0to3_atomic(
102; CHECK-NEXT:  entry:
103; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
104; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
105; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
106; CHECK-NEXT:    store atomic i32 1, i32* [[P]] unordered, align 4
107; CHECK-NEXT:    ret void
108;
109entry:
110  %p3 = bitcast i32* %p to i8*
111  call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
112  store atomic i32 1, i32* %p unordered, align 4
113  ret void
114}
115
116; Atomicity of the store is weaker from the memset
117define void @write0to3_atomic_weaker(i32* nocapture %p) {
118; CHECK-LABEL: @write0to3_atomic_weaker(
119; CHECK-NEXT:  entry:
120; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
121; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
122; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
123; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
124; CHECK-NEXT:    ret void
125;
126entry:
127  %p3 = bitcast i32* %p to i8*
128  call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
129  store i32 1, i32* %p, align 4
130  ret void
131}
132
133define void @write0to7(i32* nocapture %p) {
134; CHECK-LABEL: @write0to7(
135; CHECK-NEXT:  entry:
136; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
137; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 8
138; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
139; CHECK-NEXT:    [[P4:%.*]] = bitcast i32* [[P]] to i64*
140; CHECK-NEXT:    store i64 1, i64* [[P4]], align 8
141; CHECK-NEXT:    ret void
142;
143entry:
144  %p3 = bitcast i32* %p to i8*
145  call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false)
146  %p4 = bitcast i32* %p to i64*
147  store i64 1, i64* %p4, align 8
148  ret void
149}
150
151; Changing the memset start and length is okay here because the
152; store is a multiple of the memset element size
153define void @write0to7_atomic(i32* nocapture %p) {
154; CHECK-LABEL: @write0to7_atomic(
155; CHECK-NEXT:  entry:
156; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
157; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 8
158; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
159; CHECK-NEXT:    [[P4:%.*]] = bitcast i32* [[P]] to i64*
160; CHECK-NEXT:    store atomic i64 1, i64* [[P4]] unordered, align 8
161; CHECK-NEXT:    ret void
162;
163entry:
164  %p3 = bitcast i32* %p to i8*
165  call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
166  %p4 = bitcast i32* %p to i64*
167  store atomic i64 1, i64* %p4 unordered, align 8
168  ret void
169}
170
171define void @write0to7_2(i32* nocapture %p) {
172; CHECK-LABEL: @write0to7_2(
173; CHECK-NEXT:  entry:
174; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
175; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
176; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
177; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
178; CHECK-NEXT:    [[P4:%.*]] = bitcast i32* [[P]] to i64*
179; CHECK-NEXT:    store i64 1, i64* [[P4]], align 8
180; CHECK-NEXT:    ret void
181;
182entry:
183  %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
184  %p3 = bitcast i32* %arrayidx0 to i8*
185  call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false)
186  %p4 = bitcast i32* %p to i64*
187  store i64 1, i64* %p4, align 8
188  ret void
189}
190
191define void @write0to7_2_atomic(i32* nocapture %p) {
192; CHECK-LABEL: @write0to7_2_atomic(
193; CHECK-NEXT:  entry:
194; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
195; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
196; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
197; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
198; CHECK-NEXT:    [[P4:%.*]] = bitcast i32* [[P]] to i64*
199; CHECK-NEXT:    store atomic i64 1, i64* [[P4]] unordered, align 8
200; CHECK-NEXT:    ret void
201;
202entry:
203  %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
204  %p3 = bitcast i32* %arrayidx0 to i8*
205  call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
206  %p4 = bitcast i32* %p to i64*
207  store atomic i64 1, i64* %p4 unordered, align 8
208  ret void
209}
210
211; We do not trim the beginning of the eariler write if the alignment of the
212; start pointer is changed.
213define void @dontwrite0to3_align8(i32* nocapture %p) {
214; CHECK-LABEL: @dontwrite0to3_align8(
215; CHECK-NEXT:  entry:
216; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
217; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 8 [[P3]], i8 0, i64 32, i1 false)
218; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
219; CHECK-NEXT:    ret void
220;
221entry:
222  %p3 = bitcast i32* %p to i8*
223  call void @llvm.memset.p0i8.i64(i8* align 8 %p3, i8 0, i64 32, i1 false)
224  store i32 1, i32* %p, align 4
225  ret void
226}
227
228define void @dontwrite0to3_align8_atomic(i32* nocapture %p) {
229; CHECK-LABEL: @dontwrite0to3_align8_atomic(
230; CHECK-NEXT:  entry:
231; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
232; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[P3]], i8 0, i64 32, i32 4)
233; CHECK-NEXT:    store atomic i32 1, i32* [[P]] unordered, align 4
234; CHECK-NEXT:    ret void
235;
236entry:
237  %p3 = bitcast i32* %p to i8*
238  call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %p3, i8 0, i64 32, i32 4)
239  store atomic i32 1, i32* %p unordered, align 4
240  ret void
241}
242
243define void @dontwrite0to1(i32* nocapture %p) {
244; CHECK-LABEL: @dontwrite0to1(
245; CHECK-NEXT:  entry:
246; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
247; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i1 false)
248; CHECK-NEXT:    [[P4:%.*]] = bitcast i32* [[P]] to i16*
249; CHECK-NEXT:    store i16 1, i16* [[P4]], align 4
250; CHECK-NEXT:    ret void
251;
252entry:
253  %p3 = bitcast i32* %p to i8*
254  call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false)
255  %p4 = bitcast i32* %p to i16*
256  store i16 1, i16* %p4, align 4
257  ret void
258}
259
260define void @dontwrite0to1_atomic(i32* nocapture %p) {
261; CHECK-LABEL: @dontwrite0to1_atomic(
262; CHECK-NEXT:  entry:
263; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
264; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i32 4)
265; CHECK-NEXT:    [[P4:%.*]] = bitcast i32* [[P]] to i16*
266; CHECK-NEXT:    store atomic i16 1, i16* [[P4]] unordered, align 4
267; CHECK-NEXT:    ret void
268;
269entry:
270  %p3 = bitcast i32* %p to i8*
271  call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
272  %p4 = bitcast i32* %p to i16*
273  store atomic i16 1, i16* %p4 unordered, align 4
274  ret void
275}
276
277define void @write2to10(i32* nocapture %p) {
278; CHECK-LABEL: @write2to10(
279; CHECK-NEXT:  entry:
280; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
281; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
282; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
283; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 28, i1 false)
284; CHECK-NEXT:    [[P4:%.*]] = bitcast i32* [[P]] to i16*
285; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i16, i16* [[P4]], i64 1
286; CHECK-NEXT:    [[P5:%.*]] = bitcast i16* [[ARRAYIDX2]] to i64*
287; CHECK-NEXT:    store i64 1, i64* [[P5]], align 8
288; CHECK-NEXT:    ret void
289;
290entry:
291  %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
292  %p3 = bitcast i32* %arrayidx0 to i8*
293  call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false)
294  %p4 = bitcast i32* %p to i16*
295  %arrayidx2 = getelementptr inbounds i16, i16* %p4, i64 1
296  %p5 = bitcast i16* %arrayidx2 to i64*
297  store i64 1, i64* %p5, align 8
298  ret void
299}
300
301define void @write2to10_atomic(i32* nocapture %p) {
302; CHECK-LABEL: @write2to10_atomic(
303; CHECK-NEXT:  entry:
304; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
305; CHECK-NEXT:    [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
306; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
307; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 28, i32 4)
308; CHECK-NEXT:    [[P4:%.*]] = bitcast i32* [[P]] to i16*
309; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i16, i16* [[P4]], i64 1
310; CHECK-NEXT:    [[P5:%.*]] = bitcast i16* [[ARRAYIDX2]] to i64*
311; CHECK-NEXT:    store atomic i64 1, i64* [[P5]] unordered, align 8
312; CHECK-NEXT:    ret void
313;
314entry:
315  %arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
316  %p3 = bitcast i32* %arrayidx0 to i8*
317  call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
318  %p4 = bitcast i32* %p to i16*
319  %arrayidx2 = getelementptr inbounds i16, i16* %p4, i64 1
320  %p5 = bitcast i16* %arrayidx2 to i64*
321  store atomic i64 1, i64* %p5 unordered, align 8
322  ret void
323}
324
325define void @write8To15AndThen0To7(i64* nocapture %P) {
326; CHECK-LABEL: @write8To15AndThen0To7(
327; CHECK-NEXT:  entry:
328; CHECK-NEXT:    [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
329; CHECK-NEXT:    [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
330; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16
331; CHECK-NEXT:    tail call void @llvm.memset.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i1 false)
332; CHECK-NEXT:    [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
333; CHECK-NEXT:    [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
334; CHECK-NEXT:    store i64 1, i64* [[BASE64_1]], align 4
335; CHECK-NEXT:    store i64 2, i64* [[BASE64_0]], align 4
336; CHECK-NEXT:    ret void
337;
338entry:
339
340  %base0 = bitcast i64* %P to i8*
341  %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
342  tail call void @llvm.memset.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i1 false)
343
344  %base64_0 = getelementptr inbounds i64, i64* %P, i64 0
345  %base64_1 = getelementptr inbounds i64, i64* %P, i64 1
346
347  store i64 1, i64* %base64_1
348  store i64 2, i64* %base64_0
349  ret void
350}
351
352define void @write8To15AndThen0To7_atomic(i64* nocapture %P) {
353; CHECK-LABEL: @write8To15AndThen0To7_atomic(
354; CHECK-NEXT:  entry:
355; CHECK-NEXT:    [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
356; CHECK-NEXT:    [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
357; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16
358; CHECK-NEXT:    tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i32 8)
359; CHECK-NEXT:    [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
360; CHECK-NEXT:    [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
361; CHECK-NEXT:    store atomic i64 1, i64* [[BASE64_1]] unordered, align 8
362; CHECK-NEXT:    store atomic i64 2, i64* [[BASE64_0]] unordered, align 8
363; CHECK-NEXT:    ret void
364;
365entry:
366
367  %base0 = bitcast i64* %P to i8*
368  %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
369  tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
370
371  %base64_0 = getelementptr inbounds i64, i64* %P, i64 0
372  %base64_1 = getelementptr inbounds i64, i64* %P, i64 1
373
374  store atomic i64 1, i64* %base64_1 unordered, align 8
375  store atomic i64 2, i64* %base64_0 unordered, align 8
376  ret void
377}
378
379define void @write8To15AndThen0To7_atomic_weaker(i64* nocapture %P) {
380; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker(
381; CHECK-NEXT:  entry:
382; CHECK-NEXT:    [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
383; CHECK-NEXT:    [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
384; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16
385; CHECK-NEXT:    tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i32 8)
386; CHECK-NEXT:    [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
387; CHECK-NEXT:    [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
388; CHECK-NEXT:    store atomic i64 1, i64* [[BASE64_1]] unordered, align 8
389; CHECK-NEXT:    store i64 2, i64* [[BASE64_0]], align 8
390; CHECK-NEXT:    ret void
391;
392entry:
393
394  %base0 = bitcast i64* %P to i8*
395  %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
396  tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
397
398  %base64_0 = getelementptr inbounds i64, i64* %P, i64 0
399  %base64_1 = getelementptr inbounds i64, i64* %P, i64 1
400
401  store atomic i64 1, i64* %base64_1 unordered, align 8
402  store i64 2, i64* %base64_0, align 8
403  ret void
404}
405
406define void @write8To15AndThen0To7_atomic_weaker_2(i64* nocapture %P) {
407; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker_2(
408; CHECK-NEXT:  entry:
409; CHECK-NEXT:    [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
410; CHECK-NEXT:    [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
411; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16
412; CHECK-NEXT:    tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i32 8)
413; CHECK-NEXT:    [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
414; CHECK-NEXT:    [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
415; CHECK-NEXT:    store i64 1, i64* [[BASE64_1]], align 8
416; CHECK-NEXT:    store atomic i64 2, i64* [[BASE64_0]] unordered, align 8
417; CHECK-NEXT:    ret void
418;
419entry:
420
421  %base0 = bitcast i64* %P to i8*
422  %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
423  tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
424
425  %base64_0 = getelementptr inbounds i64, i64* %P, i64 0
426  %base64_1 = getelementptr inbounds i64, i64* %P, i64 1
427
428  store i64 1, i64* %base64_1, align 8
429  store atomic i64 2, i64* %base64_0 unordered, align 8
430  ret void
431}
432
433declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
434declare void @llvm.memset.p0i32.i64(i32* nocapture, i8, i64, i1) nounwind
435declare void @llvm.memset.p1i8.i64(i8 addrspace(1)* nocapture, i8, i64, i1) nounwind
436declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture, i8, i64, i32) nounwind
437
438define void @ow_begin_align1(i8* nocapture %p) {
439; CHECK-LABEL: @ow_begin_align1(
440; CHECK-NEXT:  entry:
441; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1
442; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P1]], i64 7
443; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP0]], i8 0, i64 25, i1 false)
444; CHECK-NEXT:    [[P2:%.*]] = bitcast i8* [[P]] to i64*
445; CHECK-NEXT:    store i64 1, i64* [[P2]], align 1
446; CHECK-NEXT:    ret void
447;
448entry:
449  %p1 = getelementptr inbounds i8, i8* %p, i64 1
450  call void @llvm.memset.p0i8.i64(i8* align 1 %p1, i8 0, i64 32, i1 false)
451  %p2 = bitcast i8* %p to i64*
452  store i64 1, i64* %p2, align 1
453  ret void
454}
455
456define void @ow_end_align4(i8* nocapture %p) {
457; CHECK-LABEL: @ow_end_align4(
458; CHECK-NEXT:  entry:
459; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1
460; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P1]], i64 4
461; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 28, i1 false)
462; CHECK-NEXT:    [[P2:%.*]] = bitcast i8* [[P]] to i64*
463; CHECK-NEXT:    store i64 1, i64* [[P2]], align 1
464; CHECK-NEXT:    ret void
465;
466entry:
467  %p1 = getelementptr inbounds i8, i8* %p, i64 1
468  call void @llvm.memset.p0i8.i64(i8* align 4 %p1, i8 0, i64 32, i1 false)
469  %p2 = bitcast i8* %p to i64*
470  store i64 1, i64* %p2, align 1
471  ret void
472}
473
474define void @ow_end_align8(i8* nocapture %p) {
475; CHECK-LABEL: @ow_end_align8(
476; CHECK-NEXT:  entry:
477; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1
478; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 8 [[P1]], i8 0, i64 32, i1 false)
479; CHECK-NEXT:    [[P2:%.*]] = bitcast i8* [[P]] to i64*
480; CHECK-NEXT:    store i64 1, i64* [[P2]], align 1
481; CHECK-NEXT:    ret void
482;
483entry:
484  %p1 = getelementptr inbounds i8, i8* %p, i64 1
485  call void @llvm.memset.p0i8.i64(i8* align 8 %p1, i8 0, i64 32, i1 false)
486  %p2 = bitcast i8* %p to i64*
487  store i64 1, i64* %p2, align 1
488  ret void
489}
490