1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -o - -S -load-store-vectorizer -dce %s | FileCheck %s
3
4; Make sure LoadStoreVectorizer vectorizes the loads below.
5; In order to prove that the vectorization is safe, it tries to
6; match nested adds and find an expression that adds a constant
7; value to an existing index and the result doesn't overflow.
8
9target triple = "x86_64--"
10
11define void @ld_v4i8_add_nsw(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) {
12; CHECK-LABEL: @ld_v4i8_add_nsw(
13; CHECK-NEXT:  bb:
14; CHECK-NEXT:    [[TMP:%.*]] = add nsw i32 [[V0:%.*]], -1
15; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[V1:%.*]], [[TMP]]
16; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
17; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]]
18; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP3]] to <4 x i8>*
19; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1
20; CHECK-NEXT:    [[TMP41:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0
21; CHECK-NEXT:    [[TMP82:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1
22; CHECK-NEXT:    [[TMP133:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2
23; CHECK-NEXT:    [[TMP184:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3
24; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP41]], i32 0
25; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP82]], i32 1
26; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP133]], i32 2
27; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP184]], i32 3
28; CHECK-NEXT:    store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]]
29; CHECK-NEXT:    ret void
30;
31bb:
32  %tmp = add nsw i32 %v0, -1
33  %tmp1 = add nsw i32 %v1, %tmp
34  %tmp2 = sext i32 %tmp1 to i64
35  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
36  %tmp4 = load i8, i8* %tmp3, align 1
37  %tmp5 = add nsw i32 %v1, %v0
38  %tmp6 = sext i32 %tmp5 to i64
39  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
40  %tmp8 = load i8, i8* %tmp7, align 1
41  %tmp9 = add nsw i32 %v0, 1
42  %tmp10 = add nsw i32 %v1, %tmp9
43  %tmp11 = sext i32 %tmp10 to i64
44  %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11
45  %tmp13 = load i8, i8* %tmp12, align 1
46  %tmp14 = add nsw i32 %v0, 2
47  %tmp15 = add nsw i32 %v1, %tmp14
48  %tmp16 = sext i32 %tmp15 to i64
49  %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16
50  %tmp18 = load i8, i8* %tmp17, align 1
51  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0
52  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1
53  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2
54  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3
55  store <4 x i8> %tmp22, <4 x i8>* %dst
56  ret void
57}
58
59define void @ld_v4i8_add_nuw(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) {
60; CHECK-LABEL: @ld_v4i8_add_nuw(
61; CHECK-NEXT:  bb:
62; CHECK-NEXT:    [[TMP:%.*]] = add nuw i32 [[V0:%.*]], -1
63; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i32 [[V1:%.*]], [[TMP]]
64; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[TMP1]] to i64
65; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]]
66; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP3]] to <4 x i8>*
67; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1
68; CHECK-NEXT:    [[TMP41:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0
69; CHECK-NEXT:    [[TMP82:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1
70; CHECK-NEXT:    [[TMP133:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2
71; CHECK-NEXT:    [[TMP184:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3
72; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP41]], i32 0
73; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP82]], i32 1
74; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP133]], i32 2
75; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP184]], i32 3
76; CHECK-NEXT:    store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]]
77; CHECK-NEXT:    ret void
78;
79bb:
80  %tmp = add nuw i32 %v0, -1
81  %tmp1 = add nuw i32 %v1, %tmp
82  %tmp2 = zext i32 %tmp1 to i64
83  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
84  %tmp4 = load i8, i8* %tmp3, align 1
85  %tmp5 = add nuw i32 %v1, %v0
86  %tmp6 = zext i32 %tmp5 to i64
87  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
88  %tmp8 = load i8, i8* %tmp7, align 1
89  %tmp9 = add nuw i32 %v0, 1
90  %tmp10 = add nuw i32 %v1, %tmp9
91  %tmp11 = zext i32 %tmp10 to i64
92  %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11
93  %tmp13 = load i8, i8* %tmp12, align 1
94  %tmp14 = add nuw i32 %v0, 2
95  %tmp15 = add nuw i32 %v1, %tmp14
96  %tmp16 = zext i32 %tmp15 to i64
97  %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16
98  %tmp18 = load i8, i8* %tmp17, align 1
99  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0
100  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1
101  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2
102  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3
103  store <4 x i8> %tmp22, <4 x i8>* %dst
104  ret void
105}
106
107define void @ld_v4i8_add_known_bits(i32 %ind0, i32 %ind1, i8* %src, <4 x i8>* %dst) {
108; CHECK-LABEL: @ld_v4i8_add_known_bits(
109; CHECK-NEXT:  bb:
110; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4
111; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 4
112; CHECK-NEXT:    [[TMP:%.*]] = add i32 [[V0]], -1
113; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[V1]], [[TMP]]
114; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
115; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]]
116; CHECK-NEXT:    [[TMP4:%.*]] = load i8, i8* [[TMP3]], align 1
117; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
118; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
119; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP6]]
120; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <3 x i8>*
121; CHECK-NEXT:    [[TMP1:%.*]] = load <3 x i8>, <3 x i8>* [[TMP0]], align 1
122; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <3 x i8> [[TMP1]], i32 0
123; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <3 x i8> [[TMP1]], i32 1
124; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <3 x i8> [[TMP1]], i32 2
125; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP4]], i32 0
126; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1
127; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2
128; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3
129; CHECK-NEXT:    store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]]
130; CHECK-NEXT:    ret void
131;
132bb:
133  %v0 = mul i32 %ind0, 4
134  %v1 = mul i32 %ind1, 4
135  %tmp = add i32 %v0, -1
136  %tmp1 = add i32 %v1, %tmp
137  %tmp2 = sext i32 %tmp1 to i64
138  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
139  %tmp4 = load i8, i8* %tmp3, align 1
140  %tmp5 = add i32 %v1, %v0
141  %tmp6 = sext i32 %tmp5 to i64
142  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
143  %tmp8 = load i8, i8* %tmp7, align 1
144  %tmp9 = add i32 %v0, 1
145  %tmp10 = add i32 %v1, %tmp9
146  %tmp11 = sext i32 %tmp10 to i64
147  %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11
148  %tmp13 = load i8, i8* %tmp12, align 1
149  %tmp14 = add i32 %v0, 2
150  %tmp15 = add i32 %v1, %tmp14
151  %tmp16 = sext i32 %tmp15 to i64
152  %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16
153  %tmp18 = load i8, i8* %tmp17, align 1
154  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0
155  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1
156  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2
157  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3
158  store <4 x i8> %tmp22, <4 x i8>* %dst
159  ret void
160}
161
162define void @ld_v4i8_add_known_bits1(i32 %ind0, i32 %ind1, i8* %src, <4 x i8>* %dst) {
163; CHECK-LABEL: @ld_v4i8_add_known_bits1(
164; CHECK-NEXT:  bb:
165; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4
166; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 4
167; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
168; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
169; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]]
170; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <4 x i8>*
171; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1
172; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0
173; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1
174; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2
175; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3
176; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP44]], i32 0
177; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1
178; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2
179; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3
180; CHECK-NEXT:    store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]]
181; CHECK-NEXT:    ret void
182;
183bb:
184  %v0 = mul i32 %ind0, 4
185  %v1 = mul i32 %ind1, 4
186  %tmp = add i32 %v0, 3
187  %tmp1 = add i32 %v1, %tmp
188  %tmp2 = sext i32 %tmp1 to i64
189  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
190  %tmp4 = load i8, i8* %tmp3, align 1
191  %tmp5 = add i32 %v1, %v0
192  %tmp6 = sext i32 %tmp5 to i64
193  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
194  %tmp8 = load i8, i8* %tmp7, align 1
195  %tmp9 = add i32 %v0, 1
196  %tmp10 = add i32 %v1, %tmp9
197  %tmp11 = sext i32 %tmp10 to i64
198  %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11
199  %tmp13 = load i8, i8* %tmp12, align 1
200  %tmp14 = add i32 %v0, 2
201  %tmp15 = add i32 %v1, %tmp14
202  %tmp16 = sext i32 %tmp15 to i64
203  %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16
204  %tmp18 = load i8, i8* %tmp17, align 1
205  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0
206  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1
207  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2
208  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3
209  store <4 x i8> %tmp22, <4 x i8>* %dst
210  ret void
211}
212
213define void @ld_v4i8_add_known_bits_by_assume(i32 %ind0, i32 %ind1, i8* %src, <4 x i8>* %dst) {
214; CHECK-LABEL: @ld_v4i8_add_known_bits_by_assume(
215; CHECK-NEXT:  bb:
216; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 3
217; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3
218; CHECK-NEXT:    [[AND_I:%.*]] = and i32 [[V0]], 3
219; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[AND_I]], 0
220; CHECK-NEXT:    [[AND_I_1:%.*]] = and i32 [[V1]], 3
221; CHECK-NEXT:    [[CMP_I_1:%.*]] = icmp eq i32 [[AND_I_1]], 0
222; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I]])
223; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I_1]])
224; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
225; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
226; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]]
227; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <4 x i8>*
228; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1
229; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0
230; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1
231; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2
232; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3
233; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP44]], i32 0
234; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1
235; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2
236; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3
237; CHECK-NEXT:    store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]]
238; CHECK-NEXT:    ret void
239;
240bb:
241  %v0 = mul i32 %ind0, 3
242  %v1 = mul i32 %ind1, 3
243  %and.i = and i32 %v0, 3
244  %cmp.i = icmp eq i32 %and.i, 0
245  %and.i.1 = and i32 %v1, 3
246  %cmp.i.1 = icmp eq i32 %and.i.1, 0
247  call void @llvm.assume(i1 %cmp.i)
248  call void @llvm.assume(i1 %cmp.i.1)
249  %tmp = add i32 %v0, 3
250  %tmp1 = add i32 %v1, %tmp
251  %tmp2 = sext i32 %tmp1 to i64
252  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
253  %tmp4 = load i8, i8* %tmp3, align 1
254  %tmp5 = add i32 %v1, %v0
255  %tmp6 = sext i32 %tmp5 to i64
256  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
257  %tmp8 = load i8, i8* %tmp7, align 1
258  %tmp9 = add i32 %v0, 1
259  %tmp10 = add i32 %v1, %tmp9
260  %tmp11 = sext i32 %tmp10 to i64
261  %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11
262  %tmp13 = load i8, i8* %tmp12, align 1
263  %tmp14 = add i32 %v0, 2
264  %tmp15 = add i32 %v1, %tmp14
265  %tmp16 = sext i32 %tmp15 to i64
266  %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16
267  %tmp18 = load i8, i8* %tmp17, align 1
268  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0
269  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1
270  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2
271  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3
272  store <4 x i8> %tmp22, <4 x i8>* %dst
273  ret void
274}
275
276declare void @llvm.assume(i1)
277
278define void @ld_v4i8_add_assume_on_arg(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) {
279; CHECK-LABEL: @ld_v4i8_add_assume_on_arg(
280; CHECK-NEXT:  bb:
281; CHECK-NEXT:    [[AND_I:%.*]] = and i32 [[V0:%.*]], 3
282; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[AND_I]], 0
283; CHECK-NEXT:    [[AND_I_1:%.*]] = and i32 [[V1:%.*]], 3
284; CHECK-NEXT:    [[CMP_I_1:%.*]] = icmp eq i32 [[AND_I_1]], 0
285; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I]])
286; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I_1]])
287; CHECK-NEXT:    [[TMP:%.*]] = add nsw i32 [[V0]], -1
288; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[V1]], [[TMP]]
289; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
290; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]]
291; CHECK-NEXT:    [[TMP4:%.*]] = load i8, i8* [[TMP3]], align 1
292; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
293; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
294; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP6]]
295; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <3 x i8>*
296; CHECK-NEXT:    [[TMP1:%.*]] = load <3 x i8>, <3 x i8>* [[TMP0]], align 1
297; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <3 x i8> [[TMP1]], i32 0
298; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <3 x i8> [[TMP1]], i32 1
299; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <3 x i8> [[TMP1]], i32 2
300; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP4]], i32 0
301; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1
302; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2
303; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3
304; CHECK-NEXT:    store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]]
305; CHECK-NEXT:    ret void
306;
307bb:
308  %and.i = and i32 %v0, 3
309  %cmp.i = icmp eq i32 %and.i, 0
310  %and.i.1 = and i32 %v1, 3
311  %cmp.i.1 = icmp eq i32 %and.i.1, 0
312  call void @llvm.assume(i1 %cmp.i)
313  call void @llvm.assume(i1 %cmp.i.1)
314  %tmp = add nsw i32 %v0, -1
315  %tmp1 = add i32 %v1, %tmp
316  %tmp2 = sext i32 %tmp1 to i64
317  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
318  %tmp4 = load i8, i8* %tmp3, align 1
319  %tmp5 = add i32 %v1, %v0
320  %tmp6 = sext i32 %tmp5 to i64
321  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
322  %tmp8 = load i8, i8* %tmp7, align 1
323  %tmp9 = add nsw i32 %v0, 1
324  %tmp10 = add i32 %v1, %tmp9
325  %tmp11 = sext i32 %tmp10 to i64
326  %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11
327  %tmp13 = load i8, i8* %tmp12, align 1
328  %tmp14 = add nsw i32 %v0, 2
329  %tmp15 = add i32 %v1, %tmp14
330  %tmp16 = sext i32 %tmp15 to i64
331  %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16
332  %tmp18 = load i8, i8* %tmp17, align 1
333  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0
334  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1
335  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2
336  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3
337  store <4 x i8> %tmp22, <4 x i8>* %dst
338  ret void
339}
340
341define void @ld_v4i8_add_assume_on_arg1(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) {
342; CHECK-LABEL: @ld_v4i8_add_assume_on_arg1(
343; CHECK-NEXT:  bb:
344; CHECK-NEXT:    [[AND_I:%.*]] = and i32 [[V0:%.*]], 3
345; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[AND_I]], 0
346; CHECK-NEXT:    [[AND_I_1:%.*]] = and i32 [[V1:%.*]], 3
347; CHECK-NEXT:    [[CMP_I_1:%.*]] = icmp eq i32 [[AND_I_1]], 0
348; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I]])
349; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I_1]])
350; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
351; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
352; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]]
353; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <4 x i8>*
354; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1
355; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0
356; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1
357; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2
358; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3
359; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP44]], i32 0
360; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1
361; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2
362; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3
363; CHECK-NEXT:    store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]]
364; CHECK-NEXT:    ret void
365;
366bb:
367  %and.i = and i32 %v0, 3
368  %cmp.i = icmp eq i32 %and.i, 0
369  %and.i.1 = and i32 %v1, 3
370  %cmp.i.1 = icmp eq i32 %and.i.1, 0
371  call void @llvm.assume(i1 %cmp.i)
372  call void @llvm.assume(i1 %cmp.i.1)
373  %tmp = add nsw i32 %v0, 3
374  %tmp1 = add i32 %v1, %tmp
375  %tmp2 = sext i32 %tmp1 to i64
376  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
377  %tmp4 = load i8, i8* %tmp3, align 1
378  %tmp5 = add i32 %v1, %v0
379  %tmp6 = sext i32 %tmp5 to i64
380  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
381  %tmp8 = load i8, i8* %tmp7, align 1
382  %tmp9 = add nsw i32 %v0, 1
383  %tmp10 = add i32 %v1, %tmp9
384  %tmp11 = sext i32 %tmp10 to i64
385  %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11
386  %tmp13 = load i8, i8* %tmp12, align 1
387  %tmp14 = add nsw i32 %v0, 2
388  %tmp15 = add i32 %v1, %tmp14
389  %tmp16 = sext i32 %tmp15 to i64
390  %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16
391  %tmp18 = load i8, i8* %tmp17, align 1
392  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0
393  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1
394  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2
395  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3
396  store <4 x i8> %tmp22, <4 x i8>* %dst
397  ret void
398}
399
400; Address computations are partly separated by control flow and with llvm.assume placed
401; in the second basic block
402
403define void @ld_v2i8_add_different_contexts(i32 %ind0, i32 %ind1, i8* %src, <2 x i8>* %dst) {
404; CHECK-LABEL: @ld_v2i8_add_different_contexts(
405; CHECK-NEXT:  bb:
406; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4
407; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3
408; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
409; CHECK-NEXT:    [[BIT_COND:%.*]] = icmp eq i32 [[V1]], 0
410; CHECK-NEXT:    br i1 [[BIT_COND]], label [[BB_LOADS:%.*]], label [[BB_SKIP:%.*]]
411; CHECK:       bb.loads:
412; CHECK-NEXT:    call void @llvm.assume(i1 [[BIT_COND]])
413; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
414; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]]
415; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <2 x i8>*
416; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i8>, <2 x i8>* [[TMP0]], align 1
417; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0
418; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1
419; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0
420; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1
421; CHECK-NEXT:    store <2 x i8> [[TMP20]], <2 x i8>* [[DST:%.*]]
422; CHECK-NEXT:    br label [[BB_SKIP]]
423; CHECK:       bb.skip:
424; CHECK-NEXT:    ret void
425;
426bb:
427  %v0 = mul i32 %ind0, 4
428  %v1 = mul i32 %ind1, 3
429  %tmp5 = add i32 %v1, %v0
430  %bit_cond = icmp eq i32 %v1, 0
431  br i1 %bit_cond, label %bb.loads, label %bb.skip
432
433bb.loads:
434  call void @llvm.assume(i1 %bit_cond)
435  %tmp = add nsw i32 %v0, 1
436  %tmp1 = add i32 %v1, %tmp
437  %tmp2 = sext i32 %tmp1 to i64
438  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
439  %tmp4 = load i8, i8* %tmp3, align 1
440  %tmp6 = sext i32 %tmp5 to i64
441  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
442  %tmp8 = load i8, i8* %tmp7, align 1
443  %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0
444  %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1
445  store <2 x i8> %tmp20, <2 x i8>* %dst
446  br label %bb.skip
447
448bb.skip:
449  ret void
450}
451
452; Same as ld_v2i8_add_different_contexts but with llvm.assume placed between loads
453
454define void @ld_v2i8_add_different_contexts1(i32 %ind0, i32 %ind1, i8* %src, <2 x i8>* %dst) {
455; CHECK-LABEL: @ld_v2i8_add_different_contexts1(
456; CHECK-NEXT:  bb:
457; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4
458; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3
459; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
460; CHECK-NEXT:    [[BIT_COND:%.*]] = icmp eq i32 [[V1]], 0
461; CHECK-NEXT:    br i1 [[BIT_COND]], label [[BB_LOADS:%.*]], label [[BB_SKIP:%.*]]
462; CHECK:       bb.loads:
463; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
464; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]]
465; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <2 x i8>*
466; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i8>, <2 x i8>* [[TMP0]], align 1
467; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0
468; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1
469; CHECK-NEXT:    call void @llvm.assume(i1 [[BIT_COND]])
470; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0
471; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1
472; CHECK-NEXT:    store <2 x i8> [[TMP20]], <2 x i8>* [[DST:%.*]]
473; CHECK-NEXT:    br label [[BB_SKIP]]
474; CHECK:       bb.skip:
475; CHECK-NEXT:    ret void
476;
477bb:
478  %v0 = mul i32 %ind0, 4
479  %v1 = mul i32 %ind1, 3
480  %tmp5 = add i32 %v1, %v0
481  %bit_cond = icmp eq i32 %v1, 0
482  br i1 %bit_cond, label %bb.loads, label %bb.skip
483
484bb.loads:
485  %tmp6 = sext i32 %tmp5 to i64
486  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
487  %tmp8 = load i8, i8* %tmp7, align 1
488  call void @llvm.assume(i1 %bit_cond)
489  %tmp = add nsw i32 %v0, 1
490  %tmp1 = add i32 %v1, %tmp
491  %tmp2 = sext i32 %tmp1 to i64
492  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
493  %tmp4 = load i8, i8* %tmp3, align 1
494  %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0
495  %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1
496  store <2 x i8> %tmp20, <2 x i8>* %dst
497  br label %bb.skip
498
499bb.skip:
500  ret void
501}
502
503; llvm.assume is placed between loads in a single basic block
504
505define void @ld_v2i8_add_context(i32 %ind0, i32 %ind1, i8* %src, <2 x i8>* %dst) {
506; CHECK-LABEL: @ld_v2i8_add_context(
507; CHECK-NEXT:  bb:
508; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4
509; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3
510; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
511; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
512; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]]
513; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <2 x i8>*
514; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i8>, <2 x i8>* [[TMP0]], align 1
515; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0
516; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1
517; CHECK-NEXT:    [[BIT_COND:%.*]] = icmp eq i32 [[TMP5]], 0
518; CHECK-NEXT:    call void @llvm.assume(i1 [[BIT_COND]])
519; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0
520; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1
521; CHECK-NEXT:    store <2 x i8> [[TMP20]], <2 x i8>* [[DST:%.*]]
522; CHECK-NEXT:    ret void
523;
524bb:
525  %v0 = mul i32 %ind0, 4
526  %v1 = mul i32 %ind1, 3
527  %tmp5 = add i32 %v1, %v0
528  %tmp6 = sext i32 %tmp5 to i64
529  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
530  %tmp8 = load i8, i8* %tmp7, align 1
531  %bit_cond = icmp eq i32 %tmp5, 0
532  call void @llvm.assume(i1 %bit_cond)
533  %tmp = add nsw i32 %v0, 1
534  %tmp1 = add i32 %v1, %tmp
535  %tmp2 = sext i32 %tmp1 to i64
536  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
537  %tmp4 = load i8, i8* %tmp3, align 1
538  %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0
539  %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1
540  store <2 x i8> %tmp20, <2 x i8>* %dst
541  ret void
542}
543
544; Placing llvm.assume after all the loads and stores in the basic block still works
545
546define void @ld_v2i8_add_context1(i32 %ind0, i32 %ind1, i8* %src, <2 x i8>* %dst) {
547; CHECK-LABEL: @ld_v2i8_add_context1(
548; CHECK-NEXT:  bb:
549; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4
550; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3
551; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
552; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
553; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]]
554; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <2 x i8>*
555; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i8>, <2 x i8>* [[TMP0]], align 1
556; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0
557; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1
558; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0
559; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1
560; CHECK-NEXT:    store <2 x i8> [[TMP20]], <2 x i8>* [[DST:%.*]]
561; CHECK-NEXT:    [[BIT_COND:%.*]] = icmp eq i32 [[TMP5]], 0
562; CHECK-NEXT:    call void @llvm.assume(i1 [[BIT_COND]])
563; CHECK-NEXT:    ret void
564;
565bb:
566  %v0 = mul i32 %ind0, 4
567  %v1 = mul i32 %ind1, 3
568  %tmp5 = add i32 %v1, %v0
569  %tmp6 = sext i32 %tmp5 to i64
570  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
571  %tmp8 = load i8, i8* %tmp7, align 1
572  %tmp = add nsw i32 %v0, 1
573  %tmp1 = add i32 %v1, %tmp
574  %tmp2 = sext i32 %tmp1 to i64
575  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
576  %tmp4 = load i8, i8* %tmp3, align 1
577  %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0
578  %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1
579  store <2 x i8> %tmp20, <2 x i8>* %dst
580  %bit_cond = icmp eq i32 %tmp5, 0
581  call void @llvm.assume(i1 %bit_cond)
582  ret void
583}
584
585; Make sure we don't vectorize the loads below because the source of
586; sext instructions doesn't have the nsw flag or known bits allowing
587; to apply the vectorization.
588
589define void @ld_v4i8_add_not_safe(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) {
590; CHECK-LABEL: @ld_v4i8_add_not_safe(
591; CHECK-NEXT:  bb:
592; CHECK-NEXT:    [[TMP:%.*]] = add nsw i32 [[V0:%.*]], -1
593; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[V1:%.*]], [[TMP]]
594; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
595; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]]
596; CHECK-NEXT:    [[TMP4:%.*]] = load i8, i8* [[TMP3]], align 1
597; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]
598; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64
599; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP6]]
600; CHECK-NEXT:    [[TMP8:%.*]] = load i8, i8* [[TMP7]], align 1
601; CHECK-NEXT:    [[TMP9:%.*]] = add nsw i32 [[V0]], 1
602; CHECK-NEXT:    [[TMP10:%.*]] = add i32 [[V1]], [[TMP9]]
603; CHECK-NEXT:    [[TMP11:%.*]] = sext i32 [[TMP10]] to i64
604; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP11]]
605; CHECK-NEXT:    [[TMP13:%.*]] = load i8, i8* [[TMP12]], align 1
606; CHECK-NEXT:    [[TMP14:%.*]] = add nsw i32 [[V0]], 2
607; CHECK-NEXT:    [[TMP15:%.*]] = add i32 [[V1]], [[TMP14]]
608; CHECK-NEXT:    [[TMP16:%.*]] = sext i32 [[TMP15]] to i64
609; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP16]]
610; CHECK-NEXT:    [[TMP18:%.*]] = load i8, i8* [[TMP17]], align 1
611; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP4]], i32 0
612; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP8]], i32 1
613; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP13]], i32 2
614; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP18]], i32 3
615; CHECK-NEXT:    store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]]
616; CHECK-NEXT:    ret void
617;
618bb:
619  %tmp = add nsw i32 %v0, -1
620  %tmp1 = add i32 %v1, %tmp
621  %tmp2 = sext i32 %tmp1 to i64
622  %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2
623  %tmp4 = load i8, i8* %tmp3, align 1
624  %tmp5 = add i32 %v1, %v0
625  %tmp6 = sext i32 %tmp5 to i64
626  %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6
627  %tmp8 = load i8, i8* %tmp7, align 1
628  %tmp9 = add nsw i32 %v0, 1
629  %tmp10 = add i32 %v1, %tmp9
630  %tmp11 = sext i32 %tmp10 to i64
631  %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11
632  %tmp13 = load i8, i8* %tmp12, align 1
633  %tmp14 = add nsw i32 %v0, 2
634  %tmp15 = add i32 %v1, %tmp14
635  %tmp16 = sext i32 %tmp15 to i64
636  %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16
637  %tmp18 = load i8, i8* %tmp17, align 1
638  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0
639  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1
640  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2
641  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3
642  store <4 x i8> %tmp22, <4 x i8>* %dst
643  ret void
644}
645