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