1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -scoped-noalias-aa -slp-vectorizer -mtriple=arm64-apple-darwin -enable-new-pm=false -S %s | FileCheck %s
3; RUN: opt -aa-pipeline='basic-aa,scoped-noalias-aa' -passes=slp-vectorizer -mtriple=arm64-apple-darwin -S %s | FileCheck %s
4
5define void @needs_versioning_not_profitable(i32* %dst, i32* %src) {
6; CHECK-LABEL: @needs_versioning_not_profitable(
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4
9; CHECK-NEXT:    [[R_0:%.*]] = ashr i32 [[SRC_0]], 16
10; CHECK-NEXT:    store i32 [[R_0]], i32* [[DST:%.*]], align 4
11; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
12; CHECK-NEXT:    [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4
13; CHECK-NEXT:    [[R_1:%.*]] = ashr i32 [[SRC_1]], 16
14; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
15; CHECK-NEXT:    store i32 [[R_1]], i32* [[DST_GEP_1]], align 4
16; CHECK-NEXT:    ret void
17;
18entry:
19  %src.0 = load i32, i32* %src, align 4
20  %r.0 = ashr i32 %src.0, 16
21  store i32 %r.0, i32* %dst, align 4
22  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
23  %src.1 = load i32, i32* %src.gep.1, align 4
24  %r.1 = ashr i32 %src.1, 16
25  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
26  store i32 %r.1, i32* %dst.gep.1, align 4
27  ret void
28}
29
30define void @needs_versioning_profitable(i32* %dst, i32* %src) {
31; CHECK-LABEL: @needs_versioning_profitable(
32; CHECK-NEXT:  entry:
33; CHECK-NEXT:    [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4
34; CHECK-NEXT:    [[R_0:%.*]] = ashr i32 [[SRC_0]], 16
35; CHECK-NEXT:    store i32 [[R_0]], i32* [[DST:%.*]], align 4
36; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
37; CHECK-NEXT:    [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4
38; CHECK-NEXT:    [[R_1:%.*]] = ashr i32 [[SRC_1]], 16
39; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
40; CHECK-NEXT:    store i32 [[R_1]], i32* [[DST_GEP_1]], align 4
41; CHECK-NEXT:    [[SRC_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
42; CHECK-NEXT:    [[SRC_2:%.*]] = load i32, i32* [[SRC_GEP_2]], align 4
43; CHECK-NEXT:    [[R_2:%.*]] = ashr i32 [[SRC_2]], 16
44; CHECK-NEXT:    [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2
45; CHECK-NEXT:    store i32 [[R_2]], i32* [[DST_GEP_2]], align 4
46; CHECK-NEXT:    [[SRC_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
47; CHECK-NEXT:    [[SRC_3:%.*]] = load i32, i32* [[SRC_GEP_3]], align 4
48; CHECK-NEXT:    [[R_3:%.*]] = ashr i32 [[SRC_3]], 16
49; CHECK-NEXT:    [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3
50; CHECK-NEXT:    store i32 [[R_3]], i32* [[DST_GEP_3]], align 4
51; CHECK-NEXT:    ret void
52;
53entry:
54  %src.0 = load i32, i32* %src, align 4
55  %r.0 = ashr i32 %src.0, 16
56  store i32 %r.0, i32* %dst, align 4
57  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
58  %src.1 = load i32, i32* %src.gep.1, align 4
59  %r.1 = ashr i32 %src.1, 16
60  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
61  store i32 %r.1, i32* %dst.gep.1, align 4
62  %src.gep.2 = getelementptr inbounds i32, i32* %src, i64 2
63  %src.2 = load i32, i32* %src.gep.2, align 4
64  %r.2 = ashr i32 %src.2, 16
65  %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2
66  store i32 %r.2, i32* %dst.gep.2, align 4
67  %src.gep.3 = getelementptr inbounds i32, i32* %src, i64 3
68  %src.3 = load i32, i32* %src.gep.3, align 4
69  %r.3 = ashr i32 %src.3, 16
70  %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3
71  store i32 %r.3, i32* %dst.gep.3, align 4
72
73  ret void
74}
75
76define void @needs_versioning_profitable_2_sources(i32* %dst, i32* %A, i32* %B) {
77; CHECK-LABEL: @needs_versioning_profitable_2_sources(
78; CHECK-NEXT:  entry:
79; CHECK-NEXT:    [[A_0:%.*]] = load i32, i32* [[A:%.*]], align 4
80; CHECK-NEXT:    [[B_0:%.*]] = load i32, i32* [[B:%.*]], align 4
81; CHECK-NEXT:    [[R_0:%.*]] = add i32 [[A_0]], [[B_0]]
82; CHECK-NEXT:    [[MUL_0:%.*]] = mul i32 [[R_0]], 2
83; CHECK-NEXT:    store i32 [[MUL_0]], i32* [[DST:%.*]], align 4
84; CHECK-NEXT:    [[A_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 1
85; CHECK-NEXT:    [[A_1:%.*]] = load i32, i32* [[A_GEP_1]], align 4
86; CHECK-NEXT:    [[B_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 1
87; CHECK-NEXT:    [[B_1:%.*]] = load i32, i32* [[B_GEP_1]], align 4
88; CHECK-NEXT:    [[R_1:%.*]] = add i32 [[A_1]], [[B_1]]
89; CHECK-NEXT:    [[MUL_1:%.*]] = mul i32 [[R_1]], 2
90; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
91; CHECK-NEXT:    store i32 [[MUL_1]], i32* [[DST_GEP_1]], align 4
92; CHECK-NEXT:    [[A_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 2
93; CHECK-NEXT:    [[A_2:%.*]] = load i32, i32* [[A_GEP_2]], align 4
94; CHECK-NEXT:    [[B_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 2
95; CHECK-NEXT:    [[B_2:%.*]] = load i32, i32* [[B_GEP_2]], align 4
96; CHECK-NEXT:    [[R_2:%.*]] = add i32 [[A_2]], [[B_2]]
97; CHECK-NEXT:    [[MUL_2:%.*]] = mul i32 [[R_2]], 2
98; CHECK-NEXT:    [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2
99; CHECK-NEXT:    store i32 [[MUL_2]], i32* [[DST_GEP_2]], align 4
100; CHECK-NEXT:    [[A_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 3
101; CHECK-NEXT:    [[A_3:%.*]] = load i32, i32* [[A_GEP_3]], align 4
102; CHECK-NEXT:    [[B_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 3
103; CHECK-NEXT:    [[B_3:%.*]] = load i32, i32* [[B_GEP_3]], align 4
104; CHECK-NEXT:    [[R_3:%.*]] = add i32 [[A_3]], [[B_3]]
105; CHECK-NEXT:    [[MUL_3:%.*]] = mul i32 [[R_3]], 2
106; CHECK-NEXT:    [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3
107; CHECK-NEXT:    store i32 [[MUL_3]], i32* [[DST_GEP_3]], align 4
108; CHECK-NEXT:    ret void
109;
110entry:
111  %A.0 = load i32, i32* %A, align 4
112  %B.0 = load i32, i32* %B, align 4
113  %r.0 = add i32 %A.0, %B.0
114  %mul.0 = mul i32 %r.0, 2
115  store i32 %mul.0, i32* %dst, align 4
116  %A.gep.1 = getelementptr inbounds i32, i32* %A, i64 1
117  %A.1 = load i32, i32* %A.gep.1, align 4
118  %B.gep.1 = getelementptr inbounds i32, i32* %B, i64 1
119  %B.1 = load i32, i32* %B.gep.1, align 4
120  %r.1 = add i32 %A.1, %B.1
121  %mul.1 = mul i32 %r.1, 2
122  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
123  store i32 %mul.1, i32* %dst.gep.1, align 4
124  %A.gep.2 = getelementptr inbounds i32, i32* %A, i64 2
125  %A.2 = load i32, i32* %A.gep.2, align 4
126  %B.gep.2 = getelementptr inbounds i32, i32* %B, i64 2
127  %B.2 = load i32, i32* %B.gep.2, align 4
128  %r.2 = add i32 %A.2, %B.2
129  %mul.2 = mul i32 %r.2, 2
130  %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2
131  store i32 %mul.2, i32* %dst.gep.2, align 4
132  %A.gep.3 = getelementptr inbounds i32, i32* %A, i64 3
133  %A.3 = load i32, i32* %A.gep.3, align 4
134  %B.gep.3 = getelementptr inbounds i32, i32* %B, i64 3
135  %B.3 = load i32, i32* %B.gep.3, align 4
136  %r.3 = add i32 %A.3, %B.3
137  %mul.3 = mul i32 %r.3, 2
138  %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3
139  store i32 %mul.3, i32* %dst.gep.3, align 4
140
141  ret void
142}
143
144declare void @use(i32)
145
146declare void @bar()
147
148define void @needs_versioning_profitable_split_points(i32* %dst, i32* %src) {
149; CHECK-LABEL: @needs_versioning_profitable_split_points(
150; CHECK-NEXT:  entry:
151; CHECK-NEXT:    call void @bar()
152; CHECK-NEXT:    call void @bar()
153; CHECK-NEXT:    call void @bar()
154; CHECK-NEXT:    [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4
155; CHECK-NEXT:    [[R_0:%.*]] = ashr i32 [[SRC_0]], 16
156; CHECK-NEXT:    store i32 [[R_0]], i32* [[DST:%.*]], align 4
157; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
158; CHECK-NEXT:    [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4
159; CHECK-NEXT:    [[R_1:%.*]] = ashr i32 [[SRC_1]], 16
160; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
161; CHECK-NEXT:    store i32 [[R_1]], i32* [[DST_GEP_1]], align 4
162; CHECK-NEXT:    [[SRC_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
163; CHECK-NEXT:    [[SRC_2:%.*]] = load i32, i32* [[SRC_GEP_2]], align 4
164; CHECK-NEXT:    [[R_2:%.*]] = ashr i32 [[SRC_2]], 16
165; CHECK-NEXT:    [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2
166; CHECK-NEXT:    store i32 [[R_2]], i32* [[DST_GEP_2]], align 4
167; CHECK-NEXT:    [[SRC_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
168; CHECK-NEXT:    [[SRC_3:%.*]] = load i32, i32* [[SRC_GEP_3]], align 4
169; CHECK-NEXT:    [[R_3:%.*]] = ashr i32 [[SRC_3]], 16
170; CHECK-NEXT:    [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3
171; CHECK-NEXT:    store i32 [[R_3]], i32* [[DST_GEP_3]], align 4
172; CHECK-NEXT:    call void @bar()
173; CHECK-NEXT:    ret void
174;
175entry:
176  call void @bar()
177  call void @bar()
178  call void @bar()
179
180  %src.0 = load i32, i32* %src, align 4
181  %r.0 = ashr i32 %src.0, 16
182  store i32 %r.0, i32* %dst, align 4
183  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
184  %src.1 = load i32, i32* %src.gep.1, align 4
185  %r.1 = ashr i32 %src.1, 16
186  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
187  store i32 %r.1, i32* %dst.gep.1, align 4
188  %src.gep.2 = getelementptr inbounds i32, i32* %src, i64 2
189  %src.2 = load i32, i32* %src.gep.2, align 4
190  %r.2 = ashr i32 %src.2, 16
191  %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2
192  store i32 %r.2, i32* %dst.gep.2, align 4
193  %src.gep.3 = getelementptr inbounds i32, i32* %src, i64 3
194  %src.3 = load i32, i32* %src.gep.3, align 4
195  %r.3 = ashr i32 %src.3, 16
196  %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3
197  store i32 %r.3, i32* %dst.gep.3, align 4
198
199  call void @bar()
200  ret void
201}
202
203define void @needs_versioning_profitable_load_used_outside_region1(i32* %dst, i32* %src, i1 %c) {
204; CHECK-LABEL: @needs_versioning_profitable_load_used_outside_region1(
205; CHECK-NEXT:  entry:
206; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
207; CHECK:       then:
208; CHECK-NEXT:    [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4
209; CHECK-NEXT:    [[R_0:%.*]] = ashr i32 [[SRC_0]], 16
210; CHECK-NEXT:    store i32 [[R_0]], i32* [[DST:%.*]], align 4
211; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
212; CHECK-NEXT:    [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4
213; CHECK-NEXT:    [[R_1:%.*]] = ashr i32 [[SRC_1]], 16
214; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
215; CHECK-NEXT:    store i32 [[R_1]], i32* [[DST_GEP_1]], align 4
216; CHECK-NEXT:    [[SRC_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
217; CHECK-NEXT:    [[SRC_2:%.*]] = load i32, i32* [[SRC_GEP_2]], align 4
218; CHECK-NEXT:    [[R_2:%.*]] = ashr i32 [[SRC_2]], 16
219; CHECK-NEXT:    [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2
220; CHECK-NEXT:    store i32 [[R_2]], i32* [[DST_GEP_2]], align 4
221; CHECK-NEXT:    [[SRC_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
222; CHECK-NEXT:    [[SRC_3:%.*]] = load i32, i32* [[SRC_GEP_3]], align 4
223; CHECK-NEXT:    [[R_3:%.*]] = ashr i32 [[SRC_3]], 16
224; CHECK-NEXT:    [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3
225; CHECK-NEXT:    store i32 [[R_3]], i32* [[DST_GEP_3]], align 4
226; CHECK-NEXT:    [[SRC_GEP_5:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 5
227; CHECK-NEXT:    [[L:%.*]] = load i32, i32* [[SRC_GEP_5]], align 4
228; CHECK-NEXT:    call void @use(i32 [[L]])
229; CHECK-NEXT:    br label [[EXIT]]
230; CHECK:       exit:
231; CHECK-NEXT:    ret void
232;
233entry:
234  br i1 %c, label %then, label %exit
235
236then:
237  %src.0 = load i32, i32* %src, align 4
238  %r.0 = ashr i32 %src.0, 16
239  store i32 %r.0, i32* %dst, align 4
240  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
241  %src.1 = load i32, i32* %src.gep.1, align 4
242  %r.1 = ashr i32 %src.1, 16
243  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
244  store i32 %r.1, i32* %dst.gep.1, align 4
245  %src.gep.2 = getelementptr inbounds i32, i32* %src, i64 2
246  %src.2 = load i32, i32* %src.gep.2, align 4
247  %r.2 = ashr i32 %src.2, 16
248  %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2
249  store i32 %r.2, i32* %dst.gep.2, align 4
250  %src.gep.3 = getelementptr inbounds i32, i32* %src, i64 3
251  %src.3 = load i32, i32* %src.gep.3, align 4
252  %r.3 = ashr i32 %src.3, 16
253  %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3
254  store i32 %r.3, i32* %dst.gep.3, align 4
255  %src.gep.5 = getelementptr inbounds i32, i32* %src, i64 5
256  %l = load i32, i32* %src.gep.5
257  call void @use(i32 %l)
258  br label %exit
259
260exit:
261  ret void
262}
263
264define void @needs_versioning_profitable_load_used_outside_region2(i32* %dst, i32* %src, i1 %c) {
265; CHECK-LABEL: @needs_versioning_profitable_load_used_outside_region2(
266; CHECK-NEXT:  entry:
267; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
268; CHECK:       then:
269; CHECK-NEXT:    [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4
270; CHECK-NEXT:    [[R_0:%.*]] = ashr i32 [[SRC_0]], 16
271; CHECK-NEXT:    store i32 [[R_0]], i32* [[DST:%.*]], align 4
272; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
273; CHECK-NEXT:    [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4
274; CHECK-NEXT:    [[R_1:%.*]] = ashr i32 [[SRC_1]], 16
275; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
276; CHECK-NEXT:    store i32 [[R_1]], i32* [[DST_GEP_1]], align 4
277; CHECK-NEXT:    [[SRC_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
278; CHECK-NEXT:    [[SRC_2:%.*]] = load i32, i32* [[SRC_GEP_2]], align 4
279; CHECK-NEXT:    [[SRC_GEP_5:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 5
280; CHECK-NEXT:    [[L:%.*]] = load i32, i32* [[SRC_GEP_5]], align 4
281; CHECK-NEXT:    [[R_2:%.*]] = ashr i32 [[SRC_2]], 16
282; CHECK-NEXT:    [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2
283; CHECK-NEXT:    store i32 [[R_2]], i32* [[DST_GEP_2]], align 4
284; CHECK-NEXT:    [[SRC_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
285; CHECK-NEXT:    [[SRC_3:%.*]] = load i32, i32* [[SRC_GEP_3]], align 4
286; CHECK-NEXT:    [[R_3:%.*]] = ashr i32 [[SRC_3]], 16
287; CHECK-NEXT:    [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3
288; CHECK-NEXT:    store i32 [[R_3]], i32* [[DST_GEP_3]], align 4
289; CHECK-NEXT:    call void @use(i32 [[L]])
290; CHECK-NEXT:    br label [[EXIT]]
291; CHECK:       exit:
292; CHECK-NEXT:    ret void
293;
294entry:
295  br i1 %c, label %then, label %exit
296
297then:
298  %src.0 = load i32, i32* %src, align 4
299  %r.0 = ashr i32 %src.0, 16
300  store i32 %r.0, i32* %dst, align 4
301  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
302  %src.1 = load i32, i32* %src.gep.1, align 4
303  %r.1 = ashr i32 %src.1, 16
304  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
305  store i32 %r.1, i32* %dst.gep.1, align 4
306  %src.gep.2 = getelementptr inbounds i32, i32* %src, i64 2
307  %src.2 = load i32, i32* %src.gep.2, align 4
308  %src.gep.5 = getelementptr inbounds i32, i32* %src, i64 5
309  %l = load i32, i32* %src.gep.5
310  %r.2 = ashr i32 %src.2, 16
311  %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2
312  store i32 %r.2, i32* %dst.gep.2, align 4
313  %src.gep.3 = getelementptr inbounds i32, i32* %src, i64 3
314  %src.3 = load i32, i32* %src.gep.3, align 4
315  %r.3 = ashr i32 %src.3, 16
316  %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3
317  store i32 %r.3, i32* %dst.gep.3, align 4
318  call void @use(i32 %l)
319  br label %exit
320
321exit:
322  ret void
323}
324
325define void @no_version(i32* nocapture %dst, i32* nocapture readonly %src) {
326; CHECK-LABEL: @no_version(
327; CHECK-NEXT:  entry:
328; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC:%.*]], i64 1
329; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[SRC]] to <2 x i32>*
330; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i32>, <2 x i32>* [[TMP0]], align 4
331; CHECK-NEXT:    [[TMP2:%.*]] = ashr <2 x i32> [[TMP1]], <i32 16, i32 16>
332; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST:%.*]], i64 1
333; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32* [[DST]] to <2 x i32>*
334; CHECK-NEXT:    store <2 x i32> [[TMP2]], <2 x i32>* [[TMP3]], align 4
335; CHECK-NEXT:    ret void
336;
337entry:
338  %src.0 = load i32, i32* %src, align 4
339  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
340  %src.1 = load i32, i32* %src.gep.1, align 4
341  %r.0 = ashr i32 %src.0, 16
342  %r.1 = ashr i32 %src.1, 16
343  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
344  store i32 %r.0, i32* %dst, align 4
345  store i32 %r.1, i32* %dst.gep.1, align 4
346  ret void
347}
348
349define void @version_multiple(i32* nocapture %out_block, i32* nocapture readonly %counter) {
350; CHECK-LABEL: @version_multiple(
351; CHECK-NEXT:  entry:
352; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[COUNTER:%.*]], align 4
353; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[OUT_BLOCK:%.*]], align 4
354; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], [[TMP0]]
355; CHECK-NEXT:    store i32 [[XOR]], i32* [[OUT_BLOCK]], align 4
356; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[COUNTER]], i64 1
357; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4
358; CHECK-NEXT:    [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, i32* [[OUT_BLOCK]], i64 1
359; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX2_1]], align 4
360; CHECK-NEXT:    [[XOR_1:%.*]] = xor i32 [[TMP3]], [[TMP2]]
361; CHECK-NEXT:    store i32 [[XOR_1]], i32* [[ARRAYIDX2_1]], align 4
362; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[COUNTER]], i64 2
363; CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4
364; CHECK-NEXT:    [[ARRAYIDX2_2:%.*]] = getelementptr inbounds i32, i32* [[OUT_BLOCK]], i64 2
365; CHECK-NEXT:    [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX2_2]], align 4
366; CHECK-NEXT:    [[XOR_2:%.*]] = xor i32 [[TMP5]], [[TMP4]]
367; CHECK-NEXT:    store i32 [[XOR_2]], i32* [[ARRAYIDX2_2]], align 4
368; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[COUNTER]], i64 3
369; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4
370; CHECK-NEXT:    [[ARRAYIDX2_3:%.*]] = getelementptr inbounds i32, i32* [[OUT_BLOCK]], i64 3
371; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX2_3]], align 4
372; CHECK-NEXT:    [[XOR_3:%.*]] = xor i32 [[TMP7]], [[TMP6]]
373; CHECK-NEXT:    store i32 [[XOR_3]], i32* [[ARRAYIDX2_3]], align 4
374; CHECK-NEXT:    ret void
375;
376entry:
377  %0 = load i32, i32* %counter, align 4
378  %1 = load i32, i32* %out_block, align 4
379  %xor = xor i32 %1, %0
380  store i32 %xor, i32* %out_block, align 4
381  %arrayidx.1 = getelementptr inbounds i32, i32* %counter, i64 1
382  %2 = load i32, i32* %arrayidx.1, align 4
383  %arrayidx2.1 = getelementptr inbounds i32, i32* %out_block, i64 1
384  %3 = load i32, i32* %arrayidx2.1, align 4
385  %xor.1 = xor i32 %3, %2
386  store i32 %xor.1, i32* %arrayidx2.1, align 4
387  %arrayidx.2 = getelementptr inbounds i32, i32* %counter, i64 2
388  %4 = load i32, i32* %arrayidx.2, align 4
389  %arrayidx2.2 = getelementptr inbounds i32, i32* %out_block, i64 2
390  %5 = load i32, i32* %arrayidx2.2, align 4
391  %xor.2 = xor i32 %5, %4
392  store i32 %xor.2, i32* %arrayidx2.2, align 4
393  %arrayidx.3 = getelementptr inbounds i32, i32* %counter, i64 3
394  %6 = load i32, i32* %arrayidx.3, align 4
395  %arrayidx2.3 = getelementptr inbounds i32, i32* %out_block, i64 3
396  %7 = load i32, i32* %arrayidx2.3, align 4
397  %xor.3 = xor i32 %7, %6
398  store i32 %xor.3, i32* %arrayidx2.3, align 4
399  ret void
400}
401
402define i32 @use_outside_version_bb(i32* %dst, i32* %src, i1 %c.1) {
403; CHECK-LABEL: @use_outside_version_bb(
404; CHECK-NEXT:  entry:
405; CHECK-NEXT:    [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4
406; CHECK-NEXT:    [[R_0:%.*]] = ashr i32 [[SRC_0]], 16
407; CHECK-NEXT:    store i32 [[R_0]], i32* [[DST:%.*]], align 4
408; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
409; CHECK-NEXT:    [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4
410; CHECK-NEXT:    [[R_1:%.*]] = ashr i32 [[SRC_1]], 16
411; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
412; CHECK-NEXT:    store i32 [[R_1]], i32* [[DST_GEP_1]], align 4
413; CHECK-NEXT:    br label [[EXIT:%.*]]
414; CHECK:       exit:
415; CHECK-NEXT:    ret i32 [[R_0]]
416;
417entry:
418  %src.0 = load i32, i32* %src, align 4
419  %r.0 = ashr i32 %src.0, 16
420  store i32 %r.0, i32* %dst, align 4
421  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
422  %src.1 = load i32, i32* %src.gep.1, align 4
423  %r.1 = ashr i32 %src.1, 16
424  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
425  store i32 %r.1, i32* %dst.gep.1, align 4
426  br label %exit
427
428exit:
429  ret i32 %r.0
430}
431
432define i32 @value_used_in_return(i32* %dst, i32* %src, i32 %x) {
433; CHECK-LABEL: @value_used_in_return(
434; CHECK-NEXT:  entry:
435; CHECK-NEXT:    [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4
436; CHECK-NEXT:    [[R_0:%.*]] = ashr i32 [[SRC_0]], 16
437; CHECK-NEXT:    store i32 [[R_0]], i32* [[DST:%.*]], align 4
438; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
439; CHECK-NEXT:    [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4
440; CHECK-NEXT:    [[R_1:%.*]] = ashr i32 [[SRC_1]], 16
441; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
442; CHECK-NEXT:    store i32 [[R_1]], i32* [[DST_GEP_1]], align 4
443; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], 20
444; CHECK-NEXT:    ret i32 [[ADD]]
445;
446entry:
447  %src.0 = load i32, i32* %src, align 4
448  %r.0 = ashr i32 %src.0, 16
449  store i32 %r.0, i32* %dst, align 4
450  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
451  %src.1 = load i32, i32* %src.gep.1, align 4
452  %r.1 = ashr i32 %src.1, 16
453  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
454  store i32 %r.1, i32* %dst.gep.1, align 4
455  %add = add i32 %x, 20
456  ret i32 %add
457}
458define i32 @needs_versioning2_cond_br(i32* %dst, i32* %src, i1 %c.1) {
459; CHECK-LABEL: @needs_versioning2_cond_br(
460; CHECK-NEXT:  entry:
461; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
462; CHECK:       then:
463; CHECK-NEXT:    [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4
464; CHECK-NEXT:    [[R_0:%.*]] = ashr i32 [[SRC_0]], 16
465; CHECK-NEXT:    store i32 [[R_0]], i32* [[DST:%.*]], align 4
466; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
467; CHECK-NEXT:    [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4
468; CHECK-NEXT:    [[R_1:%.*]] = ashr i32 [[SRC_1]], 16
469; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
470; CHECK-NEXT:    store i32 [[R_1]], i32* [[DST_GEP_1]], align 4
471; CHECK-NEXT:    ret i32 10
472; CHECK:       else:
473; CHECK-NEXT:    ret i32 0
474;
475entry:
476  br i1 %c.1, label %then, label %else
477
478then:
479  %src.0 = load i32, i32* %src, align 4
480  %r.0 = ashr i32 %src.0, 16
481  store i32 %r.0, i32* %dst, align 4
482  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
483  %src.1 = load i32, i32* %src.gep.1, align 4
484  %r.1 = ashr i32 %src.1, 16
485  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
486  store i32 %r.1, i32* %dst.gep.1, align 4
487  ret i32 10
488
489
490else:
491  ret i32 0
492}
493
494define void @pointer_defined_in_bb(i32* %dst, i32** %src.p) {
495; CHECK-LABEL: @pointer_defined_in_bb(
496; CHECK-NEXT:  entry:
497; CHECK-NEXT:    [[SRC:%.*]] = load i32*, i32** [[SRC_P:%.*]], align 8
498; CHECK-NEXT:    [[SRC_0:%.*]] = load i32, i32* [[SRC]], align 4
499; CHECK-NEXT:    [[R_0:%.*]] = ashr i32 [[SRC_0]], 16
500; CHECK-NEXT:    store i32 [[R_0]], i32* [[DST:%.*]], align 4
501; CHECK-NEXT:    [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
502; CHECK-NEXT:    [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4
503; CHECK-NEXT:    [[R_1:%.*]] = ashr i32 [[SRC_1]], 16
504; CHECK-NEXT:    [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1
505; CHECK-NEXT:    store i32 [[R_1]], i32* [[DST_GEP_1]], align 4
506; CHECK-NEXT:    ret void
507;
508entry:
509  %src = load i32*, i32** %src.p
510  %src.0 = load i32, i32* %src, align 4
511  %r.0 = ashr i32 %src.0, 16
512  store i32 %r.0, i32* %dst, align 4
513  %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1
514  %src.1 = load i32, i32* %src.gep.1, align 4
515  %r.1 = ashr i32 %src.1, 16
516  %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1
517  store i32 %r.1, i32* %dst.gep.1, align 4
518  ret void
519}
520
521define void @clobber_same_underlying_object(i32* %this) {
522; CHECK-LABEL: @clobber_same_underlying_object(
523; CHECK-NEXT:  entry:
524; CHECK-NEXT:    [[P_3:%.*]] = getelementptr inbounds i32, i32* [[THIS:%.*]], i32 3
525; CHECK-NEXT:    store i32 10, i32* [[P_3]], align 8
526; CHECK-NEXT:    tail call void @clobber()
527; CHECK-NEXT:    [[P_4:%.*]] = getelementptr inbounds i32, i32* [[THIS]], i32 4
528; CHECK-NEXT:    [[L2:%.*]] = load i32, i32* [[P_4]], align 8
529; CHECK-NEXT:    store i32 20, i32* [[P_4]], align 8
530; CHECK-NEXT:    ret void
531;
532entry:
533  %p.3 = getelementptr inbounds i32, i32* %this, i32 3
534  store i32 10, i32* %p.3, align 8
535  tail call void @clobber()
536  %p.4 = getelementptr inbounds i32, i32* %this, i32 4
537  %l2 = load i32, i32* %p.4, align 8
538  store i32 20, i32* %p.4, align 8
539  ret void
540}
541
542declare void @clobber()
543
544define void @slp_not_beneficial(i32* %A, i32* %B) {
545; CHECK-LABEL: @slp_not_beneficial(
546; CHECK-NEXT:  bb:
547; CHECK-NEXT:    [[TMP:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 4
548; CHECK-NEXT:    store i32 0, i32* [[TMP]], align 8
549; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 5
550; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i32 4
551; CHECK-NEXT:    [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 8
552; CHECK-NEXT:    store i32 [[TMP5]], i32* [[TMP3]], align 8
553; CHECK-NEXT:    ret void
554;
555bb:
556  %tmp = getelementptr inbounds i32, i32* %A, i32 4
557  store i32 0, i32* %tmp, align 8
558  %tmp3 = getelementptr inbounds i32, i32* %A, i32 5
559  %tmp4 = getelementptr inbounds i32, i32* %B, i32 4
560  %tmp5 = load i32, i32* %tmp4, align 8
561  store i32 %tmp5, i32* %tmp3, align 8
562  ret void
563}
564
565define void @widget(double* %ptr, double* %ptr.2) {
566; CHECK-LABEL: @widget(
567; CHECK-NEXT:  bb1:
568; CHECK-NEXT:    [[TMP3:%.*]] = load double, double* null, align 8
569; CHECK-NEXT:    [[TMP4:%.*]] = fmul double undef, [[TMP3]]
570; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds double, double* [[PTR:%.*]], i32 0
571; CHECK-NEXT:    [[TMP6:%.*]] = load double, double* [[TMP5]], align 8
572; CHECK-NEXT:    [[TMP7:%.*]] = fadd double [[TMP6]], [[TMP4]]
573; CHECK-NEXT:    store double [[TMP7]], double* [[TMP5]], align 8
574; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds double, double* [[PTR_2:%.*]], i64 0
575; CHECK-NEXT:    [[TMP9:%.*]] = load double, double* [[TMP8]], align 8
576; CHECK-NEXT:    [[TMP10:%.*]] = fmul double undef, [[TMP9]]
577; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds double, double* [[PTR]], i32 1
578; CHECK-NEXT:    [[TMP12:%.*]] = load double, double* [[TMP11]], align 8
579; CHECK-NEXT:    [[TMP13:%.*]] = fadd double [[TMP12]], [[TMP10]]
580; CHECK-NEXT:    store double [[TMP13]], double* [[TMP11]], align 8
581; CHECK-NEXT:    br label [[BB15:%.*]]
582; CHECK:       bb15:
583; CHECK-NEXT:    br label [[BB15]]
584;
585bb1:                                              ; preds = %bb
586  %tmp3 = load double, double* null, align 8
587  %tmp4 = fmul double undef, %tmp3
588  %tmp5 = getelementptr inbounds double, double* %ptr, i32 0
589  %tmp6 = load double, double* %tmp5, align 8
590  %tmp7 = fadd double %tmp6, %tmp4
591  store double %tmp7, double* %tmp5, align 8
592  %tmp8 = getelementptr inbounds double, double* %ptr.2, i64 0
593  %tmp9 = load double, double* %tmp8, align 8
594  %tmp10 = fmul double undef, %tmp9
595  %tmp11 = getelementptr inbounds double, double* %ptr, i32 1
596  %tmp12 = load double, double* %tmp11, align 8
597  %tmp13 = fadd double %tmp12, %tmp10
598  store double %tmp13, double* %tmp11, align 8
599  br label %bb15
600
601bb15:                                             ; preds = %bb15, %bb14
602  br label %bb15
603}
604
605%struct = type { i32, i32, float, float }
606
607; Some points we collected as candidates for runtime checks have been removed
608; before generating runtime checks. Make sure versioning is skipped.
609define void @test_bounds_removed_before_runtime_checks(%struct * %A, i32** %B, i1 %c) {
610; CHECK-LABEL: @test_bounds_removed_before_runtime_checks(
611; CHECK-NEXT:  entry:
612; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds [[STRUCT:%.*]], %struct* [[A:%.*]], i64 0, i32 0
613; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds [[STRUCT]], %struct* [[A]], i64 0, i32 1
614; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[TMP11]] to <2 x i32>*
615; CHECK-NEXT:    store <2 x i32> <i32 10, i32 300>, <2 x i32>* [[TMP0]], align 8
616; CHECK-NEXT:    [[TMP13:%.*]] = load i32*, i32** [[B:%.*]], align 8
617; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB23:%.*]], label [[BB14:%.*]]
618; CHECK:       bb14:
619; CHECK-NEXT:    [[TMP15:%.*]] = sext i32 10 to i64
620; CHECK-NEXT:    [[TMP16:%.*]] = add nsw i64 2, [[TMP15]]
621; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr inbounds i32, i32* [[TMP13]], i64 [[TMP16]]
622; CHECK-NEXT:    [[TMP18:%.*]] = bitcast i32* [[TMP17]] to i8*
623; CHECK-NEXT:    [[TMP19:%.*]] = getelementptr inbounds i8, i8* [[TMP18]], i64 3
624; CHECK-NEXT:    [[TMP20:%.*]] = getelementptr inbounds [[STRUCT]], %struct* [[A]], i64 0, i32 2
625; CHECK-NEXT:    store float 0.000000e+00, float* [[TMP20]], align 8
626; CHECK-NEXT:    [[TMP21:%.*]] = load i8, i8* [[TMP19]], align 1
627; CHECK-NEXT:    [[TMP22:%.*]] = getelementptr inbounds [[STRUCT]], %struct* [[A]], i64 0, i32 3
628; CHECK-NEXT:    store float 0.000000e+00, float* [[TMP22]], align 4
629; CHECK-NEXT:    br label [[BB23]]
630; CHECK:       bb23:
631; CHECK-NEXT:    ret void
632;
633entry:
634  %tmp1 = fmul float 10.0, 20.0
635  %tmp2 = fptosi float %tmp1 to i32
636  %tmp3 = fmul float 30.0, 20.0
637  %tmp4 = fptosi float %tmp3 to i32
638  %tmp5 = icmp sgt i32 100, %tmp2
639  %tmp6 = select i1 %tmp5, i32 %tmp2, i32 10
640  %tmp7 = select i1 false, i32 0, i32 %tmp6
641  %tmp8 = icmp sgt i32 200, %tmp4
642  %tmp9 = select i1 %tmp8, i32 %tmp4, i32 300
643  %tmp10 = select i1 false, i32 0, i32 %tmp9
644  %tmp11 = getelementptr inbounds %struct, %struct* %A, i64 0, i32 0
645  store i32 %tmp7, i32* %tmp11, align 8
646  %tmp12 = getelementptr inbounds %struct, %struct* %A, i64 0, i32 1
647  store i32 %tmp10, i32* %tmp12, align 4
648  %tmp13 = load i32*, i32** %B, align 8
649  br i1 %c, label %bb23, label %bb14
650
651bb14:
652  %tmp15 = sext i32 %tmp7 to i64
653  %tmp16 = add nsw i64 2, %tmp15
654  %tmp17 = getelementptr inbounds i32, i32* %tmp13, i64 %tmp16
655  %tmp18 = bitcast i32* %tmp17 to i8*
656  %tmp19 = getelementptr inbounds i8, i8* %tmp18, i64 3
657  %tmp20 = getelementptr inbounds %struct, %struct* %A, i64 0, i32 2
658  store float 0.0, float* %tmp20, align 8
659  %tmp21 = load i8, i8* %tmp19, align 1
660  %tmp22 = getelementptr inbounds %struct, %struct* %A, i64 0, i32 3
661  store float 0.0, float* %tmp22, align 4
662  br label %bb23
663
664bb23:
665  ret void
666}
667
668; In this test there's a single bound, do not generate runtime checks.
669define void @single_membound(double* %arg, double* %arg1, double %x) {
670; CHECK-LABEL: @single_membound(
671; CHECK-NEXT:  entry:
672; CHECK-NEXT:    [[TMP:%.*]] = fsub double [[X:%.*]], 9.900000e+01
673; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds double, double* [[ARG:%.*]], i64 1
674; CHECK-NEXT:    store double [[TMP]], double* [[TMP9]], align 8
675; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds double, double* [[ARG1:%.*]], i64 0
676; CHECK-NEXT:    [[TMP12:%.*]] = load double, double* [[TMP10]], align 8
677; CHECK-NEXT:    [[TMP13:%.*]] = fsub double 1.000000e+00, [[TMP12]]
678; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds double, double* [[ARG]], i64 2
679; CHECK-NEXT:    br label [[BB15:%.*]]
680; CHECK:       bb15:
681; CHECK-NEXT:    [[TMP16:%.*]] = fmul double [[TMP]], 2.000000e+01
682; CHECK-NEXT:    store double [[TMP16]], double* [[TMP9]], align 8
683; CHECK-NEXT:    [[TMP17:%.*]] = fmul double [[TMP13]], 3.000000e+01
684; CHECK-NEXT:    store double [[TMP17]], double* [[TMP14]], align 8
685; CHECK-NEXT:    ret void
686;
687entry:
688  %tmp = fsub double %x, 99.0
689  %tmp9 = getelementptr inbounds double, double* %arg, i64 1
690  store double %tmp, double* %tmp9, align 8
691  %tmp10 = getelementptr inbounds double, double* %arg1, i64 0
692  %tmp12 = load double, double* %tmp10, align 8
693  %tmp13 = fsub double 1.0, %tmp12
694  %tmp14 = getelementptr inbounds double, double* %arg, i64 2
695  br label %bb15
696
697bb15:
698  %tmp16 = fmul double %tmp, 20.0
699  store double %tmp16, double* %tmp9, align 8
700  %tmp17 = fmul double %tmp13, 30.0
701  store double %tmp17, double* %tmp14, align 8
702  ret void
703}
704
705%struct.2 = type { [4 x float] }
706
707; Make sure we do not crash when we encounter a SCEVCouldNotCompute.
708define void @no_lcssa_phi(%struct.2* %A, float* %B, i1 %c) {
709; CHECK-LABEL: @no_lcssa_phi(
710; CHECK-NEXT:  bb:
711; CHECK-NEXT:    br label [[LOOP:%.*]]
712; CHECK:       loop:
713; CHECK-NEXT:    [[PTR_PHI:%.*]] = phi %struct.2* [ [[A:%.*]], [[BB:%.*]] ], [ null, [[LOOP]] ]
714; CHECK-NEXT:    br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP]]
715; CHECK:       exit:
716; CHECK-NEXT:    [[B_GEP_0:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 0
717; CHECK-NEXT:    [[L_0:%.*]] = load float, float* [[B_GEP_0]], align 8
718; CHECK-NEXT:    [[ADD_0:%.*]] = fadd float [[L_0]], 1.000000e+01
719; CHECK-NEXT:    [[MUL_0:%.*]] = fmul float [[ADD_0]], 3.000000e+01
720; CHECK-NEXT:    [[A_GEP_0:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], %struct.2* [[PTR_PHI]], i64 0, i32 0, i32 0
721; CHECK-NEXT:    store float [[MUL_0]], float* [[A_GEP_0]], align 8
722; CHECK-NEXT:    [[B_GEP_1:%.*]] = getelementptr inbounds float, float* [[B]], i64 1
723; CHECK-NEXT:    [[L_1:%.*]] = load float, float* [[B_GEP_1]], align 8
724; CHECK-NEXT:    [[ADD_1:%.*]] = fadd float [[L_1]], 1.000000e+01
725; CHECK-NEXT:    [[MUL_1:%.*]] = fmul float [[ADD_1]], 3.000000e+01
726; CHECK-NEXT:    [[A_GEP_1:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI]], i64 0, i32 0, i32 1
727; CHECK-NEXT:    store float [[MUL_1]], float* [[A_GEP_1]], align 8
728; CHECK-NEXT:    [[B_GEP_2:%.*]] = getelementptr inbounds float, float* [[B]], i64 2
729; CHECK-NEXT:    [[L_2:%.*]] = load float, float* [[B_GEP_2]], align 8
730; CHECK-NEXT:    [[ADD_2:%.*]] = fadd float [[L_2]], 1.000000e+01
731; CHECK-NEXT:    [[MUL_2:%.*]] = fmul float [[ADD_2]], 3.000000e+01
732; CHECK-NEXT:    [[A_GEP_2:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI]], i64 0, i32 0, i32 2
733; CHECK-NEXT:    store float [[MUL_2]], float* [[A_GEP_2]], align 8
734; CHECK-NEXT:    [[B_GEP_3:%.*]] = getelementptr inbounds float, float* [[B]], i64 3
735; CHECK-NEXT:    [[L_3:%.*]] = load float, float* [[B_GEP_3]], align 8
736; CHECK-NEXT:    [[ADD_3:%.*]] = fadd float [[L_3]], 1.000000e+01
737; CHECK-NEXT:    [[MUL_3:%.*]] = fmul float [[ADD_3]], 3.000000e+01
738; CHECK-NEXT:    [[A_GEP_3:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI]], i64 0, i32 0, i32 3
739; CHECK-NEXT:    store float [[MUL_3]], float* [[A_GEP_3]], align 8
740; CHECK-NEXT:    ret void
741;
742bb:
743  br label %loop
744
745loop:
746  %ptr.phi = phi %struct.2* [ %A, %bb ], [ null, %loop ]
747  br i1 %c, label %exit, label %loop
748
749exit:
750  %B.gep.0 = getelementptr inbounds float, float* %B, i64 0
751  %l.0 = load float, float* %B.gep.0, align 8
752  %add.0 = fadd float %l.0, 10.0
753  %mul.0 = fmul float %add.0, 30.0
754  %A.gep.0 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi, i64 0, i32 0, i32 0
755  store float %mul.0, float* %A.gep.0, align 8
756  %B.gep.1 = getelementptr inbounds float, float* %B, i64 1
757  %l.1 = load float, float* %B.gep.1, align 8
758  %add.1 = fadd float %l.1, 10.0
759  %mul.1 = fmul float %add.1, 30.0
760  %A.gep.1 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi, i64 0, i32 0, i32 1
761  store float %mul.1, float* %A.gep.1, align 8
762  %B.gep.2 = getelementptr inbounds float, float* %B, i64 2
763  %l.2 = load float, float* %B.gep.2, align 8
764  %add.2 = fadd float %l.2, 10.0
765  %mul.2 = fmul float %add.2, 30.0
766  %A.gep.2 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi, i64 0, i32 0, i32 2
767  store float %mul.2, float* %A.gep.2, align 8
768  %B.gep.3 = getelementptr inbounds float, float* %B, i64 3
769  %l.3 = load float, float* %B.gep.3, align 8
770  %add.3 = fadd float %l.3, 10.0
771  %mul.3 = fmul float %add.3, 30.0
772  %A.gep.3 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi, i64 0, i32 0, i32 3
773  store float %mul.3, float* %A.gep.3, align 8
774  ret void
775}
776
777; Make sure lcssa phis as pointer bases are handled properly.
778define void @lcssa_phi(%struct.2* %A, float* %B, i1 %c) {
779; CHECK-LABEL: @lcssa_phi(
780; CHECK-NEXT:  bb:
781; CHECK-NEXT:    br label [[LOOP:%.*]]
782; CHECK:       loop:
783; CHECK-NEXT:    [[PTR_PHI:%.*]] = phi %struct.2* [ [[A:%.*]], [[BB:%.*]] ], [ null, [[LOOP]] ]
784; CHECK-NEXT:    br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP]]
785; CHECK:       exit:
786; CHECK-NEXT:    [[PTR_PHI_LCSSA:%.*]] = phi %struct.2* [ [[PTR_PHI]], [[LOOP]] ]
787; CHECK-NEXT:    [[B_GEP_0:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 0
788; CHECK-NEXT:    [[L_0:%.*]] = load float, float* [[B_GEP_0]], align 8
789; CHECK-NEXT:    [[ADD_0:%.*]] = fadd float [[L_0]], 1.000000e+01
790; CHECK-NEXT:    [[MUL_0:%.*]] = fmul float [[ADD_0]], 3.000000e+01
791; CHECK-NEXT:    [[A_GEP_0:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], %struct.2* [[PTR_PHI_LCSSA]], i64 0, i32 0, i32 0
792; CHECK-NEXT:    store float [[MUL_0]], float* [[A_GEP_0]], align 8
793; CHECK-NEXT:    [[B_GEP_1:%.*]] = getelementptr inbounds float, float* [[B]], i64 1
794; CHECK-NEXT:    [[L_1:%.*]] = load float, float* [[B_GEP_1]], align 8
795; CHECK-NEXT:    [[ADD_1:%.*]] = fadd float [[L_1]], 1.000000e+01
796; CHECK-NEXT:    [[MUL_1:%.*]] = fmul float [[ADD_1]], 3.000000e+01
797; CHECK-NEXT:    [[A_GEP_1:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI_LCSSA]], i64 0, i32 0, i32 1
798; CHECK-NEXT:    store float [[MUL_1]], float* [[A_GEP_1]], align 8
799; CHECK-NEXT:    [[B_GEP_2:%.*]] = getelementptr inbounds float, float* [[B]], i64 2
800; CHECK-NEXT:    [[L_2:%.*]] = load float, float* [[B_GEP_2]], align 8
801; CHECK-NEXT:    [[ADD_2:%.*]] = fadd float [[L_2]], 1.000000e+01
802; CHECK-NEXT:    [[MUL_2:%.*]] = fmul float [[ADD_2]], 3.000000e+01
803; CHECK-NEXT:    [[A_GEP_2:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI_LCSSA]], i64 0, i32 0, i32 2
804; CHECK-NEXT:    store float [[MUL_2]], float* [[A_GEP_2]], align 8
805; CHECK-NEXT:    [[B_GEP_3:%.*]] = getelementptr inbounds float, float* [[B]], i64 3
806; CHECK-NEXT:    [[L_3:%.*]] = load float, float* [[B_GEP_3]], align 8
807; CHECK-NEXT:    [[ADD_3:%.*]] = fadd float [[L_3]], 1.000000e+01
808; CHECK-NEXT:    [[MUL_3:%.*]] = fmul float [[ADD_3]], 3.000000e+01
809; CHECK-NEXT:    [[A_GEP_3:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI_LCSSA]], i64 0, i32 0, i32 3
810; CHECK-NEXT:    store float [[MUL_3]], float* [[A_GEP_3]], align 8
811; CHECK-NEXT:    ret void
812;
813bb:
814  br label %loop
815
816loop:
817  %ptr.phi = phi %struct.2* [ %A, %bb ], [ null, %loop ]
818  br i1 %c, label %exit, label %loop
819
820exit:
821  %ptr.phi.lcssa = phi %struct.2* [ %ptr.phi, %loop ]
822  %B.gep.0 = getelementptr inbounds float, float* %B, i64 0
823  %l.0 = load float, float* %B.gep.0, align 8
824  %add.0 = fadd float %l.0, 10.0
825  %mul.0 = fmul float %add.0, 30.0
826  %A.gep.0 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi.lcssa, i64 0, i32 0, i32 0
827  store float %mul.0, float* %A.gep.0, align 8
828  %B.gep.1 = getelementptr inbounds float, float* %B, i64 1
829  %l.1 = load float, float* %B.gep.1, align 8
830  %add.1 = fadd float %l.1, 10.0
831  %mul.1 = fmul float %add.1, 30.0
832  %A.gep.1 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi.lcssa, i64 0, i32 0, i32 1
833  store float %mul.1, float* %A.gep.1, align 8
834  %B.gep.2 = getelementptr inbounds float, float* %B, i64 2
835  %l.2 = load float, float* %B.gep.2, align 8
836  %add.2 = fadd float %l.2, 10.0
837  %mul.2 = fmul float %add.2, 30.0
838  %A.gep.2 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi.lcssa, i64 0, i32 0, i32 2
839  store float %mul.2, float* %A.gep.2, align 8
840  %B.gep.3 = getelementptr inbounds float, float* %B, i64 3
841  %l.3 = load float, float* %B.gep.3, align 8
842  %add.3 = fadd float %l.3, 10.0
843  %mul.3 = fmul float %add.3, 30.0
844  %A.gep.3 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi.lcssa, i64 0, i32 0, i32 3
845  store float %mul.3, float* %A.gep.3, align 8
846  ret void
847}
848
849%struct.spam = type { [60 x i32], i32, [12 x i8] }
850
851declare void @foo(i8*)
852
853; Test case with a basic block where parts can be vectorized without versioning.
854define i32 @block_partly_vectorized_without_versioning(%struct.spam* readonly %arg, i8* nocapture readonly %arg1, i8* nocapture %arg2, i8* nocapture readonly %arg3, i8* %A, i8* %B) {
855; CHECK-LABEL: @block_partly_vectorized_without_versioning(
856; CHECK-NEXT:  bb:
857; CHECK-NEXT:    [[T:%.*]] = alloca <16 x i8>, align 16
858; CHECK-NEXT:    [[T4:%.*]] = getelementptr inbounds <16 x i8>, <16 x i8>* [[T]], i64 0, i64 0
859; CHECK-NEXT:    [[T5:%.*]] = getelementptr inbounds i8, i8* [[ARG3:%.*]], i64 1
860; CHECK-NEXT:    [[T6:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 2
861; CHECK-NEXT:    [[T7:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 3
862; CHECK-NEXT:    [[T8:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 4
863; CHECK-NEXT:    [[T9:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 5
864; CHECK-NEXT:    [[T10:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 6
865; CHECK-NEXT:    [[T11:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 7
866; CHECK-NEXT:    [[T12:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 8
867; CHECK-NEXT:    [[T13:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 9
868; CHECK-NEXT:    [[T14:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 10
869; CHECK-NEXT:    [[T15:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 11
870; CHECK-NEXT:    [[T16:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 12
871; CHECK-NEXT:    [[T17:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 13
872; CHECK-NEXT:    [[T18:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 14
873; CHECK-NEXT:    [[T19:%.*]] = bitcast i8* [[ARG1:%.*]] to <16 x i8>*
874; CHECK-NEXT:    [[A_GEP_0:%.*]] = getelementptr i8, i8* [[A:%.*]], i64 0
875; CHECK-NEXT:    [[B_GEP_0:%.*]] = getelementptr i8, i8* [[B:%.*]], i64 0
876; CHECK-NEXT:    [[A_GEP_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
877; CHECK-NEXT:    [[B_GEP_1:%.*]] = getelementptr i8, i8* [[B]], i64 1
878; CHECK-NEXT:    [[A_GEP_2:%.*]] = getelementptr i8, i8* [[A]], i64 2
879; CHECK-NEXT:    [[B_GEP_2:%.*]] = getelementptr i8, i8* [[B]], i64 2
880; CHECK-NEXT:    [[A_GEP_3:%.*]] = getelementptr i8, i8* [[A]], i64 3
881; CHECK-NEXT:    [[B_GEP_3:%.*]] = getelementptr i8, i8* [[B]], i64 3
882; CHECK-NEXT:    [[A_GEP_4:%.*]] = getelementptr i8, i8* [[A]], i64 4
883; CHECK-NEXT:    [[B_GEP_4:%.*]] = getelementptr i8, i8* [[B]], i64 4
884; CHECK-NEXT:    [[A_GEP_5:%.*]] = getelementptr i8, i8* [[A]], i64 5
885; CHECK-NEXT:    [[B_GEP_5:%.*]] = getelementptr i8, i8* [[B]], i64 5
886; CHECK-NEXT:    [[A_GEP_6:%.*]] = getelementptr i8, i8* [[A]], i64 6
887; CHECK-NEXT:    [[B_GEP_6:%.*]] = getelementptr i8, i8* [[B]], i64 6
888; CHECK-NEXT:    [[A_GEP_7:%.*]] = getelementptr i8, i8* [[A]], i64 7
889; CHECK-NEXT:    [[B_GEP_7:%.*]] = getelementptr i8, i8* [[B]], i64 7
890; CHECK-NEXT:    [[A_GEP_8:%.*]] = getelementptr i8, i8* [[A]], i64 8
891; CHECK-NEXT:    [[B_GEP_8:%.*]] = getelementptr i8, i8* [[B]], i64 8
892; CHECK-NEXT:    [[A_GEP_9:%.*]] = getelementptr i8, i8* [[A]], i64 9
893; CHECK-NEXT:    [[B_GEP_9:%.*]] = getelementptr i8, i8* [[B]], i64 9
894; CHECK-NEXT:    [[A_GEP_10:%.*]] = getelementptr i8, i8* [[A]], i64 10
895; CHECK-NEXT:    [[B_GEP_10:%.*]] = getelementptr i8, i8* [[B]], i64 10
896; CHECK-NEXT:    [[A_GEP_11:%.*]] = getelementptr i8, i8* [[A]], i64 11
897; CHECK-NEXT:    [[B_GEP_11:%.*]] = getelementptr i8, i8* [[B]], i64 11
898; CHECK-NEXT:    [[A_GEP_12:%.*]] = getelementptr i8, i8* [[A]], i64 12
899; CHECK-NEXT:    [[B_GEP_12:%.*]] = getelementptr i8, i8* [[B]], i64 12
900; CHECK-NEXT:    [[A_GEP_13:%.*]] = getelementptr i8, i8* [[A]], i64 13
901; CHECK-NEXT:    [[B_GEP_13:%.*]] = getelementptr i8, i8* [[B]], i64 13
902; CHECK-NEXT:    [[A_GEP_14:%.*]] = getelementptr i8, i8* [[A]], i64 14
903; CHECK-NEXT:    [[B_GEP_14:%.*]] = getelementptr i8, i8* [[B]], i64 14
904; CHECK-NEXT:    [[A_GEP_15:%.*]] = getelementptr i8, i8* [[A]], i64 15
905; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[A_GEP_0]] to <16 x i8>*
906; CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i8>, <16 x i8>* [[TMP0]], align 1
907; CHECK-NEXT:    [[B_GEP_15:%.*]] = getelementptr i8, i8* [[B]], i64 15
908; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[B_GEP_0]] to <16 x i8>*
909; CHECK-NEXT:    [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[TMP2]], align 1
910; CHECK-NEXT:    [[TMP4:%.*]] = xor <16 x i8> [[TMP1]], [[TMP3]]
911; CHECK-NEXT:    [[R_GEP_0:%.*]] = getelementptr i8, i8* [[ARG1]], i64 0
912; CHECK-NEXT:    [[R_GEP_1:%.*]] = getelementptr i8, i8* [[ARG1]], i64 1
913; CHECK-NEXT:    [[R_GEP_2:%.*]] = getelementptr i8, i8* [[ARG1]], i64 2
914; CHECK-NEXT:    [[R_GEP_3:%.*]] = getelementptr i8, i8* [[ARG1]], i64 3
915; CHECK-NEXT:    [[R_GEP_4:%.*]] = getelementptr i8, i8* [[ARG1]], i64 4
916; CHECK-NEXT:    [[R_GEP_5:%.*]] = getelementptr i8, i8* [[ARG1]], i64 5
917; CHECK-NEXT:    [[R_GEP_6:%.*]] = getelementptr i8, i8* [[ARG1]], i64 6
918; CHECK-NEXT:    [[R_GEP_7:%.*]] = getelementptr i8, i8* [[ARG1]], i64 7
919; CHECK-NEXT:    [[R_GEP_8:%.*]] = getelementptr i8, i8* [[ARG1]], i64 8
920; CHECK-NEXT:    [[R_GEP_9:%.*]] = getelementptr i8, i8* [[ARG1]], i64 9
921; CHECK-NEXT:    [[R_GEP_10:%.*]] = getelementptr i8, i8* [[ARG1]], i64 10
922; CHECK-NEXT:    [[R_GEP_11:%.*]] = getelementptr i8, i8* [[ARG1]], i64 11
923; CHECK-NEXT:    [[R_GEP_12:%.*]] = getelementptr i8, i8* [[ARG1]], i64 12
924; CHECK-NEXT:    [[R_GEP_13:%.*]] = getelementptr i8, i8* [[ARG1]], i64 13
925; CHECK-NEXT:    [[R_GEP_14:%.*]] = getelementptr i8, i8* [[ARG1]], i64 14
926; CHECK-NEXT:    [[R_GEP_15:%.*]] = getelementptr i8, i8* [[ARG1]], i64 15
927; CHECK-NEXT:    [[TMP5:%.*]] = bitcast i8* [[R_GEP_0]] to <16 x i8>*
928; CHECK-NEXT:    store <16 x i8> [[TMP4]], <16 x i8>* [[TMP5]], align 1
929; CHECK-NEXT:    [[T21:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 15
930; CHECK-NEXT:    [[T22:%.*]] = bitcast i8* [[ARG3]] to <16 x i8>*
931; CHECK-NEXT:    call void @foo(i8* nonnull [[T4]])
932; CHECK-NEXT:    [[T26:%.*]] = load i8, i8* [[ARG3]], align 1
933; CHECK-NEXT:    [[T27:%.*]] = load i8, i8* [[ARG2:%.*]], align 1
934; CHECK-NEXT:    [[T28:%.*]] = xor i8 [[T27]], [[T26]]
935; CHECK-NEXT:    store i8 [[T28]], i8* [[ARG2]], align 1
936; CHECK-NEXT:    [[T29:%.*]] = load i8, i8* [[T5]], align 1
937; CHECK-NEXT:    [[T30:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 1
938; CHECK-NEXT:    [[T31:%.*]] = load i8, i8* [[T30]], align 1
939; CHECK-NEXT:    [[T32:%.*]] = xor i8 [[T31]], [[T29]]
940; CHECK-NEXT:    store i8 [[T32]], i8* [[T30]], align 1
941; CHECK-NEXT:    [[T33:%.*]] = load i8, i8* [[T6]], align 1
942; CHECK-NEXT:    [[T34:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 2
943; CHECK-NEXT:    [[T35:%.*]] = load i8, i8* [[T34]], align 1
944; CHECK-NEXT:    [[T36:%.*]] = xor i8 [[T35]], [[T33]]
945; CHECK-NEXT:    store i8 [[T36]], i8* [[T34]], align 1
946; CHECK-NEXT:    [[T37:%.*]] = load i8, i8* [[T7]], align 1
947; CHECK-NEXT:    [[T38:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 3
948; CHECK-NEXT:    [[T39:%.*]] = load i8, i8* [[T38]], align 1
949; CHECK-NEXT:    [[T40:%.*]] = xor i8 [[T39]], [[T37]]
950; CHECK-NEXT:    store i8 [[T40]], i8* [[T38]], align 1
951; CHECK-NEXT:    [[T41:%.*]] = load i8, i8* [[T8]], align 1
952; CHECK-NEXT:    [[T42:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 4
953; CHECK-NEXT:    [[T43:%.*]] = load i8, i8* [[T42]], align 1
954; CHECK-NEXT:    [[T44:%.*]] = xor i8 [[T43]], [[T41]]
955; CHECK-NEXT:    store i8 [[T44]], i8* [[T42]], align 1
956; CHECK-NEXT:    [[T45:%.*]] = load i8, i8* [[T9]], align 1
957; CHECK-NEXT:    [[T46:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 5
958; CHECK-NEXT:    [[T47:%.*]] = load i8, i8* [[T46]], align 1
959; CHECK-NEXT:    [[T48:%.*]] = xor i8 [[T47]], [[T45]]
960; CHECK-NEXT:    store i8 [[T48]], i8* [[T46]], align 1
961; CHECK-NEXT:    [[T49:%.*]] = load i8, i8* [[T10]], align 1
962; CHECK-NEXT:    [[T50:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 6
963; CHECK-NEXT:    [[T51:%.*]] = load i8, i8* [[T50]], align 1
964; CHECK-NEXT:    [[T52:%.*]] = xor i8 [[T51]], [[T49]]
965; CHECK-NEXT:    store i8 [[T52]], i8* [[T50]], align 1
966; CHECK-NEXT:    [[T53:%.*]] = load i8, i8* [[T11]], align 1
967; CHECK-NEXT:    [[T54:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 7
968; CHECK-NEXT:    [[T55:%.*]] = load i8, i8* [[T54]], align 1
969; CHECK-NEXT:    [[T56:%.*]] = xor i8 [[T55]], [[T53]]
970; CHECK-NEXT:    store i8 [[T56]], i8* [[T54]], align 1
971; CHECK-NEXT:    [[T57:%.*]] = load i8, i8* [[T12]], align 1
972; CHECK-NEXT:    [[T58:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 8
973; CHECK-NEXT:    [[T59:%.*]] = load i8, i8* [[T58]], align 1
974; CHECK-NEXT:    [[T60:%.*]] = xor i8 [[T59]], [[T57]]
975; CHECK-NEXT:    store i8 [[T60]], i8* [[T58]], align 1
976; CHECK-NEXT:    [[T61:%.*]] = load i8, i8* [[T13]], align 1
977; CHECK-NEXT:    [[T62:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 9
978; CHECK-NEXT:    [[T63:%.*]] = load i8, i8* [[T62]], align 1
979; CHECK-NEXT:    [[T64:%.*]] = xor i8 [[T63]], [[T61]]
980; CHECK-NEXT:    store i8 [[T64]], i8* [[T62]], align 1
981; CHECK-NEXT:    [[T65:%.*]] = load i8, i8* [[T14]], align 1
982; CHECK-NEXT:    [[T66:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 10
983; CHECK-NEXT:    [[T67:%.*]] = load i8, i8* [[T66]], align 1
984; CHECK-NEXT:    [[T68:%.*]] = xor i8 [[T67]], [[T65]]
985; CHECK-NEXT:    store i8 [[T68]], i8* [[T66]], align 1
986; CHECK-NEXT:    [[T69:%.*]] = load i8, i8* [[T15]], align 1
987; CHECK-NEXT:    [[T70:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 11
988; CHECK-NEXT:    [[T71:%.*]] = load i8, i8* [[T70]], align 1
989; CHECK-NEXT:    [[T72:%.*]] = xor i8 [[T71]], [[T69]]
990; CHECK-NEXT:    store i8 [[T72]], i8* [[T70]], align 1
991; CHECK-NEXT:    [[T73:%.*]] = load i8, i8* [[T16]], align 1
992; CHECK-NEXT:    [[T74:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 12
993; CHECK-NEXT:    [[T75:%.*]] = load i8, i8* [[T74]], align 1
994; CHECK-NEXT:    [[T76:%.*]] = xor i8 [[T75]], [[T73]]
995; CHECK-NEXT:    store i8 [[T76]], i8* [[T74]], align 1
996; CHECK-NEXT:    [[T77:%.*]] = load i8, i8* [[T17]], align 1
997; CHECK-NEXT:    [[T78:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 13
998; CHECK-NEXT:    [[T79:%.*]] = load i8, i8* [[T78]], align 1
999; CHECK-NEXT:    [[T80:%.*]] = xor i8 [[T79]], [[T77]]
1000; CHECK-NEXT:    store i8 [[T80]], i8* [[T78]], align 1
1001; CHECK-NEXT:    [[T81:%.*]] = load i8, i8* [[T18]], align 1
1002; CHECK-NEXT:    [[T82:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 14
1003; CHECK-NEXT:    [[T83:%.*]] = load i8, i8* [[T82]], align 1
1004; CHECK-NEXT:    [[T84:%.*]] = xor i8 [[T83]], [[T81]]
1005; CHECK-NEXT:    store i8 [[T84]], i8* [[T82]], align 1
1006; CHECK-NEXT:    [[T85:%.*]] = load i8, i8* [[T21]], align 1
1007; CHECK-NEXT:    [[T86:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 15
1008; CHECK-NEXT:    [[T87:%.*]] = load i8, i8* [[T86]], align 1
1009; CHECK-NEXT:    [[T88:%.*]] = xor i8 [[T87]], [[T85]]
1010; CHECK-NEXT:    store i8 [[T88]], i8* [[T86]], align 1
1011; CHECK-NEXT:    ret i32 1
1012;
1013bb:
1014  %t = alloca <16 x i8>, align 16
1015  %t4 = getelementptr inbounds <16 x i8>, <16 x i8>* %t, i64 0, i64 0
1016  %t5 = getelementptr inbounds i8, i8* %arg3, i64 1
1017  %t6 = getelementptr inbounds i8, i8* %arg3, i64 2
1018  %t7 = getelementptr inbounds i8, i8* %arg3, i64 3
1019  %t8 = getelementptr inbounds i8, i8* %arg3, i64 4
1020  %t9 = getelementptr inbounds i8, i8* %arg3, i64 5
1021  %t10 = getelementptr inbounds i8, i8* %arg3, i64 6
1022  %t11 = getelementptr inbounds i8, i8* %arg3, i64 7
1023  %t12 = getelementptr inbounds i8, i8* %arg3, i64 8
1024  %t13 = getelementptr inbounds i8, i8* %arg3, i64 9
1025  %t14 = getelementptr inbounds i8, i8* %arg3, i64 10
1026  %t15 = getelementptr inbounds i8, i8* %arg3, i64 11
1027  %t16 = getelementptr inbounds i8, i8* %arg3, i64 12
1028  %t17 = getelementptr inbounds i8, i8* %arg3, i64 13
1029  %t18 = getelementptr inbounds i8, i8* %arg3, i64 14
1030  %t19 = bitcast i8* %arg1 to <16 x i8>*
1031  %A.gep.0 = getelementptr i8, i8* %A, i64 0
1032  %A.0 = load i8, i8* %A.gep.0
1033  %B.gep.0 = getelementptr i8, i8* %B, i64 0
1034  %B.0 = load i8, i8* %B.gep.0
1035  %xor.0 = xor i8 %A.0, %B.0
1036  %A.gep.1 = getelementptr i8, i8* %A, i64 1
1037  %A.1 = load i8, i8* %A.gep.1
1038  %B.gep.1 = getelementptr i8, i8* %B, i64 1
1039  %B.1 = load i8, i8* %B.gep.1
1040  %xor.1 = xor i8 %A.1, %B.1
1041  %A.gep.2 = getelementptr i8, i8* %A, i64 2
1042  %A.2 = load i8, i8* %A.gep.2
1043  %B.gep.2 = getelementptr i8, i8* %B, i64 2
1044  %B.2 = load i8, i8* %B.gep.2
1045  %xor.2 = xor i8 %A.2, %B.2
1046  %A.gep.3 = getelementptr i8, i8* %A, i64 3
1047  %A.3 = load i8, i8* %A.gep.3
1048  %B.gep.3 = getelementptr i8, i8* %B, i64 3
1049  %B.3 = load i8, i8* %B.gep.3
1050  %xor.3 = xor i8 %A.3, %B.3
1051  %A.gep.4 = getelementptr i8, i8* %A, i64 4
1052  %A.4 = load i8, i8* %A.gep.4
1053  %B.gep.4 = getelementptr i8, i8* %B, i64 4
1054  %B.4 = load i8, i8* %B.gep.4
1055  %xor.4 = xor i8 %A.4, %B.4
1056  %A.gep.5 = getelementptr i8, i8* %A, i64 5
1057  %A.5 = load i8, i8* %A.gep.5
1058  %B.gep.5 = getelementptr i8, i8* %B, i64 5
1059  %B.5 = load i8, i8* %B.gep.5
1060  %xor.5 = xor i8 %A.5, %B.5
1061  %A.gep.6 = getelementptr i8, i8* %A, i64 6
1062  %A.6 = load i8, i8* %A.gep.6
1063  %B.gep.6 = getelementptr i8, i8* %B, i64 6
1064  %B.6 = load i8, i8* %B.gep.6
1065  %xor.6 = xor i8 %A.6, %B.6
1066  %A.gep.7 = getelementptr i8, i8* %A, i64 7
1067  %A.7 = load i8, i8* %A.gep.7
1068  %B.gep.7 = getelementptr i8, i8* %B, i64 7
1069  %B.7 = load i8, i8* %B.gep.7
1070  %xor.7 = xor i8 %A.7, %B.7
1071  %A.gep.8 = getelementptr i8, i8* %A, i64 8
1072  %A.8 = load i8, i8* %A.gep.8
1073  %B.gep.8 = getelementptr i8, i8* %B, i64 8
1074  %B.8 = load i8, i8* %B.gep.8
1075  %xor.8 = xor i8 %A.8, %B.8
1076  %A.gep.9 = getelementptr i8, i8* %A, i64 9
1077  %A.9 = load i8, i8* %A.gep.9
1078  %B.gep.9 = getelementptr i8, i8* %B, i64 9
1079  %B.9 = load i8, i8* %B.gep.9
1080  %xor.9 = xor i8 %A.9, %B.9
1081  %A.gep.10 = getelementptr i8, i8* %A, i64 10
1082  %A.10 = load i8, i8* %A.gep.10
1083  %B.gep.10 = getelementptr i8, i8* %B, i64 10
1084  %B.10 = load i8, i8* %B.gep.10
1085  %xor.10 = xor i8 %A.10, %B.10
1086  %A.gep.11 = getelementptr i8, i8* %A, i64 11
1087  %A.11 = load i8, i8* %A.gep.11
1088  %B.gep.11 = getelementptr i8, i8* %B, i64 11
1089  %B.11 = load i8, i8* %B.gep.11
1090  %xor.11 = xor i8 %A.11, %B.11
1091  %A.gep.12 = getelementptr i8, i8* %A, i64 12
1092  %A.12 = load i8, i8* %A.gep.12
1093  %B.gep.12 = getelementptr i8, i8* %B, i64 12
1094  %B.12 = load i8, i8* %B.gep.12
1095  %xor.12 = xor i8 %A.12, %B.12
1096  %A.gep.13 = getelementptr i8, i8* %A, i64 13
1097  %A.13 = load i8, i8* %A.gep.13
1098  %B.gep.13 = getelementptr i8, i8* %B, i64 13
1099  %B.13 = load i8, i8* %B.gep.13
1100  %xor.13 = xor i8 %A.13, %B.13
1101  %A.gep.14 = getelementptr i8, i8* %A, i64 14
1102  %A.14 = load i8, i8* %A.gep.14
1103  %B.gep.14 = getelementptr i8, i8* %B, i64 14
1104  %B.14 = load i8, i8* %B.gep.14
1105  %xor.14 = xor i8 %A.14, %B.14
1106  %A.gep.15 = getelementptr i8, i8* %A, i64 15
1107  %A.15 = load i8, i8* %A.gep.15
1108  %B.gep.15 = getelementptr i8, i8* %B, i64 15
1109  %B.15 = load i8, i8* %B.gep.15
1110  %xor.15 = xor i8 %A.15, %B.15
1111  %R.gep.0 = getelementptr i8, i8* %arg1, i64 0
1112  store i8 %xor.0, i8* %R.gep.0
1113  %R.gep.1 = getelementptr i8, i8* %arg1, i64 1
1114  store i8 %xor.1, i8* %R.gep.1
1115  %R.gep.2 = getelementptr i8, i8* %arg1, i64 2
1116  store i8 %xor.2, i8* %R.gep.2
1117  %R.gep.3 = getelementptr i8, i8* %arg1, i64 3
1118  store i8 %xor.3, i8* %R.gep.3
1119  %R.gep.4 = getelementptr i8, i8* %arg1, i64 4
1120  store i8 %xor.4, i8* %R.gep.4
1121  %R.gep.5 = getelementptr i8, i8* %arg1, i64 5
1122  store i8 %xor.5, i8* %R.gep.5
1123  %R.gep.6 = getelementptr i8, i8* %arg1, i64 6
1124  store i8 %xor.6, i8* %R.gep.6
1125  %R.gep.7 = getelementptr i8, i8* %arg1, i64 7
1126  store i8 %xor.7, i8* %R.gep.7
1127  %R.gep.8 = getelementptr i8, i8* %arg1, i64 8
1128  store i8 %xor.8, i8* %R.gep.8
1129  %R.gep.9 = getelementptr i8, i8* %arg1, i64 9
1130  store i8 %xor.9, i8* %R.gep.9
1131  %R.gep.10 = getelementptr i8, i8* %arg1, i64 10
1132  store i8 %xor.10, i8* %R.gep.10
1133  %R.gep.11 = getelementptr i8, i8* %arg1, i64 11
1134  store i8 %xor.11, i8* %R.gep.11
1135  %R.gep.12 = getelementptr i8, i8* %arg1, i64 12
1136  store i8 %xor.12, i8* %R.gep.12
1137  %R.gep.13 = getelementptr i8, i8* %arg1, i64 13
1138  store i8 %xor.13, i8* %R.gep.13
1139  %R.gep.14 = getelementptr i8, i8* %arg1, i64 14
1140  store i8 %xor.14, i8* %R.gep.14
1141  %R.gep.15 = getelementptr i8, i8* %arg1, i64 15
1142  store i8 %xor.15, i8* %R.gep.15
1143
1144
1145  %t21 = getelementptr inbounds i8, i8* %arg3, i64 15
1146  %t22 = bitcast i8* %arg3 to <16 x i8>*
1147
1148  call void @foo(i8* nonnull %t4)
1149  %t26 = load i8, i8* %arg3, align 1
1150  %t27 = load i8, i8* %arg2, align 1
1151  %t28 = xor i8 %t27, %t26
1152  store i8 %t28, i8* %arg2, align 1
1153  %t29 = load i8, i8* %t5, align 1
1154  %t30 = getelementptr inbounds i8, i8* %arg2, i64 1
1155  %t31 = load i8, i8* %t30, align 1
1156  %t32 = xor i8 %t31, %t29
1157  store i8 %t32, i8* %t30, align 1
1158  %t33 = load i8, i8* %t6, align 1
1159  %t34 = getelementptr inbounds i8, i8* %arg2, i64 2
1160  %t35 = load i8, i8* %t34, align 1
1161  %t36 = xor i8 %t35, %t33
1162  store i8 %t36, i8* %t34, align 1
1163  %t37 = load i8, i8* %t7, align 1
1164  %t38 = getelementptr inbounds i8, i8* %arg2, i64 3
1165  %t39 = load i8, i8* %t38, align 1
1166  %t40 = xor i8 %t39, %t37
1167  store i8 %t40, i8* %t38, align 1
1168  %t41 = load i8, i8* %t8, align 1
1169  %t42 = getelementptr inbounds i8, i8* %arg2, i64 4
1170  %t43 = load i8, i8* %t42, align 1
1171  %t44 = xor i8 %t43, %t41
1172  store i8 %t44, i8* %t42, align 1
1173  %t45 = load i8, i8* %t9, align 1
1174  %t46 = getelementptr inbounds i8, i8* %arg2, i64 5
1175  %t47 = load i8, i8* %t46, align 1
1176  %t48 = xor i8 %t47, %t45
1177  store i8 %t48, i8* %t46, align 1
1178  %t49 = load i8, i8* %t10, align 1
1179  %t50 = getelementptr inbounds i8, i8* %arg2, i64 6
1180  %t51 = load i8, i8* %t50, align 1
1181  %t52 = xor i8 %t51, %t49
1182  store i8 %t52, i8* %t50, align 1
1183  %t53 = load i8, i8* %t11, align 1
1184  %t54 = getelementptr inbounds i8, i8* %arg2, i64 7
1185  %t55 = load i8, i8* %t54, align 1
1186  %t56 = xor i8 %t55, %t53
1187  store i8 %t56, i8* %t54, align 1
1188  %t57 = load i8, i8* %t12, align 1
1189  %t58 = getelementptr inbounds i8, i8* %arg2, i64 8
1190  %t59 = load i8, i8* %t58, align 1
1191  %t60 = xor i8 %t59, %t57
1192  store i8 %t60, i8* %t58, align 1
1193  %t61 = load i8, i8* %t13, align 1
1194  %t62 = getelementptr inbounds i8, i8* %arg2, i64 9
1195  %t63 = load i8, i8* %t62, align 1
1196  %t64 = xor i8 %t63, %t61
1197  store i8 %t64, i8* %t62, align 1
1198  %t65 = load i8, i8* %t14, align 1
1199  %t66 = getelementptr inbounds i8, i8* %arg2, i64 10
1200  %t67 = load i8, i8* %t66, align 1
1201  %t68 = xor i8 %t67, %t65
1202  store i8 %t68, i8* %t66, align 1
1203  %t69 = load i8, i8* %t15, align 1
1204  %t70 = getelementptr inbounds i8, i8* %arg2, i64 11
1205  %t71 = load i8, i8* %t70, align 1
1206  %t72 = xor i8 %t71, %t69
1207  store i8 %t72, i8* %t70, align 1
1208  %t73 = load i8, i8* %t16, align 1
1209  %t74 = getelementptr inbounds i8, i8* %arg2, i64 12
1210  %t75 = load i8, i8* %t74, align 1
1211  %t76 = xor i8 %t75, %t73
1212  store i8 %t76, i8* %t74, align 1
1213  %t77 = load i8, i8* %t17, align 1
1214  %t78 = getelementptr inbounds i8, i8* %arg2, i64 13
1215  %t79 = load i8, i8* %t78, align 1
1216  %t80 = xor i8 %t79, %t77
1217  store i8 %t80, i8* %t78, align 1
1218  %t81 = load i8, i8* %t18, align 1
1219  %t82 = getelementptr inbounds i8, i8* %arg2, i64 14
1220  %t83 = load i8, i8* %t82, align 1
1221  %t84 = xor i8 %t83, %t81
1222  store i8 %t84, i8* %t82, align 1
1223  %t85 = load i8, i8* %t21, align 1
1224  %t86 = getelementptr inbounds i8, i8* %arg2, i64 15
1225  %t87 = load i8, i8* %t86, align 1
1226  %t88 = xor i8 %t87, %t85
1227  store i8 %t88, i8* %t86, align 1
1228  ret i32 1
1229}
1230
1231; A test case where instructions required to compute the pointer bounds get
1232; vectorized before versioning. Make sure there is no crash.
1233define void @crash_instructions_deleted(float* %t, i32* %a, i32** noalias %ptr) {
1234; CHECK-LABEL: @crash_instructions_deleted(
1235; CHECK-NEXT:  bb:
1236; CHECK-NEXT:    [[T15:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 2
1237; CHECK-NEXT:    [[T16:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 3
1238; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[T15]] to <2 x i32>*
1239; CHECK-NEXT:    store <2 x i32> <i32 0, i32 10>, <2 x i32>* [[TMP0]], align 8
1240; CHECK-NEXT:    [[T17:%.*]] = load i32*, i32** [[PTR:%.*]], align 8
1241; CHECK-NEXT:    br label [[BB18:%.*]]
1242; CHECK:       bb18:
1243; CHECK-NEXT:    [[T19:%.*]] = sext i32 0 to i64
1244; CHECK-NEXT:    [[T20:%.*]] = add nsw i64 1, [[T19]]
1245; CHECK-NEXT:    [[T21:%.*]] = getelementptr inbounds i32, i32* [[T17]], i64 [[T20]]
1246; CHECK-NEXT:    [[T22:%.*]] = bitcast i32* [[T21]] to i8*
1247; CHECK-NEXT:    [[T23:%.*]] = getelementptr inbounds i8, i8* [[T22]], i64 1
1248; CHECK-NEXT:    [[T24:%.*]] = getelementptr inbounds i8, i8* [[T22]], i64 2
1249; CHECK-NEXT:    [[T25:%.*]] = getelementptr inbounds i8, i8* [[T22]], i64 3
1250; CHECK-NEXT:    [[T26:%.*]] = load i8, i8* [[T22]], align 1
1251; CHECK-NEXT:    [[T27:%.*]] = uitofp i8 [[T26]] to float
1252; CHECK-NEXT:    [[T28:%.*]] = fdiv float [[T27]], 2.550000e+02
1253; CHECK-NEXT:    [[T29:%.*]] = getelementptr inbounds float, float* [[T:%.*]], i64 0
1254; CHECK-NEXT:    store float [[T28]], float* [[T29]], align 8
1255; CHECK-NEXT:    [[T30:%.*]] = load i8, i8* [[T23]], align 1
1256; CHECK-NEXT:    [[T31:%.*]] = uitofp i8 [[T30]] to float
1257; CHECK-NEXT:    [[T32:%.*]] = fdiv float [[T31]], 2.550000e+02
1258; CHECK-NEXT:    [[T33:%.*]] = getelementptr inbounds float, float* [[T]], i64 1
1259; CHECK-NEXT:    store float [[T32]], float* [[T33]], align 4
1260; CHECK-NEXT:    [[T34:%.*]] = load i8, i8* [[T24]], align 1
1261; CHECK-NEXT:    [[T35:%.*]] = uitofp i8 [[T34]] to float
1262; CHECK-NEXT:    [[T36:%.*]] = fdiv float [[T35]], 2.550000e+02
1263; CHECK-NEXT:    [[T37:%.*]] = getelementptr inbounds float, float* [[T]], i64 2
1264; CHECK-NEXT:    store float [[T36]], float* [[T37]], align 8
1265; CHECK-NEXT:    [[T38:%.*]] = load i8, i8* [[T25]], align 1
1266; CHECK-NEXT:    [[T39:%.*]] = uitofp i8 [[T38]] to float
1267; CHECK-NEXT:    [[T40:%.*]] = fdiv float [[T39]], 2.550000e+02
1268; CHECK-NEXT:    [[T41:%.*]] = getelementptr inbounds float, float* [[T]], i64 3
1269; CHECK-NEXT:    store float [[T40]], float* [[T41]], align 4
1270; CHECK-NEXT:    ret void
1271;
1272bb:
1273  %t6 = icmp slt i32 10, 0
1274  %t7 = icmp sgt i32 20, 20
1275  %t9 = select i1 %t7, i32 5, i32 0
1276  %t10 = select i1 %t6, i32 0, i32 %t9
1277  %t11 = icmp slt i32 10, 0
1278  %t12 = icmp sgt i32 20, 20
1279  %t13 = select i1 %t12, i32 5, i32 10
1280  %t14 = select i1 %t11, i32 0, i32 %t13
1281  %t15 = getelementptr inbounds i32, i32* %a, i32 2
1282  store i32 %t10, i32* %t15, align 8
1283  %t16 = getelementptr inbounds i32, i32* %a, i32 3
1284  store i32 %t14, i32* %t16, align 4
1285  %t17 = load i32*, i32** %ptr, align 8
1286  br label %bb18
1287
1288bb18:                                             ; preds = %bb5
1289  %t19 = sext i32 %t10 to i64
1290  %t20 = add nsw i64 1, %t19
1291  %t21 = getelementptr inbounds i32, i32* %t17, i64 %t20
1292  %t22 = bitcast i32* %t21 to i8*
1293  %t23 = getelementptr inbounds i8, i8* %t22, i64 1
1294  %t24 = getelementptr inbounds i8, i8* %t22, i64 2
1295  %t25 = getelementptr inbounds i8, i8* %t22, i64 3
1296  %t26 = load i8, i8* %t22, align 1
1297  %t27 = uitofp i8 %t26 to float
1298  %t28 = fdiv float %t27, 2.550000e+02
1299  %t29 = getelementptr inbounds float, float* %t, i64 0
1300  store float %t28, float* %t29, align 8
1301  %t30 = load i8, i8* %t23, align 1
1302  %t31 = uitofp i8 %t30 to float
1303  %t32 = fdiv float %t31, 2.550000e+02
1304  %t33 = getelementptr inbounds float, float* %t, i64 1
1305  store float %t32, float* %t33, align 4
1306  %t34 = load i8, i8* %t24, align 1
1307  %t35 = uitofp i8 %t34 to float
1308  %t36 = fdiv float %t35, 2.550000e+02
1309  %t37 = getelementptr inbounds float, float* %t, i64 2
1310  store float %t36, float* %t37, align 8
1311  %t38 = load i8, i8* %t25, align 1
1312  %t39 = uitofp i8 %t38 to float
1313  %t40 = fdiv float %t39, 2.550000e+02
1314  %t41 = getelementptr inbounds float, float* %t, i64 3
1315  store float %t40, float* %t41, align 4
1316  ret void
1317}
1318
1319; A test case where there are no instructions accessing a tracked object in a
1320; block for which versioning was requested.
1321define void @crash_no_tracked_instructions(float** %arg, float* %arg.2, float* %arg.3, i1 %c) {
1322; CHECK-LABEL: @crash_no_tracked_instructions(
1323; CHECK-NEXT:  entry:
1324; CHECK-NEXT:    [[T19:%.*]] = load float*, float** [[ARG:%.*]], align 8
1325; CHECK-NEXT:    [[T20:%.*]] = load float, float* [[ARG_3:%.*]], align 4
1326; CHECK-NEXT:    [[T21:%.*]] = getelementptr inbounds float, float* [[ARG_2:%.*]], i64 0
1327; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB22:%.*]], label [[BB30:%.*]]
1328; CHECK:       bb22:
1329; CHECK-NEXT:    [[T23:%.*]] = fmul float [[T20]], 9.900000e+01
1330; CHECK-NEXT:    [[T24:%.*]] = fmul float [[T23]], 9.900000e+01
1331; CHECK-NEXT:    [[T25:%.*]] = getelementptr inbounds float, float* [[T19]], i64 2
1332; CHECK-NEXT:    [[T26:%.*]] = fmul float [[T23]], 1.000000e+01
1333; CHECK-NEXT:    store float [[T26]], float* [[T25]], align 4
1334; CHECK-NEXT:    [[T27:%.*]] = load float, float* [[T21]], align 8
1335; CHECK-NEXT:    [[T28:%.*]] = fadd float [[T24]], 2.000000e+01
1336; CHECK-NEXT:    [[T29:%.*]] = fadd float [[T26]], 2.000000e+01
1337; CHECK-NEXT:    br label [[BB30]]
1338; CHECK:       bb30:
1339; CHECK-NEXT:    [[T31:%.*]] = phi float [ [[T28]], [[BB22]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]
1340; CHECK-NEXT:    [[T32:%.*]] = phi float [ [[T29]], [[BB22]] ], [ [[T20]], [[ENTRY]] ]
1341; CHECK-NEXT:    br label [[BB36:%.*]]
1342; CHECK:       bb36:
1343; CHECK-NEXT:    [[T37:%.*]] = fmul float [[T31]], 3.000000e+00
1344; CHECK-NEXT:    [[T38:%.*]] = getelementptr inbounds float, float* [[ARG_3]], i64 0
1345; CHECK-NEXT:    store float [[T37]], float* [[T38]], align 4
1346; CHECK-NEXT:    [[T39:%.*]] = fmul float [[T32]], 3.000000e+00
1347; CHECK-NEXT:    [[T40:%.*]] = getelementptr inbounds float, float* [[ARG_3]], i64 1
1348; CHECK-NEXT:    store float [[T39]], float* [[T40]], align 4
1349; CHECK-NEXT:    br label [[BB41:%.*]]
1350; CHECK:       bb41:
1351; CHECK-NEXT:    ret void
1352;
1353entry:
1354  %t19 = load float*, float** %arg
1355  %t20 = load float, float* %arg.3, align 4
1356  %t21 = getelementptr inbounds float, float* %arg.2, i64 0
1357  br i1 %c, label %bb22, label %bb30
1358
1359bb22:
1360  %t23 = fmul float %t20, 99.0
1361  %t24 = fmul float %t23, 99.0
1362  %t25 = getelementptr inbounds float, float* %t19, i64 2
1363  %t26 = fmul float %t23, 10.0
1364  store float %t26, float* %t25, align 4
1365  %t27 = load float, float* %t21, align 8
1366  %t28 = fadd float %t24, 20.0
1367  %t29 = fadd float %t26, 20.0
1368  br label %bb30
1369
1370bb30:
1371  %t31 = phi float [ %t28, %bb22 ], [ 0.0, %entry ]
1372  %t32 = phi float [ %t29, %bb22 ], [ %t20, %entry ]
1373  br label %bb36
1374
1375bb36:
1376  %t37 = fmul float %t31, 3.0
1377  %t38 = getelementptr inbounds float, float* %arg.3, i64 0
1378  store float %t37, float* %t38, align 4
1379  %t39 = fmul float %t32, 3.0
1380  %t40 = getelementptr inbounds float, float* %arg.3, i64 1
1381  store float %t39, float* %t40, align 4
1382  br label %bb41
1383
1384bb41:
1385  ret void
1386}
1387