1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -gvn -S < %s | FileCheck %s
3
4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4:5"
5target triple = "x86_64-unknown-linux-gnu"
6
7define void @f0(i1 %alwaysFalse, i64 %val, i64* %loc) {
8; CHECK-LABEL: @f0(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    store i64 [[VAL:%.*]], i64* [[LOC:%.*]], align 8
11; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
12; CHECK:       neverTaken:
13; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i64* [[LOC]] to i8 addrspace(4)**
14; CHECK-NEXT:    [[PTR:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)** [[LOC_BC]], align 8
15; CHECK-NEXT:    store i8 5, i8 addrspace(4)* [[PTR]], align 1
16; CHECK-NEXT:    ret void
17; CHECK:       alwaysTaken:
18; CHECK-NEXT:    ret void
19;
20  entry:
21  store i64 %val, i64* %loc
22  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
23
24  neverTaken:
25  %loc.bc = bitcast i64* %loc to i8 addrspace(4)**
26  %ptr = load i8 addrspace(4)*, i8 addrspace(4)** %loc.bc
27  store i8 5, i8 addrspace(4)* %ptr
28  ret void
29
30  alwaysTaken:
31  ret void
32}
33
34define i64 @f1(i1 %alwaysFalse, i8 addrspace(4)* %val, i8 addrspace(4)** %loc) {
35; CHECK-LABEL: @f1(
36; CHECK-NEXT:  entry:
37; CHECK-NEXT:    store i8 addrspace(4)* [[VAL:%.*]], i8 addrspace(4)** [[LOC:%.*]], align 8
38; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
39; CHECK:       neverTaken:
40; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)** [[LOC]] to i64*
41; CHECK-NEXT:    [[INT:%.*]] = load i64, i64* [[LOC_BC]], align 8
42; CHECK-NEXT:    ret i64 [[INT]]
43; CHECK:       alwaysTaken:
44; CHECK-NEXT:    ret i64 42
45;
46  entry:
47  store i8 addrspace(4)* %val, i8 addrspace(4)** %loc
48  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
49
50  neverTaken:
51  %loc.bc = bitcast i8 addrspace(4)** %loc to i64*
52  %int = load i64, i64* %loc.bc
53  ret i64 %int
54
55  alwaysTaken:
56  ret i64 42
57}
58
59;; Note: For terseness, we stop using the %alwaysfalse trick for the
60;; tests below and just exercise the bits of forwarding logic directly.
61
62declare void @llvm.memset.p4i8.i64(i8 addrspace(4)* nocapture, i8, i64, i1) nounwind
63
64; Can't forward as the load might be dead.  (Pretend we wrote out the alwaysfalse idiom above.)
65define i8 addrspace(4)* @neg_forward_memset(i8 addrspace(4)* addrspace(4)* %loc) {
66; CHECK-LABEL: @neg_forward_memset(
67; CHECK-NEXT:  entry:
68; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
69; CHECK-NEXT:    call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 7, i64 8, i1 false)
70; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], align 8
71; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
72;
73  entry:
74  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
75  call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 7, i64 8, i1 false)
76  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
77  ret i8 addrspace(4)* %ref
78}
79
80define <1 x i8 addrspace(4)*> @neg_forward_memset_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) {
81; CHECK-LABEL: @neg_forward_memset_vload(
82; CHECK-NEXT:  entry:
83; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
84; CHECK-NEXT:    call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 7, i64 8, i1 false)
85; CHECK-NEXT:    [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]], align 8
86; CHECK-NEXT:    ret <1 x i8 addrspace(4)*> [[REF]]
87;
88  entry:
89  %loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
90  call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 7, i64 8, i1 false)
91  %ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc
92  ret <1 x i8 addrspace(4)*> %ref
93}
94
95
96; Can forward since we can do so w/o breaking types
97define i8 addrspace(4)* @forward_memset_zero(i8 addrspace(4)* addrspace(4)* %loc) {
98; CHECK-LABEL: @forward_memset_zero(
99; CHECK-NEXT:  entry:
100; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
101; CHECK-NEXT:    call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 0, i64 8, i1 false)
102; CHECK-NEXT:    ret i8 addrspace(4)* null
103;
104  entry:
105  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
106  call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 0, i64 8, i1 false)
107  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
108  ret i8 addrspace(4)* %ref
109}
110
111; Can't forward as the load might be dead.  (Pretend we wrote out the alwaysfalse idiom above.)
112define i8 addrspace(4)* @neg_forward_store(i8 addrspace(4)* addrspace(4)* %loc) {
113; CHECK-LABEL: @neg_forward_store(
114; CHECK-NEXT:  entry:
115; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)*
116; CHECK-NEXT:    store i64 5, i64 addrspace(4)* [[LOC_BC]], align 8
117; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], align 8
118; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
119;
120  entry:
121  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i64 addrspace(4)*
122  store i64 5, i64 addrspace(4)* %loc.bc
123  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
124  ret i8 addrspace(4)* %ref
125}
126
127define <1 x i8 addrspace(4)*> @neg_forward_store_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) {
128; CHECK-LABEL: @neg_forward_store_vload(
129; CHECK-NEXT:  entry:
130; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)*
131; CHECK-NEXT:    store i64 5, i64 addrspace(4)* [[LOC_BC]], align 8
132; CHECK-NEXT:    [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]], align 8
133; CHECK-NEXT:    ret <1 x i8 addrspace(4)*> [[REF]]
134;
135  entry:
136  %loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i64 addrspace(4)*
137  store i64 5, i64 addrspace(4)* %loc.bc
138  %ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc
139  ret <1 x i8 addrspace(4)*> %ref
140}
141
142; Nulls have known bit patterns, so we can forward
143define i8 addrspace(4)* @forward_store_zero(i8 addrspace(4)* addrspace(4)* %loc) {
144; CHECK-LABEL: @forward_store_zero(
145; CHECK-NEXT:  entry:
146; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)*
147; CHECK-NEXT:    store i64 0, i64 addrspace(4)* [[LOC_BC]], align 8
148; CHECK-NEXT:    ret i8 addrspace(4)* null
149;
150  entry:
151  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i64 addrspace(4)*
152  store i64 0, i64 addrspace(4)* %loc.bc
153  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
154  ret i8 addrspace(4)* %ref
155}
156
157; Nulls have known bit patterns, so we can forward
158define i8 addrspace(4)* @forward_store_zero2(i8 addrspace(4)* addrspace(4)* %loc) {
159; CHECK-LABEL: @forward_store_zero2(
160; CHECK-NEXT:  entry:
161; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i32> addrspace(4)*
162; CHECK-NEXT:    store <2 x i32> zeroinitializer, <2 x i32> addrspace(4)* [[LOC_BC]], align 8
163; CHECK-NEXT:    ret i8 addrspace(4)* null
164;
165  entry:
166  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i32> addrspace(4)*
167  store <2 x i32> zeroinitializer, <2 x i32> addrspace(4)* %loc.bc
168  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
169  ret i8 addrspace(4)* %ref
170}
171
172
173
174@NonZeroConstant = constant <4 x i64> <i64 3, i64 3, i64 3, i64 3>
175@NonZeroConstant2 = constant <4 x i64 addrspace(4)*> <
176  i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3),
177  i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3),
178  i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3),
179  i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3)>
180@ZeroConstant = constant <4 x i64> zeroinitializer
181
182
183; Can't forward as the load might be dead.  (Pretend we wrote out the alwaysfalse idiom above.)
184define i8 addrspace(4)* @neg_forward_memcopy(i8 addrspace(4)* addrspace(4)* %loc) {
185; CHECK-LABEL: @neg_forward_memcopy(
186; CHECK-NEXT:  entry:
187; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
188; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 8, i1 false)
189; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], align 8
190; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
191;
192entry:
193  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
194  %src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
195  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
196  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
197  ret i8 addrspace(4)* %ref
198}
199
200define i64 addrspace(4)* @neg_forward_memcopy2(i64 addrspace(4)* addrspace(4)* %loc) {
201; CHECK-LABEL: @neg_forward_memcopy2(
202; CHECK-NEXT:  entry:
203; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i64 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
204; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 8, i1 false)
205; CHECK-NEXT:    [[REF:%.*]] = load i64 addrspace(4)*, i64 addrspace(4)* addrspace(4)* [[LOC]], align 8
206; CHECK-NEXT:    ret i64 addrspace(4)* [[REF]]
207;
208entry:
209  %loc.bc = bitcast i64 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
210  %src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
211  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
212  %ref = load i64 addrspace(4)*, i64 addrspace(4)* addrspace(4)* %loc
213  ret i64 addrspace(4)* %ref
214}
215
216define i8 addrspace(4)* @forward_memcopy(i8 addrspace(4)* addrspace(4)* %loc) {
217; CHECK-LABEL: @forward_memcopy(
218; CHECK-NEXT:  entry:
219; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
220; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 8, i1 false)
221; CHECK-NEXT:    ret i8 addrspace(4)* bitcast (i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3) to i8 addrspace(4)*)
222;
223entry:
224  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
225  %src.bc = bitcast <4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*
226  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
227  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
228  ret i8 addrspace(4)* %ref
229}
230
231define i64 addrspace(4)* @forward_memcopy2(i64 addrspace(4)* addrspace(4)* %loc) {
232; CHECK-LABEL: @forward_memcopy2(
233; CHECK-NEXT:  entry:
234; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i64 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
235; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 8, i1 false)
236; CHECK-NEXT:    ret i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3)
237;
238entry:
239  %loc.bc = bitcast i64 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
240  %src.bc = bitcast <4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*
241  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
242  %ref = load i64 addrspace(4)*, i64 addrspace(4)* addrspace(4)* %loc
243  ret i64 addrspace(4)* %ref
244}
245
246define <1 x i8 addrspace(4)*> @neg_forward_memcpy_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) {
247; CHECK-LABEL: @neg_forward_memcpy_vload(
248; CHECK-NEXT:  entry:
249; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
250; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 8, i1 false)
251; CHECK-NEXT:    [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]], align 8
252; CHECK-NEXT:    ret <1 x i8 addrspace(4)*> [[REF]]
253;
254entry:
255  %loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
256  %src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
257  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
258  %ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc
259  ret <1 x i8 addrspace(4)*> %ref
260}
261
262define <4 x i64 addrspace(4)*> @neg_forward_memcpy_vload2(<4 x i64 addrspace(4)*> addrspace(4)* %loc) {
263; CHECK-LABEL: @neg_forward_memcpy_vload2(
264; CHECK-NEXT:  entry:
265; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast <4 x i64 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
266; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 32, i1 false)
267; CHECK-NEXT:    [[REF:%.*]] = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*> addrspace(4)* [[LOC]], align 32
268; CHECK-NEXT:    ret <4 x i64 addrspace(4)*> [[REF]]
269;
270entry:
271  %loc.bc = bitcast <4 x i64 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
272  %src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
273  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 32, i1 false)
274  %ref = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*> addrspace(4)* %loc
275  ret <4 x i64 addrspace(4)*> %ref
276}
277
278define <4 x i64> @neg_forward_memcpy_vload3(<4 x i64> addrspace(4)* %loc) {
279; CHECK-LABEL: @neg_forward_memcpy_vload3(
280; CHECK-NEXT:  entry:
281; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast <4 x i64> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
282; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 32, i1 false)
283; CHECK-NEXT:    [[REF:%.*]] = load <4 x i64>, <4 x i64> addrspace(4)* [[LOC]], align 32
284; CHECK-NEXT:    ret <4 x i64> [[REF]]
285;
286entry:
287  %loc.bc = bitcast <4 x i64> addrspace(4)* %loc to i8 addrspace(4)*
288  %src.bc = bitcast <4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*
289  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 32, i1 false)
290  %ref = load <4 x i64>, <4 x i64> addrspace(4)* %loc
291  ret <4 x i64> %ref
292}
293
294define <1 x i64 addrspace(4)*> @forward_memcpy_vload3(<4 x i64 addrspace(4)*> addrspace(4)* %loc) {
295; CHECK-LABEL: @forward_memcpy_vload3(
296; CHECK-NEXT:  entry:
297; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast <4 x i64 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
298; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 32, i1 false)
299; CHECK-NEXT:    ret <1 x i64 addrspace(4)*> <i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3)>
300;
301entry:
302  %loc.bc = bitcast <4 x i64 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
303  %src.bc = bitcast <4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*
304  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 32, i1 false)
305  %ref = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*> addrspace(4)* %loc
306  %val = extractelement <4 x i64 addrspace(4)*> %ref, i32 0
307  %ret = insertelement <1 x i64 addrspace(4)*> undef, i64 addrspace(4)* %val, i32 0
308  ret <1 x i64 addrspace(4)*> %ret
309}
310
311; Can forward since we can do so w/o breaking types
312define i8 addrspace(4)* @forward_memcpy_zero(i8 addrspace(4)* addrspace(4)* %loc) {
313; CHECK-LABEL: @forward_memcpy_zero(
314; CHECK-NEXT:  entry:
315; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
316; CHECK-NEXT:    call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @ZeroConstant to i8*), i64 8, i1 false)
317; CHECK-NEXT:    ret i8 addrspace(4)* null
318;
319entry:
320  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
321  %src.bc = bitcast <4 x i64>* @ZeroConstant to i8*
322  call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
323  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
324  ret i8 addrspace(4)* %ref
325}
326
327declare void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* nocapture, i8* nocapture, i64, i1) nounwind
328
329
330; Same as the neg_forward_store cases, but for non defs.
331; (Pretend we wrote out the alwaysfalse idiom above.)
332define i8 addrspace(4)* @neg_store_clobber(i8 addrspace(4)* addrspace(4)* %loc) {
333; CHECK-LABEL: @neg_store_clobber(
334; CHECK-NEXT:  entry:
335; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i64> addrspace(4)*
336; CHECK-NEXT:    store <2 x i64> <i64 4, i64 4>, <2 x i64> addrspace(4)* [[LOC_BC]], align 16
337; CHECK-NEXT:    [[LOC_OFF:%.*]] = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], i64 1
338; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC_OFF]], align 8
339; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
340;
341entry:
342  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i64> addrspace(4)*
343  store <2 x i64> <i64 4, i64 4>, <2 x i64> addrspace(4)* %loc.bc
344  %loc.off = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc, i64 1
345  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
346  ret i8 addrspace(4)* %ref
347}
348
349declare void @use(<2 x i64>) inaccessiblememonly
350
351; Same as the neg_forward_store cases, but for non defs.
352; (Pretend we wrote out the alwaysfalse idiom above.)
353define i8 addrspace(4)* @neg_load_clobber(i8 addrspace(4)* addrspace(4)* %loc) {
354; CHECK-LABEL: @neg_load_clobber(
355; CHECK-NEXT:  entry:
356; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i64> addrspace(4)*
357; CHECK-NEXT:    [[V:%.*]] = load <2 x i64>, <2 x i64> addrspace(4)* [[LOC_BC]], align 16
358; CHECK-NEXT:    call void @use(<2 x i64> [[V]])
359; CHECK-NEXT:    [[LOC_OFF:%.*]] = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], i64 1
360; CHECK-NEXT:    [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC_OFF]], align 8
361; CHECK-NEXT:    ret i8 addrspace(4)* [[REF]]
362;
363entry:
364  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i64> addrspace(4)*
365  %v = load <2 x i64>, <2 x i64> addrspace(4)* %loc.bc
366  call void @use(<2 x i64> %v)
367  %loc.off = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc, i64 1
368  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
369  ret i8 addrspace(4)* %ref
370}
371
372define i8 addrspace(4)* @store_clobber_zero(i8 addrspace(4)* addrspace(4)* %loc) {
373; CHECK-LABEL: @store_clobber_zero(
374; CHECK-NEXT:  entry:
375; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i64> addrspace(4)*
376; CHECK-NEXT:    store <2 x i64> zeroinitializer, <2 x i64> addrspace(4)* [[LOC_BC]], align 16
377; CHECK-NEXT:    [[LOC_OFF:%.*]] = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], i64 1
378; CHECK-NEXT:    ret i8 addrspace(4)* null
379;
380entry:
381  %loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i64> addrspace(4)*
382  store <2 x i64> zeroinitializer, <2 x i64> addrspace(4)* %loc.bc
383  %loc.off = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc, i64 1
384  %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
385  ret i8 addrspace(4)* %ref
386}
387
388
389define void @smaller_vector(i8* %p) {
390; CHECK-LABEL: @smaller_vector(
391; CHECK-NEXT:  entry:
392; CHECK-NEXT:    [[A:%.*]] = bitcast i8* [[P:%.*]] to <4 x i64 addrspace(4)*>*
393; CHECK-NEXT:    [[B:%.*]] = bitcast i8* [[P]] to <2 x i64 addrspace(4)*>*
394; CHECK-NEXT:    [[V4:%.*]] = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*>* [[A]], align 32
395; CHECK-NEXT:    [[V2:%.*]] = load <2 x i64 addrspace(4)*>, <2 x i64 addrspace(4)*>* [[B]], align 32
396; CHECK-NEXT:    call void @use.v2(<2 x i64 addrspace(4)*> [[V2]])
397; CHECK-NEXT:    call void @use.v4(<4 x i64 addrspace(4)*> [[V4]])
398; CHECK-NEXT:    ret void
399;
400entry:
401  %a = bitcast i8* %p to <4 x i64 addrspace(4)*>*
402  %b = bitcast i8* %p to <2 x i64 addrspace(4)*>*
403  %v4 = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*>* %a, align 32
404  %v2 = load <2 x i64 addrspace(4)*>, <2 x i64 addrspace(4)*>* %b, align 32
405  call void @use.v2(<2 x i64 addrspace(4)*> %v2)
406  call void @use.v4(<4 x i64 addrspace(4)*> %v4)
407  ret void
408}
409
410define i64 addrspace(4)* @vector_extract(i8* %p) {
411; CHECK-LABEL: @vector_extract(
412; CHECK-NEXT:  entry:
413; CHECK-NEXT:    [[A:%.*]] = bitcast i8* [[P:%.*]] to <4 x i64 addrspace(4)*>*
414; CHECK-NEXT:    [[B:%.*]] = bitcast i8* [[P]] to i64 addrspace(4)**
415; CHECK-NEXT:    [[V4:%.*]] = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*>* [[A]], align 32
416; CHECK-NEXT:    [[RES:%.*]] = load i64 addrspace(4)*, i64 addrspace(4)** [[B]], align 32
417; CHECK-NEXT:    call void @use.v4(<4 x i64 addrspace(4)*> [[V4]])
418; CHECK-NEXT:    ret i64 addrspace(4)* [[RES]]
419;
420entry:
421  %a = bitcast i8* %p to <4 x i64 addrspace(4)*>*
422  %b = bitcast i8* %p to i64 addrspace(4)**
423  %v4 = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*>* %a, align 32
424  %res = load i64 addrspace(4)*, i64 addrspace(4)** %b, align 32
425  call void @use.v4(<4 x i64 addrspace(4)*> %v4)
426  ret i64 addrspace(4)* %res
427}
428
429declare void @use.v2(<2 x i64 addrspace(4)*>)
430declare void @use.v4(<4 x i64 addrspace(4)*>)
431define i8 addrspace(5)* @multini(i1 %alwaysFalse, i8 addrspace(4)* %val, i8 addrspace(4)** %loc) {
432; CHECK-LABEL: @multini(
433; CHECK-NEXT:  entry:
434; CHECK-NEXT:    store i8 addrspace(4)* [[VAL:%.*]], i8 addrspace(4)** [[LOC:%.*]], align 8
435; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
436; CHECK:       neverTaken:
437; CHECK-NEXT:    [[LOC_BC:%.*]] = bitcast i8 addrspace(4)** [[LOC]] to i8 addrspace(5)**
438; CHECK-NEXT:    [[DIFFERENTAS:%.*]] = load i8 addrspace(5)*, i8 addrspace(5)** [[LOC_BC]], align 8
439; CHECK-NEXT:    ret i8 addrspace(5)* [[DIFFERENTAS]]
440; CHECK:       alwaysTaken:
441; CHECK-NEXT:    ret i8 addrspace(5)* null
442;
443entry:
444  store i8 addrspace(4)* %val, i8 addrspace(4)** %loc
445  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
446
447neverTaken:
448  %loc.bc = bitcast i8 addrspace(4)** %loc to i8 addrspace(5)**
449  %differentas = load i8 addrspace(5)*, i8 addrspace(5)** %loc.bc
450  ret i8 addrspace(5)* %differentas
451
452alwaysTaken:
453  ret i8 addrspace(5)* null
454}
455