1; RUN: opt -basic-aa -loop-accesses -analyze -enable-new-pm=0 < %s | FileCheck %s -check-prefix=LAA
2; RUN: opt -passes='require<aa>,require<scalar-evolution>,require<aa>,loop(print-access-info)' -aa-pipeline='basic-aa' -disable-output < %s  2>&1 | FileCheck %s --check-prefix=LAA
3; RUN: opt -loop-versioning -S < %s | FileCheck %s -check-prefix=LV
4
5target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6
7; For this loop:
8;   unsigned index = 0;
9;   for (int i = 0; i < n; i++) {
10;    A[2 * index] = A[2 * index] + B[i];
11;    index++;
12;   }
13;
14; SCEV is unable to prove that A[2 * i] does not overflow.
15;
16; Analyzing the IR does not help us because the GEPs are not
17; affine AddRecExprs. However, we can turn them into AddRecExprs
18; using SCEV Predicates.
19;
20; Once we have an affine expression we need to add an additional NUSW
21; to check that the pointers don't wrap since the GEPs are not
22; inbound.
23
24; LAA-LABEL: f1
25; LAA: Memory dependences are safe{{$}}
26; LAA: SCEV assumptions:
27; LAA-NEXT: {0,+,2}<%for.body> Added Flags: <nusw>
28; LAA-NEXT: {%a,+,4}<%for.body> Added Flags: <nusw>
29
30; The expression for %mul_ext as analyzed by SCEV is
31;    (zext i32 {0,+,2}<%for.body> to i64)
32; We have added the nusw flag to turn this expression into the SCEV expression:
33;    i64 {0,+,2}<%for.body>
34
35; LAA: [PSE]  %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext:
36; LAA-NEXT: ((2 * (zext i32 {0,+,2}<%for.body> to i64))<nuw><nsw> + %a)
37; LAA-NEXT: --> {%a,+,4}<%for.body>
38
39
40; LV-LABEL: f1
41; LV-LABEL: for.body.lver.check
42
43; LV-NEXT: [[A0:%[^ ]*]] = ptrtoint i16* %a to i64
44
45; LV:      [[BETrunc:%[^ ]*]] = trunc i64 [[BE:%[^ ]*]] to i32
46; LV-NEXT: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc]])
47; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
48; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
49; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 0, [[OFMulResult]]
50; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 0, [[OFMulResult]]
51; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp ugt i32 [[SubEnd]], 0
52; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp ult i32 [[AddEnd]], 0
53; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg]], i1 [[CmpPos]]
54; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
55; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
56; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
57
58; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
59
60
61; LV-NEXT: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE]])
62; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
63; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
64; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[A0:%[^ ]*]], [[OFMulResult1]]
65; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[A0]], [[OFMulResult1]]
66; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[A0]]
67; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[A0]]
68; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg1]], i1 [[CmpPos1]]
69; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
70
71; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
72; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
73define void @f1(i16* noalias %a,
74                i16* noalias %b, i64 %N) {
75entry:
76  br label %for.body
77
78for.body:                                         ; preds = %for.body, %entry
79  %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
80  %ind1 = phi i32 [ 0, %entry ], [ %inc1, %for.body ]
81
82  %mul = mul i32 %ind1, 2
83  %mul_ext = zext i32 %mul to i64
84
85  %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext
86  %loadA = load i16, i16* %arrayidxA, align 2
87
88  %arrayidxB = getelementptr i16, i16* %b, i64 %ind
89  %loadB = load i16, i16* %arrayidxB, align 2
90
91  %add = mul i16 %loadA, %loadB
92
93  store i16 %add, i16* %arrayidxA, align 2
94
95  %inc = add nuw nsw i64 %ind, 1
96  %inc1 = add i32 %ind1, 1
97
98  %exitcond = icmp eq i64 %inc, %N
99  br i1 %exitcond, label %for.end, label %for.body
100
101for.end:                                          ; preds = %for.body
102  ret void
103}
104
105; For this loop:
106;   unsigned index = n;
107;   for (int i = 0; i < n; i++) {
108;    A[2 * index] = A[2 * index] + B[i];
109;    index--;
110;   }
111;
112; the SCEV expression for 2 * index is not an AddRecExpr
113; (and implictly not affine). However, we are able to make assumptions
114; that will turn the expression into an affine one and continue the
115; analysis.
116;
117; Once we have an affine expression we need to add an additional NUSW
118; to check that the pointers don't wrap since the GEPs are not
119; inbounds.
120;
121; This loop has a negative stride for A, and the nusw flag is required in
122; order to properly extend the increment from i32 -4 to i64 -4.
123
124; LAA-LABEL: f2
125; LAA: Memory dependences are safe{{$}}
126; LAA: SCEV assumptions:
127; LAA-NEXT: {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> Added Flags: <nusw>
128; LAA-NEXT: {((4 * (zext i31 (trunc i64 %N to i31) to i64))<nuw><nsw> + %a),+,-4}<%for.body> Added Flags: <nusw>
129
130; The expression for %mul_ext as analyzed by SCEV is
131;     (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)
132; We have added the nusw flag to turn this expression into the following SCEV:
133;     i64 {zext i32 (2 * (trunc i64 %N to i32)) to i64,+,-2}<%for.body>
134
135; LAA: [PSE]  %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext:
136; LAA-NEXT: ((2 * (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64))<nuw><nsw> + %a)
137; LAA-NEXT: --> {((4 * (zext i31 (trunc i64 %N to i31) to i64))<nuw><nsw> + %a),+,-4}<%for.body>
138
139; LV-LABEL: f2
140; LV-LABEL: for.body.lver.check
141
142; LV: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc:%[^ ]*]])
143; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
144; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
145; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 [[Start:%[^ ]*]], [[OFMulResult]]
146; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 [[Start]], [[OFMulResult]]
147; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp ugt i32 [[SubEnd]], [[Start]]
148; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp ult i32 [[AddEnd]], [[Start]]
149; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg]], i1 [[CmpPos]]
150; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
151; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
152; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
153
154; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
155
156; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE]])
157; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
158; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
159; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[Start:%[^ ]*]], [[OFMulResult1]]
160; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[Start]], [[OFMulResult1]]
161; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[Start]]
162; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[Start]]
163; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg1]], i1 [[CmpPos1]]
164; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
165
166; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
167; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
168define void @f2(i16* noalias %a,
169                i16* noalias %b, i64 %N) {
170entry:
171  %TruncN = trunc i64 %N to i32
172  br label %for.body
173
174for.body:                                         ; preds = %for.body, %entry
175  %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
176  %ind1 = phi i32 [ %TruncN, %entry ], [ %dec, %for.body ]
177
178  %mul = mul i32 %ind1, 2
179  %mul_ext = zext i32 %mul to i64
180
181  %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext
182  %loadA = load i16, i16* %arrayidxA, align 2
183
184  %arrayidxB = getelementptr i16, i16* %b, i64 %ind
185  %loadB = load i16, i16* %arrayidxB, align 2
186
187  %add = mul i16 %loadA, %loadB
188
189  store i16 %add, i16* %arrayidxA, align 2
190
191  %inc = add nuw nsw i64 %ind, 1
192  %dec = sub i32 %ind1, 1
193
194  %exitcond = icmp eq i64 %inc, %N
195  br i1 %exitcond, label %for.end, label %for.body
196
197for.end:                                          ; preds = %for.body
198  ret void
199}
200
201; We replicate the tests above, but this time sign extend 2 * index instead
202; of zero extending it.
203
204; LAA-LABEL: f3
205; LAA: Memory dependences are safe{{$}}
206; LAA: SCEV assumptions:
207; LAA-NEXT: {0,+,2}<%for.body> Added Flags: <nssw>
208; LAA-NEXT: {%a,+,4}<%for.body> Added Flags: <nusw>
209
210; The expression for %mul_ext as analyzed by SCEV is
211;     i64 (sext i32 {0,+,2}<%for.body> to i64)
212; We have added the nssw flag to turn this expression into the following SCEV:
213;     i64 {0,+,2}<%for.body>
214
215; LAA: [PSE]  %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext:
216; LAA-NEXT: ((2 * (sext i32 {0,+,2}<%for.body> to i64))<nsw> + %a)
217; LAA-NEXT: --> {%a,+,4}<%for.body>
218
219; LV-LABEL: f3
220; LV-LABEL: for.body.lver.check
221
222; LV: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc:%[^ ]*]])
223; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
224; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
225; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 0, [[OFMulResult]]
226; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 0, [[OFMulResult]]
227; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp sgt i32 [[SubEnd]], 0
228; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp slt i32 [[AddEnd]], 0
229; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg]], i1 [[CmpPos]]
230; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
231; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
232; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
233
234; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
235
236; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]])
237; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
238; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
239; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[A0:%[^ ]*]], [[OFMulResult1]]
240; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[A0]], [[OFMulResult1]]
241; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[A0]]
242; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[A0]]
243; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg1]], i1 [[CmpPos1]]
244; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
245
246; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
247; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
248define void @f3(i16* noalias %a,
249                i16* noalias %b, i64 %N) {
250entry:
251  br label %for.body
252
253for.body:                                         ; preds = %for.body, %entry
254  %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
255  %ind1 = phi i32 [ 0, %entry ], [ %inc1, %for.body ]
256
257  %mul = mul i32 %ind1, 2
258  %mul_ext = sext i32 %mul to i64
259
260  %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext
261  %loadA = load i16, i16* %arrayidxA, align 2
262
263  %arrayidxB = getelementptr i16, i16* %b, i64 %ind
264  %loadB = load i16, i16* %arrayidxB, align 2
265
266  %add = mul i16 %loadA, %loadB
267
268  store i16 %add, i16* %arrayidxA, align 2
269
270  %inc = add nuw nsw i64 %ind, 1
271  %inc1 = add i32 %ind1, 1
272
273  %exitcond = icmp eq i64 %inc, %N
274  br i1 %exitcond, label %for.end, label %for.body
275
276for.end:                                          ; preds = %for.body
277  ret void
278}
279
280; LAA-LABEL: f4
281; LAA: Memory dependences are safe{{$}}
282; LAA: SCEV assumptions:
283; LAA-NEXT: {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> Added Flags: <nssw>
284; LAA-NEXT: {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64))<nsw> + %a),+,-4}<%for.body> Added Flags: <nusw>
285
286; The expression for %mul_ext as analyzed by SCEV is
287;     i64  (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)
288; We have added the nssw flag to turn this expression into the following SCEV:
289;     i64 {sext i32 (2 * (trunc i64 %N to i32)) to i64,+,-2}<%for.body>
290
291; LAA: [PSE]  %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext:
292; LAA-NEXT: ((2 * (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64))<nsw> + %a)
293; LAA-NEXT: --> {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64))<nsw> + %a),+,-4}<%for.body>
294
295; LV-LABEL: f4
296; LV-LABEL: for.body.lver.check
297
298; LV: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc:%[^ ]*]])
299; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
300; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
301; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 [[Start:%[^ ]*]], [[OFMulResult]]
302; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 [[Start]], [[OFMulResult]]
303; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp sgt i32 [[SubEnd]], [[Start]]
304; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp slt i32 [[AddEnd]], [[Start]]
305; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg]], i1 [[CmpPos]]
306; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
307; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
308; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
309
310; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
311
312; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]])
313; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
314; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
315; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[Start:%[^ ]*]], [[OFMulResult1]]
316; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[Start]], [[OFMulResult1]]
317; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[Start]]
318; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[Start]]
319; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg1]], i1 [[CmpPos1]]
320; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
321
322; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
323; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
324define void @f4(i16* noalias %a,
325                i16* noalias %b, i64 %N) {
326entry:
327  %TruncN = trunc i64 %N to i32
328  br label %for.body
329
330for.body:                                         ; preds = %for.body, %entry
331  %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
332  %ind1 = phi i32 [ %TruncN, %entry ], [ %dec, %for.body ]
333
334  %mul = mul i32 %ind1, 2
335  %mul_ext = sext i32 %mul to i64
336
337  %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext
338  %loadA = load i16, i16* %arrayidxA, align 2
339
340  %arrayidxB = getelementptr i16, i16* %b, i64 %ind
341  %loadB = load i16, i16* %arrayidxB, align 2
342
343  %add = mul i16 %loadA, %loadB
344
345  store i16 %add, i16* %arrayidxA, align 2
346
347  %inc = add nuw nsw i64 %ind, 1
348  %dec = sub i32 %ind1, 1
349
350  %exitcond = icmp eq i64 %inc, %N
351  br i1 %exitcond, label %for.end, label %for.body
352
353for.end:                                          ; preds = %for.body
354  ret void
355}
356
357; The following function is similar to the one above, but has the GEP
358; to pointer %A inbounds. The index %mul doesn't have the nsw flag.
359; This means that the SCEV expression for %mul can wrap and we need
360; a SCEV predicate to continue analysis.
361;
362; We can still analyze this by adding the required no wrap SCEV predicates.
363
364; LAA-LABEL: f5
365; LAA: Memory dependences are safe{{$}}
366; LAA: SCEV assumptions:
367; LAA-NEXT: {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> Added Flags: <nssw>
368; LAA-NEXT: {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64))<nsw> + %a),+,-4}<%for.body> Added Flags: <nusw>
369
370; LAA: [PSE]  %arrayidxA = getelementptr inbounds i16, i16* %a, i32 %mul:
371; LAA-NEXT: ((2 * (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64))<nsw> + %a)
372; LAA-NEXT: --> {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64))<nsw> + %a),+,-4}<%for.body>
373
374; LV-LABEL: f5
375; LV-LABEL: for.body.lver.check
376; LV: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc:%[^ ]*]])
377; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
378; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
379; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 [[Start:%[^ ]*]], [[OFMulResult]]
380; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 [[Start]], [[OFMulResult]]
381; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp sgt i32 [[SubEnd]], [[Start]]
382; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp slt i32 [[AddEnd]], [[Start]]
383; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg]], i1 [[CmpPos]]
384; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
385; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
386; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
387
388; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
389
390; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]])
391; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
392; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
393; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[Start:%[^ ]*]], [[OFMulResult1]]
394; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[Start]], [[OFMulResult1]]
395; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[Start]]
396; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[Start]]
397; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg1]], i1 [[CmpPos1]]
398; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
399
400; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
401; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
402define void @f5(i16* noalias %a,
403                i16* noalias %b, i64 %N) {
404entry:
405  %TruncN = trunc i64 %N to i32
406  br label %for.body
407
408for.body:                                         ; preds = %for.body, %entry
409  %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
410  %ind1 = phi i32 [ %TruncN, %entry ], [ %dec, %for.body ]
411
412  %mul = mul i32 %ind1, 2
413
414  %arrayidxA = getelementptr inbounds i16, i16* %a, i32 %mul
415  %loadA = load i16, i16* %arrayidxA, align 2
416
417  %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind
418  %loadB = load i16, i16* %arrayidxB, align 2
419
420  %add = mul i16 %loadA, %loadB
421
422  store i16 %add, i16* %arrayidxA, align 2
423
424  %inc = add nuw nsw i64 %ind, 1
425  %dec = sub i32 %ind1, 1
426
427  %exitcond = icmp eq i64 %inc, %N
428  br i1 %exitcond, label %for.end, label %for.body
429
430for.end:                                          ; preds = %for.body
431  ret void
432}
433