xref: /llvm-project/llvm/test/Transforms/IndVarSimplify/ARM/code-size.ll (revision 3ce360f15b5a790a5fd9dcab716bbed7b4d3a347)
15eb705d5SSam Parker; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
26017d9a6SRoman Lebedev; RUN: opt -mtriple=thumbv8m.main -passes=indvars -S < %s | FileCheck %s --check-prefix=CHECK-V8M
36017d9a6SRoman Lebedev; RUN: opt -mtriple=thumbv8a -passes=indvars -S < %s | FileCheck %s --check-prefix=CHECK-V8A
45eb705d5SSam Parker
55eb705d5SSam Parkerdefine i32 @remove_loop(i32 %size) #0 {
65eb705d5SSam Parker; CHECK-V8M-LABEL: @remove_loop(
75eb705d5SSam Parker; CHECK-V8M-NEXT:  entry:
85eb705d5SSam Parker; CHECK-V8M-NEXT:    [[TMP0:%.*]] = add i32 [[SIZE:%.*]], 31
9b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SIZE]], i32 31)
10b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[UMIN]]
11b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 5
12b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP3:%.*]] = shl nuw i32 [[TMP2]], 5
135eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[WHILE_COND:%.*]]
145eb705d5SSam Parker; CHECK-V8M:       while.cond:
155eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 false, label [[WHILE_COND]], label [[WHILE_END:%.*]]
165eb705d5SSam Parker; CHECK-V8M:       while.end:
17b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP4:%.*]] = sub i32 [[SIZE]], [[TMP3]]
18b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    ret i32 [[TMP4]]
195eb705d5SSam Parker;
205eb705d5SSam Parker; CHECK-V8A-LABEL: @remove_loop(
215eb705d5SSam Parker; CHECK-V8A-NEXT:  entry:
225eb705d5SSam Parker; CHECK-V8A-NEXT:    [[TMP0:%.*]] = add i32 [[SIZE:%.*]], 31
23b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SIZE]], i32 31)
24b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[UMIN]]
25b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 5
26b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP3:%.*]] = shl nuw i32 [[TMP2]], 5
275eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[WHILE_COND:%.*]]
285eb705d5SSam Parker; CHECK-V8A:       while.cond:
295eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 false, label [[WHILE_COND]], label [[WHILE_END:%.*]]
305eb705d5SSam Parker; CHECK-V8A:       while.end:
31b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP4:%.*]] = sub i32 [[SIZE]], [[TMP3]]
32b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    ret i32 [[TMP4]]
335eb705d5SSam Parker;
345eb705d5SSam Parkerentry:
355eb705d5SSam Parker  br label %while.cond
365eb705d5SSam Parker
375eb705d5SSam Parkerwhile.cond:                                       ; preds = %while.cond, %entry
385eb705d5SSam Parker  %size.addr.0 = phi i32 [ %size, %entry ], [ %sub, %while.cond ]
395eb705d5SSam Parker  %cmp = icmp ugt i32 %size.addr.0, 31
405eb705d5SSam Parker  %sub = add i32 %size.addr.0, -32
415eb705d5SSam Parker  br i1 %cmp, label %while.cond, label %while.end
425eb705d5SSam Parker
435eb705d5SSam Parkerwhile.end:                                        ; preds = %while.cond
445eb705d5SSam Parker  %size.lcssa = phi i32 [ %size.addr.0, %while.cond ]
455eb705d5SSam Parker  ret i32 %size.lcssa
465eb705d5SSam Parker}
475eb705d5SSam Parker
485eb705d5SSam Parkerdefine void @expandOuterRecurrence(i32 %arg) nounwind #0 {
495eb705d5SSam Parker; CHECK-V8M-LABEL: @expandOuterRecurrence(
505eb705d5SSam Parker; CHECK-V8M-NEXT:  entry:
515eb705d5SSam Parker; CHECK-V8M-NEXT:    [[SUB1:%.*]] = sub nsw i32 [[ARG:%.*]], 1
525eb705d5SSam Parker; CHECK-V8M-NEXT:    [[CMP1:%.*]] = icmp slt i32 0, [[SUB1]]
535eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 [[CMP1]], label [[OUTER_PREHEADER:%.*]], label [[EXIT:%.*]]
545eb705d5SSam Parker; CHECK-V8M:       outer.preheader:
555eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[OUTER:%.*]]
565eb705d5SSam Parker; CHECK-V8M:       outer:
575eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I:%.*]] = phi i32 [ [[I_INC:%.*]], [[OUTER_INC:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
585eb705d5SSam Parker; CHECK-V8M-NEXT:    [[SUB2:%.*]] = sub nsw i32 [[ARG]], [[I]]
595eb705d5SSam Parker; CHECK-V8M-NEXT:    [[SUB3:%.*]] = sub nsw i32 [[SUB2]], 1
605eb705d5SSam Parker; CHECK-V8M-NEXT:    [[CMP2:%.*]] = icmp slt i32 0, [[SUB3]]
615eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 [[CMP2]], label [[INNER_PH:%.*]], label [[OUTER_INC]]
625eb705d5SSam Parker; CHECK-V8M:       inner.ph:
635eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[INNER:%.*]]
645eb705d5SSam Parker; CHECK-V8M:       inner:
655eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 false, label [[INNER]], label [[OUTER_INC_LOOPEXIT:%.*]]
665eb705d5SSam Parker; CHECK-V8M:       outer.inc.loopexit:
675eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[OUTER_INC]]
685eb705d5SSam Parker; CHECK-V8M:       outer.inc:
695eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
705eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 false, label [[OUTER]], label [[EXIT_LOOPEXIT:%.*]]
715eb705d5SSam Parker; CHECK-V8M:       exit.loopexit:
725eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[EXIT]]
735eb705d5SSam Parker; CHECK-V8M:       exit:
745eb705d5SSam Parker; CHECK-V8M-NEXT:    ret void
755eb705d5SSam Parker;
765eb705d5SSam Parker; CHECK-V8A-LABEL: @expandOuterRecurrence(
775eb705d5SSam Parker; CHECK-V8A-NEXT:  entry:
785eb705d5SSam Parker; CHECK-V8A-NEXT:    [[SUB1:%.*]] = sub nsw i32 [[ARG:%.*]], 1
795eb705d5SSam Parker; CHECK-V8A-NEXT:    [[CMP1:%.*]] = icmp slt i32 0, [[SUB1]]
805eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 [[CMP1]], label [[OUTER_PREHEADER:%.*]], label [[EXIT:%.*]]
815eb705d5SSam Parker; CHECK-V8A:       outer.preheader:
825eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[OUTER:%.*]]
835eb705d5SSam Parker; CHECK-V8A:       outer:
845eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I:%.*]] = phi i32 [ [[I_INC:%.*]], [[OUTER_INC:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
855eb705d5SSam Parker; CHECK-V8A-NEXT:    [[SUB2:%.*]] = sub nsw i32 [[ARG]], [[I]]
865eb705d5SSam Parker; CHECK-V8A-NEXT:    [[SUB3:%.*]] = sub nsw i32 [[SUB2]], 1
875eb705d5SSam Parker; CHECK-V8A-NEXT:    [[CMP2:%.*]] = icmp slt i32 0, [[SUB3]]
885eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 [[CMP2]], label [[INNER_PH:%.*]], label [[OUTER_INC]]
895eb705d5SSam Parker; CHECK-V8A:       inner.ph:
905eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[INNER:%.*]]
915eb705d5SSam Parker; CHECK-V8A:       inner:
925eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 false, label [[INNER]], label [[OUTER_INC_LOOPEXIT:%.*]]
935eb705d5SSam Parker; CHECK-V8A:       outer.inc.loopexit:
945eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[OUTER_INC]]
955eb705d5SSam Parker; CHECK-V8A:       outer.inc:
965eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
975eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 false, label [[OUTER]], label [[EXIT_LOOPEXIT:%.*]]
985eb705d5SSam Parker; CHECK-V8A:       exit.loopexit:
995eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[EXIT]]
1005eb705d5SSam Parker; CHECK-V8A:       exit:
1015eb705d5SSam Parker; CHECK-V8A-NEXT:    ret void
1025eb705d5SSam Parker;
1035eb705d5SSam Parkerentry:
1045eb705d5SSam Parker  %sub1 = sub nsw i32 %arg, 1
1055eb705d5SSam Parker  %cmp1 = icmp slt i32 0, %sub1
1065eb705d5SSam Parker  br i1 %cmp1, label %outer, label %exit
1075eb705d5SSam Parker
1085eb705d5SSam Parkerouter:
1095eb705d5SSam Parker  %i = phi i32 [ 0, %entry ], [ %i.inc, %outer.inc ]
1105eb705d5SSam Parker  %sub2 = sub nsw i32 %arg, %i
1115eb705d5SSam Parker  %sub3 = sub nsw i32 %sub2, 1
1125eb705d5SSam Parker  %cmp2 = icmp slt i32 0, %sub3
1135eb705d5SSam Parker  br i1 %cmp2, label %inner.ph, label %outer.inc
1145eb705d5SSam Parker
1155eb705d5SSam Parkerinner.ph:
1165eb705d5SSam Parker  br label %inner
1175eb705d5SSam Parker
1185eb705d5SSam Parkerinner:
1195eb705d5SSam Parker  %j = phi i32 [ 0, %inner.ph ], [ %j.inc, %inner ]
1205eb705d5SSam Parker  %j.inc = add nsw i32 %j, 1
1215eb705d5SSam Parker  %cmp3 = icmp slt i32 %j.inc, %sub3
1225eb705d5SSam Parker  br i1 %cmp3, label %inner, label %outer.inc
1235eb705d5SSam Parker
1245eb705d5SSam Parkerouter.inc:
1255eb705d5SSam Parker  %i.inc = add nsw i32 %i, 1
1265eb705d5SSam Parker  %cmp4 = icmp slt i32 %i.inc, %sub1
1275eb705d5SSam Parker  br i1 %cmp4, label %outer, label %exit
1285eb705d5SSam Parker
1295eb705d5SSam Parkerexit:
1305eb705d5SSam Parker  ret void
1315eb705d5SSam Parker}
1325eb705d5SSam Parker
133*3ce360f1SNikita Popovdefine i32 @test1(ptr %array, i32 %length, i32 %n) #0 {
1345eb705d5SSam Parker; CHECK-V8M-LABEL: @test1(
1355eb705d5SSam Parker; CHECK-V8M-NEXT:  loop.preheader:
136b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
137b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
138c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
139c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[LENGTH:%.*]])
140c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[LENGTH]], [[UMIN]]
1415eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[LOOP:%.*]]
1425eb705d5SSam Parker; CHECK-V8M:       loop:
1435eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1445eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
145c8b675eaSNikita Popov; CHECK-V8M-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
1465eb705d5SSam Parker; CHECK-V8M:       deopt:
1475eb705d5SSam Parker; CHECK-V8M-NEXT:    call void @prevent_merging()
1485eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 -1
1495eb705d5SSam Parker; CHECK-V8M:       guarded:
1505eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
151*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
152*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1535eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1545eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1555eb705d5SSam Parker; CHECK-V8M-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1565eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1575eb705d5SSam Parker; CHECK-V8M:       exit:
1585eb705d5SSam Parker; CHECK-V8M-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1595eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 [[RESULT]]
1605eb705d5SSam Parker;
1615eb705d5SSam Parker; CHECK-V8A-LABEL: @test1(
1625eb705d5SSam Parker; CHECK-V8A-NEXT:  loop.preheader:
163b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
164b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
165c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
166c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[LENGTH:%.*]])
167c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[LENGTH]], [[UMIN]]
1685eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[LOOP:%.*]]
1695eb705d5SSam Parker; CHECK-V8A:       loop:
1705eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1715eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
172c8b675eaSNikita Popov; CHECK-V8A-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
1735eb705d5SSam Parker; CHECK-V8A:       deopt:
1745eb705d5SSam Parker; CHECK-V8A-NEXT:    call void @prevent_merging()
1755eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 -1
1765eb705d5SSam Parker; CHECK-V8A:       guarded:
1775eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
178*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
179*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
1805eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1815eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1825eb705d5SSam Parker; CHECK-V8A-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1835eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1845eb705d5SSam Parker; CHECK-V8A:       exit:
1855eb705d5SSam Parker; CHECK-V8A-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1865eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 [[RESULT]]
1875eb705d5SSam Parker;
1885eb705d5SSam Parkerloop.preheader:                                   ; preds = %entry
1895eb705d5SSam Parker  br label %loop
1905eb705d5SSam Parker
1915eb705d5SSam Parkerloop:                                             ; preds = %guarded, %loop.preheader
1925eb705d5SSam Parker  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1935eb705d5SSam Parker  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1945eb705d5SSam Parker  %within.bounds = icmp ult i32 %i, %length
1955eb705d5SSam Parker  br i1 %within.bounds, label %guarded, label %deopt, !prof !0
1965eb705d5SSam Parker
1975eb705d5SSam Parkerdeopt:                                            ; preds = %loop
1985eb705d5SSam Parker  call void @prevent_merging()
1995eb705d5SSam Parker  ret i32 -1
2005eb705d5SSam Parker
2015eb705d5SSam Parkerguarded:                                          ; preds = %loop
2025eb705d5SSam Parker  %i.i64 = zext i32 %i to i64
203*3ce360f1SNikita Popov  %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
204*3ce360f1SNikita Popov  %array.i = load i32, ptr %array.i.ptr, align 4
2055eb705d5SSam Parker  %loop.acc.next = add i32 %loop.acc, %array.i
2065eb705d5SSam Parker  %i.next = add nuw i32 %i, 1
2075eb705d5SSam Parker  %continue = icmp ult i32 %i.next, %n
2085eb705d5SSam Parker  br i1 %continue, label %loop, label %exit
2095eb705d5SSam Parker
2105eb705d5SSam Parkerexit:                                             ; preds = %guarded, %entry
2115eb705d5SSam Parker  %result = phi i32 [ %loop.acc.next, %guarded ]
2125eb705d5SSam Parker  ret i32 %result
2135eb705d5SSam Parker}
2145eb705d5SSam Parker
2155eb705d5SSam Parkerdeclare void @maythrow()
2165eb705d5SSam Parker
217*3ce360f1SNikita Popovdefine i32 @test2(ptr %array, i32 %length, i32 %n) #0 {
2185eb705d5SSam Parker; CHECK-V8M-LABEL: @test2(
2195eb705d5SSam Parker; CHECK-V8M-NEXT:  loop.preheader:
2205eb705d5SSam Parker; CHECK-V8M-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], -1
221c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
222c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[LENGTH:%.*]])
223c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[LENGTH]], [[UMIN]]
2245eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[LOOP:%.*]]
2255eb705d5SSam Parker; CHECK-V8M:       loop:
2265eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
2275eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
228c8b675eaSNikita Popov; CHECK-V8M-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
2295eb705d5SSam Parker; CHECK-V8M:       deopt:
2305eb705d5SSam Parker; CHECK-V8M-NEXT:    call void @prevent_merging()
2315eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 -1
2325eb705d5SSam Parker; CHECK-V8M:       guarded:
2335eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
234*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
235*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
2365eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
2375eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
2385eb705d5SSam Parker; CHECK-V8M-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
2395eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
2405eb705d5SSam Parker; CHECK-V8M:       exit:
2415eb705d5SSam Parker; CHECK-V8M-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
2425eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 [[RESULT]]
2435eb705d5SSam Parker;
2445eb705d5SSam Parker; CHECK-V8A-LABEL: @test2(
2455eb705d5SSam Parker; CHECK-V8A-NEXT:  loop.preheader:
2465eb705d5SSam Parker; CHECK-V8A-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], -1
247c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
248c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[LENGTH:%.*]])
249c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[LENGTH]], [[UMIN]]
2505eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[LOOP:%.*]]
2515eb705d5SSam Parker; CHECK-V8A:       loop:
2525eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
2535eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
254c8b675eaSNikita Popov; CHECK-V8A-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
2555eb705d5SSam Parker; CHECK-V8A:       deopt:
2565eb705d5SSam Parker; CHECK-V8A-NEXT:    call void @prevent_merging()
2575eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 -1
2585eb705d5SSam Parker; CHECK-V8A:       guarded:
2595eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
260*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]
261*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
2625eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
2635eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
2645eb705d5SSam Parker; CHECK-V8A-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
2655eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
2665eb705d5SSam Parker; CHECK-V8A:       exit:
2675eb705d5SSam Parker; CHECK-V8A-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
2685eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 [[RESULT]]
2695eb705d5SSam Parker;
2705eb705d5SSam Parkerloop.preheader:                                   ; preds = %entry
2715eb705d5SSam Parker  br label %loop
2725eb705d5SSam Parker
2735eb705d5SSam Parkerloop:                                             ; preds = %guarded, %loop.preheader
2745eb705d5SSam Parker  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
2755eb705d5SSam Parker  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
2765eb705d5SSam Parker  %within.bounds = icmp ne i32 %i, %length
2775eb705d5SSam Parker  br i1 %within.bounds, label %guarded, label %deopt, !prof !0
2785eb705d5SSam Parker
2795eb705d5SSam Parkerdeopt:                                            ; preds = %loop
2805eb705d5SSam Parker  call void @prevent_merging()
2815eb705d5SSam Parker  ret i32 -1
2825eb705d5SSam Parker
2835eb705d5SSam Parkerguarded:                                          ; preds = %loop
2845eb705d5SSam Parker  %i.i64 = zext i32 %i to i64
285*3ce360f1SNikita Popov  %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64
286*3ce360f1SNikita Popov  %array.i = load i32, ptr %array.i.ptr, align 4
2875eb705d5SSam Parker  %loop.acc.next = add i32 %loop.acc, %array.i
2885eb705d5SSam Parker  %i.next = add nuw i32 %i, 1
2895eb705d5SSam Parker  %continue = icmp ne i32 %i.next, %n
2905eb705d5SSam Parker  br i1 %continue, label %loop, label %exit
2915eb705d5SSam Parker
2925eb705d5SSam Parkerexit:                                             ; preds = %guarded, %entry
2935eb705d5SSam Parker  %result = phi i32 [ %loop.acc.next, %guarded ]
2945eb705d5SSam Parker  ret i32 %result
2955eb705d5SSam Parker}
2965eb705d5SSam Parker
297*3ce360f1SNikita Popovdefine i32 @two_range_checks(ptr %array.1, i32 %length.1, ptr %array.2, i32 %length.2, i32 %n) #0 {
2985eb705d5SSam Parker; CHECK-V8M-LABEL: @two_range_checks(
2995eb705d5SSam Parker; CHECK-V8M-NEXT:  loop.preheader:
300b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_2:%.*]], i32 [[LENGTH_1:%.*]])
301b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
302b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
303c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
304c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[UMIN]])
305c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[UMIN]], [[UMIN1]]
3065eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[LOOP:%.*]]
3075eb705d5SSam Parker; CHECK-V8M:       loop:
3085eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
3095eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
310c8b675eaSNikita Popov; CHECK-V8M-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
3115eb705d5SSam Parker; CHECK-V8M:       deopt:
3125eb705d5SSam Parker; CHECK-V8M-NEXT:    call void @prevent_merging()
3135eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 -1
3145eb705d5SSam Parker; CHECK-V8M:       guarded:
3155eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
316*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
317*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
3185eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
319*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]
320*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4
3215eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
3225eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
3235eb705d5SSam Parker; CHECK-V8M-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
3245eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
3255eb705d5SSam Parker; CHECK-V8M:       exit:
3265eb705d5SSam Parker; CHECK-V8M-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
3275eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 [[RESULT]]
3285eb705d5SSam Parker;
3295eb705d5SSam Parker; CHECK-V8A-LABEL: @two_range_checks(
3305eb705d5SSam Parker; CHECK-V8A-NEXT:  loop.preheader:
331b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_2:%.*]], i32 [[LENGTH_1:%.*]])
332b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
333b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
334c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
335c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[UMIN]])
336c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[UMIN]], [[UMIN1]]
3375eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[LOOP:%.*]]
3385eb705d5SSam Parker; CHECK-V8A:       loop:
3395eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
3405eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
341c8b675eaSNikita Popov; CHECK-V8A-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
3425eb705d5SSam Parker; CHECK-V8A:       deopt:
3435eb705d5SSam Parker; CHECK-V8A-NEXT:    call void @prevent_merging()
3445eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 -1
3455eb705d5SSam Parker; CHECK-V8A:       guarded:
3465eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
347*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
348*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
3495eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
350*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]
351*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4
3525eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
3535eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
3545eb705d5SSam Parker; CHECK-V8A-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
3555eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
3565eb705d5SSam Parker; CHECK-V8A:       exit:
3575eb705d5SSam Parker; CHECK-V8A-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
3585eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 [[RESULT]]
3595eb705d5SSam Parker;
3605eb705d5SSam Parkerloop.preheader:                                   ; preds = %entry
3615eb705d5SSam Parker  br label %loop
3625eb705d5SSam Parker
3635eb705d5SSam Parkerloop:                                             ; preds = %guarded, %loop.preheader
3645eb705d5SSam Parker  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
3655eb705d5SSam Parker  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
3665eb705d5SSam Parker  %within.bounds.1 = icmp ult i32 %i, %length.1
3675eb705d5SSam Parker  %within.bounds.2 = icmp ult i32 %i, %length.2
3685eb705d5SSam Parker  %within.bounds = and i1 %within.bounds.1, %within.bounds.2
3695eb705d5SSam Parker  br i1 %within.bounds, label %guarded, label %deopt, !prof !0
3705eb705d5SSam Parker
3715eb705d5SSam Parkerdeopt:                                            ; preds = %loop
3725eb705d5SSam Parker  call void @prevent_merging()
3735eb705d5SSam Parker  ret i32 -1
3745eb705d5SSam Parker
3755eb705d5SSam Parkerguarded:                                          ; preds = %loop
3765eb705d5SSam Parker  %i.i64 = zext i32 %i to i64
377*3ce360f1SNikita Popov  %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64
378*3ce360f1SNikita Popov  %array.1.i = load i32, ptr %array.1.i.ptr, align 4
3795eb705d5SSam Parker  %loop.acc.1 = add i32 %loop.acc, %array.1.i
380*3ce360f1SNikita Popov  %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i64
381*3ce360f1SNikita Popov  %array.2.i = load i32, ptr %array.2.i.ptr, align 4
3825eb705d5SSam Parker  %loop.acc.next = add i32 %loop.acc.1, %array.2.i
3835eb705d5SSam Parker  %i.next = add nuw i32 %i, 1
3845eb705d5SSam Parker  %continue = icmp ult i32 %i.next, %n
3855eb705d5SSam Parker  br i1 %continue, label %loop, label %exit
3865eb705d5SSam Parker
3875eb705d5SSam Parkerexit:                                             ; preds = %guarded, %entry
3885eb705d5SSam Parker  %result = phi i32 [ %loop.acc.next, %guarded ]
3895eb705d5SSam Parker  ret i32 %result
3905eb705d5SSam Parker}
3915eb705d5SSam Parker
392*3ce360f1SNikita Popovdefine i32 @three_range_checks(ptr %array.1, i32 %length.1, ptr %array.2, i32 %length.2, ptr %array.3, i32 %length.3, i32 %n) #0 {
3935eb705d5SSam Parker; CHECK-V8M-LABEL: @three_range_checks(
3945eb705d5SSam Parker; CHECK-V8M-NEXT:  loop.preheader:
395b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_3:%.*]], i32 [[LENGTH_2:%.*]])
396b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[LENGTH_1:%.*]])
397b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
398b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
399c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
400c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[UMIN2:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[UMIN1]])
401c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[UMIN1]], [[UMIN2]]
4025eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[LOOP:%.*]]
4035eb705d5SSam Parker; CHECK-V8M:       loop:
4045eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
4055eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
406c8b675eaSNikita Popov; CHECK-V8M-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
4075eb705d5SSam Parker; CHECK-V8M:       deopt:
4085eb705d5SSam Parker; CHECK-V8M-NEXT:    call void @prevent_merging()
4095eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 -1
4105eb705d5SSam Parker; CHECK-V8M:       guarded:
4115eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
412*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
413*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
4145eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
415*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]
416*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4
4175eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
418*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]
419*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4
4205eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
4215eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
4225eb705d5SSam Parker; CHECK-V8M-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
4235eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
4245eb705d5SSam Parker; CHECK-V8M:       exit:
4255eb705d5SSam Parker; CHECK-V8M-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
4265eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 [[RESULT]]
4275eb705d5SSam Parker;
4285eb705d5SSam Parker; CHECK-V8A-LABEL: @three_range_checks(
4295eb705d5SSam Parker; CHECK-V8A-NEXT:  loop.preheader:
430b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_3:%.*]], i32 [[LENGTH_2:%.*]])
431b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[LENGTH_1:%.*]])
432b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
433b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
434c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
435c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[UMIN2:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[UMIN1]])
436c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[UMIN1]], [[UMIN2]]
4375eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[LOOP:%.*]]
4385eb705d5SSam Parker; CHECK-V8A:       loop:
4395eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
4405eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
441c8b675eaSNikita Popov; CHECK-V8A-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
4425eb705d5SSam Parker; CHECK-V8A:       deopt:
4435eb705d5SSam Parker; CHECK-V8A-NEXT:    call void @prevent_merging()
4445eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 -1
4455eb705d5SSam Parker; CHECK-V8A:       guarded:
4465eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
447*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
448*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
4495eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
450*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]]
451*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4
4525eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
453*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]
454*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4
4555eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
4565eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
4575eb705d5SSam Parker; CHECK-V8A-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
4585eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
4595eb705d5SSam Parker; CHECK-V8A:       exit:
4605eb705d5SSam Parker; CHECK-V8A-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
4615eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 [[RESULT]]
4625eb705d5SSam Parker;
4635eb705d5SSam Parkerloop.preheader:                                   ; preds = %entry
4645eb705d5SSam Parker  br label %loop
4655eb705d5SSam Parker
4665eb705d5SSam Parkerloop:                                             ; preds = %guarded, %loop.preheader
4675eb705d5SSam Parker  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
4685eb705d5SSam Parker  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
4695eb705d5SSam Parker  %within.bounds.1 = icmp ult i32 %i, %length.1
4705eb705d5SSam Parker  %within.bounds.2 = icmp ult i32 %i, %length.2
4715eb705d5SSam Parker  %within.bounds.3 = icmp ult i32 %i, %length.3
4725eb705d5SSam Parker  %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2
4735eb705d5SSam Parker  %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3
4745eb705d5SSam Parker  br i1 %within.bounds, label %guarded, label %deopt, !prof !0
4755eb705d5SSam Parker
4765eb705d5SSam Parkerdeopt:                                            ; preds = %loop
4775eb705d5SSam Parker  call void @prevent_merging()
4785eb705d5SSam Parker  ret i32 -1
4795eb705d5SSam Parker
4805eb705d5SSam Parkerguarded:                                          ; preds = %loop
4815eb705d5SSam Parker  %i.i64 = zext i32 %i to i64
482*3ce360f1SNikita Popov  %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64
483*3ce360f1SNikita Popov  %array.1.i = load i32, ptr %array.1.i.ptr, align 4
4845eb705d5SSam Parker  %loop.acc.1 = add i32 %loop.acc, %array.1.i
485*3ce360f1SNikita Popov  %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i64
486*3ce360f1SNikita Popov  %array.2.i = load i32, ptr %array.2.i.ptr, align 4
4875eb705d5SSam Parker  %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
488*3ce360f1SNikita Popov  %array.3.i.ptr = getelementptr inbounds i32, ptr %array.3, i64 %i.i64
489*3ce360f1SNikita Popov  %array.3.i = load i32, ptr %array.3.i.ptr, align 4
4905eb705d5SSam Parker  %loop.acc.next = add i32 %loop.acc.2, %array.3.i
4915eb705d5SSam Parker  %i.next = add nuw i32 %i, 1
4925eb705d5SSam Parker  %continue = icmp ult i32 %i.next, %n
4935eb705d5SSam Parker  br i1 %continue, label %loop, label %exit
4945eb705d5SSam Parker
4955eb705d5SSam Parkerexit:                                             ; preds = %guarded, %entry
4965eb705d5SSam Parker  %result = phi i32 [ %loop.acc.next, %guarded ]
4975eb705d5SSam Parker  ret i32 %result
4985eb705d5SSam Parker}
4995eb705d5SSam Parker
5005eb705d5SSam Parker; Analogous to the above, but with two distinct branches (on different conditions)
501*3ce360f1SNikita Popovdefine i32 @distinct_checks(ptr %array.1, i32 %length.1, ptr %array.2, i32 %length.2, ptr %array.3, i32 %length.3, i32 %n) #0 {
5025eb705d5SSam Parker; CHECK-V8M-LABEL: @distinct_checks(
5035eb705d5SSam Parker; CHECK-V8M-NEXT:  loop.preheader:
504b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
505b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
506c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
507c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP2:%.*]] = freeze i32 [[LENGTH_2:%.*]]
508c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[TMP2]])
509c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[LENGTH_1:%.*]])
510c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[LENGTH_1]], [[UMIN1]]
511c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[LENGTH_2]], [[UMIN1]]
5125eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[LOOP:%.*]]
5135eb705d5SSam Parker; CHECK-V8M:       loop:
5145eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED1:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
5155eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED1]] ], [ 0, [[LOOP_PREHEADER]] ]
516c8b675eaSNikita Popov; CHECK-V8M-NEXT:    br i1 [[TMP3]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
5175eb705d5SSam Parker; CHECK-V8M:       deopt:
5185eb705d5SSam Parker; CHECK-V8M-NEXT:    call void @prevent_merging()
5195eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 -1
5205eb705d5SSam Parker; CHECK-V8M:       guarded:
5215eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
522*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
523*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
5245eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
525c8b675eaSNikita Popov; CHECK-V8M-NEXT:    br i1 [[TMP4]], label [[GUARDED1]], label [[DEOPT2:%.*]], !prof [[PROF0]]
5265eb705d5SSam Parker; CHECK-V8M:       deopt2:
5275eb705d5SSam Parker; CHECK-V8M-NEXT:    call void @prevent_merging()
5285eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 -1
5295eb705d5SSam Parker; CHECK-V8M:       guarded1:
530*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]
531*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4
5325eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_3_I]]
5335eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
5345eb705d5SSam Parker; CHECK-V8M-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
5355eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
5365eb705d5SSam Parker; CHECK-V8M:       exit:
5375eb705d5SSam Parker; CHECK-V8M-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED1]] ]
5385eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 [[RESULT]]
5395eb705d5SSam Parker;
5405eb705d5SSam Parker; CHECK-V8A-LABEL: @distinct_checks(
5415eb705d5SSam Parker; CHECK-V8A-NEXT:  loop.preheader:
542b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
543b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
544c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
545c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP2:%.*]] = freeze i32 [[LENGTH_2:%.*]]
546c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[TMP2]])
547c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[LENGTH_1:%.*]])
548c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[LENGTH_1]], [[UMIN1]]
549c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[LENGTH_2]], [[UMIN1]]
5505eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[LOOP:%.*]]
5515eb705d5SSam Parker; CHECK-V8A:       loop:
5525eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED1:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
5535eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED1]] ], [ 0, [[LOOP_PREHEADER]] ]
554c8b675eaSNikita Popov; CHECK-V8A-NEXT:    br i1 [[TMP3]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
5555eb705d5SSam Parker; CHECK-V8A:       deopt:
5565eb705d5SSam Parker; CHECK-V8A-NEXT:    call void @prevent_merging()
5575eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 -1
5585eb705d5SSam Parker; CHECK-V8A:       guarded:
5595eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
560*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
561*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
5625eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
563c8b675eaSNikita Popov; CHECK-V8A-NEXT:    br i1 [[TMP4]], label [[GUARDED1]], label [[DEOPT2:%.*]], !prof [[PROF0]]
5645eb705d5SSam Parker; CHECK-V8A:       deopt2:
5655eb705d5SSam Parker; CHECK-V8A-NEXT:    call void @prevent_merging()
5665eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 -1
5675eb705d5SSam Parker; CHECK-V8A:       guarded1:
568*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]
569*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4
5705eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_3_I]]
5715eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
5725eb705d5SSam Parker; CHECK-V8A-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
5735eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
5745eb705d5SSam Parker; CHECK-V8A:       exit:
5755eb705d5SSam Parker; CHECK-V8A-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED1]] ]
5765eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 [[RESULT]]
5775eb705d5SSam Parker;
5785eb705d5SSam Parkerloop.preheader:                                   ; preds = %entry
5795eb705d5SSam Parker  br label %loop
5805eb705d5SSam Parker
5815eb705d5SSam Parkerloop:                                             ; preds = %guarded4, %loop.preheader
5825eb705d5SSam Parker  %loop.acc = phi i32 [ %loop.acc.next, %guarded1 ], [ 0, %loop.preheader ]
5835eb705d5SSam Parker  %i = phi i32 [ %i.next, %guarded1 ], [ 0, %loop.preheader ]
5845eb705d5SSam Parker  %within.bounds.1 = icmp ult i32 %i, %length.1
5855eb705d5SSam Parker  br i1 %within.bounds.1, label %guarded, label %deopt, !prof !0
5865eb705d5SSam Parker
5875eb705d5SSam Parkerdeopt:                                            ; preds = %loop
5885eb705d5SSam Parker  call void @prevent_merging()
5895eb705d5SSam Parker  ret i32 -1
5905eb705d5SSam Parker
5915eb705d5SSam Parkerguarded:                                          ; preds = %loop
5925eb705d5SSam Parker  %i.i64 = zext i32 %i to i64
593*3ce360f1SNikita Popov  %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64
594*3ce360f1SNikita Popov  %array.1.i = load i32, ptr %array.1.i.ptr, align 4
5955eb705d5SSam Parker  %loop.acc.1 = add i32 %loop.acc, %array.1.i
5965eb705d5SSam Parker  %within.bounds.2 = icmp ult i32 %i, %length.2
5975eb705d5SSam Parker  br i1 %within.bounds.2, label %guarded1, label %deopt2, !prof !0
5985eb705d5SSam Parker
5995eb705d5SSam Parkerdeopt2:                                           ; preds = %guarded
6005eb705d5SSam Parker  call void @prevent_merging()
6015eb705d5SSam Parker  ret i32 -1
6025eb705d5SSam Parker
6035eb705d5SSam Parkerguarded1:                                         ; preds = %guarded1
604*3ce360f1SNikita Popov  %array.3.i.ptr = getelementptr inbounds i32, ptr %array.3, i64 %i.i64
605*3ce360f1SNikita Popov  %array.3.i = load i32, ptr %array.3.i.ptr, align 4
6065eb705d5SSam Parker  %loop.acc.next = add i32 %loop.acc.1, %array.3.i
6075eb705d5SSam Parker  %i.next = add nuw i32 %i, 1
6085eb705d5SSam Parker  %continue = icmp ult i32 %i.next, %n
6095eb705d5SSam Parker  br i1 %continue, label %loop, label %exit
6105eb705d5SSam Parker
6115eb705d5SSam Parkerexit:
6125eb705d5SSam Parker  %result = phi i32 [ %loop.acc.next, %guarded1 ]
6135eb705d5SSam Parker  ret i32 %result
6145eb705d5SSam Parker}
6155eb705d5SSam Parker
616*3ce360f1SNikita Popovdefine i32 @duplicate_checks(ptr %array.1, ptr %array.2, ptr %array.3, i32 %length, i32 %n) #0 {
6175eb705d5SSam Parker; CHECK-V8M-LABEL: @duplicate_checks(
6185eb705d5SSam Parker; CHECK-V8M-NEXT:  loop.preheader:
619b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
620b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
621c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
622c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[LENGTH:%.*]])
623c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[LENGTH]], [[UMIN]]
6245eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[LOOP:%.*]]
6255eb705d5SSam Parker; CHECK-V8M:       loop:
6265eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED1:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
6275eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED1]] ], [ 0, [[LOOP_PREHEADER]] ]
628c8b675eaSNikita Popov; CHECK-V8M-NEXT:    br i1 [[TMP2]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
6295eb705d5SSam Parker; CHECK-V8M:       deopt:
6305eb705d5SSam Parker; CHECK-V8M-NEXT:    call void @prevent_merging()
6315eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 -1
6325eb705d5SSam Parker; CHECK-V8M:       guarded:
6335eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
634*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
635*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
6365eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
637c8b675eaSNikita Popov; CHECK-V8M-NEXT:    br i1 true, label [[GUARDED1]], label [[DEOPT2:%.*]], !prof [[PROF0]]
6385eb705d5SSam Parker; CHECK-V8M:       deopt2:
6395eb705d5SSam Parker; CHECK-V8M-NEXT:    call void @prevent_merging()
6405eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 -1
6415eb705d5SSam Parker; CHECK-V8M:       guarded1:
642*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]
643*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4
6445eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_3_I]]
6455eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
6465eb705d5SSam Parker; CHECK-V8M-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
6475eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
6485eb705d5SSam Parker; CHECK-V8M:       exit:
6495eb705d5SSam Parker; CHECK-V8M-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED1]] ]
6505eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 [[RESULT]]
6515eb705d5SSam Parker;
6525eb705d5SSam Parker; CHECK-V8A-LABEL: @duplicate_checks(
6535eb705d5SSam Parker; CHECK-V8A-NEXT:  loop.preheader:
654b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
655b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
656c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP1:%.*]] = freeze i32 [[TMP0]]
657c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[LENGTH:%.*]])
658c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[LENGTH]], [[UMIN]]
6595eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[LOOP:%.*]]
6605eb705d5SSam Parker; CHECK-V8A:       loop:
6615eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED1:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
6625eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED1]] ], [ 0, [[LOOP_PREHEADER]] ]
663c8b675eaSNikita Popov; CHECK-V8A-NEXT:    br i1 [[TMP2]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
6645eb705d5SSam Parker; CHECK-V8A:       deopt:
6655eb705d5SSam Parker; CHECK-V8A-NEXT:    call void @prevent_merging()
6665eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 -1
6675eb705d5SSam Parker; CHECK-V8A:       guarded:
6685eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
669*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]]
670*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4
6715eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
672c8b675eaSNikita Popov; CHECK-V8A-NEXT:    br i1 true, label [[GUARDED1]], label [[DEOPT2:%.*]], !prof [[PROF0]]
6735eb705d5SSam Parker; CHECK-V8A:       deopt2:
6745eb705d5SSam Parker; CHECK-V8A-NEXT:    call void @prevent_merging()
6755eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 -1
6765eb705d5SSam Parker; CHECK-V8A:       guarded1:
677*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]]
678*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4
6795eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_3_I]]
6805eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
6815eb705d5SSam Parker; CHECK-V8A-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
6825eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
6835eb705d5SSam Parker; CHECK-V8A:       exit:
6845eb705d5SSam Parker; CHECK-V8A-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED1]] ]
6855eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 [[RESULT]]
6865eb705d5SSam Parker;
6875eb705d5SSam Parkerloop.preheader:                                   ; preds = %entry
6885eb705d5SSam Parker  br label %loop
6895eb705d5SSam Parker
6905eb705d5SSam Parkerloop:                                             ; preds = %guarded4, %loop.preheader
6915eb705d5SSam Parker  %loop.acc = phi i32 [ %loop.acc.next, %guarded1 ], [ 0, %loop.preheader ]
6925eb705d5SSam Parker  %i = phi i32 [ %i.next, %guarded1 ], [ 0, %loop.preheader ]
6935eb705d5SSam Parker  %within.bounds.1 = icmp ult i32 %i, %length
6945eb705d5SSam Parker  br i1 %within.bounds.1, label %guarded, label %deopt, !prof !0
6955eb705d5SSam Parker
6965eb705d5SSam Parkerdeopt:                                            ; preds = %loop
6975eb705d5SSam Parker  call void @prevent_merging()
6985eb705d5SSam Parker  ret i32 -1
6995eb705d5SSam Parker
7005eb705d5SSam Parkerguarded:                                          ; preds = %loop
7015eb705d5SSam Parker  %i.i64 = zext i32 %i to i64
702*3ce360f1SNikita Popov  %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64
703*3ce360f1SNikita Popov  %array.1.i = load i32, ptr %array.1.i.ptr, align 4
7045eb705d5SSam Parker  %loop.acc.1 = add i32 %loop.acc, %array.1.i
7055eb705d5SSam Parker  %within.bounds.2 = icmp ult i32 %i, %length
7065eb705d5SSam Parker  br i1 %within.bounds.2, label %guarded1, label %deopt2, !prof !0
7075eb705d5SSam Parker
7085eb705d5SSam Parkerdeopt2:                                           ; preds = %guarded
7095eb705d5SSam Parker  call void @prevent_merging()
7105eb705d5SSam Parker  ret i32 -1
7115eb705d5SSam Parker
7125eb705d5SSam Parkerguarded1:                                         ; preds = %guarded1
713*3ce360f1SNikita Popov  %array.3.i.ptr = getelementptr inbounds i32, ptr %array.3, i64 %i.i64
714*3ce360f1SNikita Popov  %array.3.i = load i32, ptr %array.3.i.ptr, align 4
7155eb705d5SSam Parker  %loop.acc.next = add i32 %loop.acc.1, %array.3.i
7165eb705d5SSam Parker  %i.next = add nuw i32 %i, 1
7175eb705d5SSam Parker  %continue = icmp ult i32 %i.next, %n
7185eb705d5SSam Parker  br i1 %continue, label %loop, label %exit
7195eb705d5SSam Parker
7205eb705d5SSam Parkerexit:
7215eb705d5SSam Parker  %result = phi i32 [ %loop.acc.next, %guarded1 ]
7225eb705d5SSam Parker  ret i32 %result
7235eb705d5SSam Parker}
7245eb705d5SSam Parker
7255eb705d5SSam Parker; Demonstrate that this approach works with IVs of different steps, and types
7265eb705d5SSam Parker; This version uses a manually lftred exit condition to work around an issue described
7275eb705d5SSam Parker; in detail on next test.
728*3ce360f1SNikita Popovdefine i32 @different_ivs(ptr %array, i32 %length, i32 %n) #0 {
7295eb705d5SSam Parker; CHECK-V8M-LABEL: @different_ivs(
7305eb705d5SSam Parker; CHECK-V8M-NEXT:  loop.preheader:
7315eb705d5SSam Parker; CHECK-V8M-NEXT:    [[N64:%.*]] = zext i32 [[N:%.*]] to i64
732b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[N64]], i64 1)
733b46c085dSRoman Lebedev; CHECK-V8M-NEXT:    [[TMP0:%.*]] = add nsw i64 [[UMAX]], -1
734c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP1:%.*]] = freeze i64 [[TMP0]]
735c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP2:%.*]] = zext i32 [[LENGTH:%.*]] to i64
736c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP1]], i64 [[TMP2]])
737c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP3:%.*]] = zext i32 [[LENGTH]] to i64
738c8b675eaSNikita Popov; CHECK-V8M-NEXT:    [[TMP4:%.*]] = icmp ne i64 [[TMP3]], [[UMIN]]
7395eb705d5SSam Parker; CHECK-V8M-NEXT:    br label [[LOOP:%.*]]
7405eb705d5SSam Parker; CHECK-V8M:       loop:
7415eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
7425eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
743c8b675eaSNikita Popov; CHECK-V8M-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
7445eb705d5SSam Parker; CHECK-V8M:       deopt:
7455eb705d5SSam Parker; CHECK-V8M-NEXT:    call void @prevent_merging()
7465eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 -1
7475eb705d5SSam Parker; CHECK-V8M:       guarded:
748*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I]]
749*3ce360f1SNikita Popov; CHECK-V8M-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
7505eb705d5SSam Parker; CHECK-V8M-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
7515eb705d5SSam Parker; CHECK-V8M-NEXT:    [[I_NEXT]] = add nuw nsw i64 [[I]], 1
7525eb705d5SSam Parker; CHECK-V8M-NEXT:    [[CONTINUE:%.*]] = icmp ult i64 [[I_NEXT]], [[N64]]
7535eb705d5SSam Parker; CHECK-V8M-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
7545eb705d5SSam Parker; CHECK-V8M:       exit:
7555eb705d5SSam Parker; CHECK-V8M-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
7565eb705d5SSam Parker; CHECK-V8M-NEXT:    ret i32 [[RESULT]]
7575eb705d5SSam Parker;
7585eb705d5SSam Parker; CHECK-V8A-LABEL: @different_ivs(
7595eb705d5SSam Parker; CHECK-V8A-NEXT:  loop.preheader:
7605eb705d5SSam Parker; CHECK-V8A-NEXT:    [[N64:%.*]] = zext i32 [[N:%.*]] to i64
761b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[N64]], i64 1)
762b46c085dSRoman Lebedev; CHECK-V8A-NEXT:    [[TMP0:%.*]] = add nsw i64 [[UMAX]], -1
763c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP1:%.*]] = freeze i64 [[TMP0]]
764c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP2:%.*]] = zext i32 [[LENGTH:%.*]] to i64
765c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP1]], i64 [[TMP2]])
766c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP3:%.*]] = zext i32 [[LENGTH]] to i64
767c8b675eaSNikita Popov; CHECK-V8A-NEXT:    [[TMP4:%.*]] = icmp ne i64 [[TMP3]], [[UMIN]]
7685eb705d5SSam Parker; CHECK-V8A-NEXT:    br label [[LOOP:%.*]]
7695eb705d5SSam Parker; CHECK-V8A:       loop:
7705eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
7715eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
772c8b675eaSNikita Popov; CHECK-V8A-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
7735eb705d5SSam Parker; CHECK-V8A:       deopt:
7745eb705d5SSam Parker; CHECK-V8A-NEXT:    call void @prevent_merging()
7755eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 -1
7765eb705d5SSam Parker; CHECK-V8A:       guarded:
777*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I]]
778*3ce360f1SNikita Popov; CHECK-V8A-NEXT:    [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
7795eb705d5SSam Parker; CHECK-V8A-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
7805eb705d5SSam Parker; CHECK-V8A-NEXT:    [[I_NEXT]] = add nuw nsw i64 [[I]], 1
7815eb705d5SSam Parker; CHECK-V8A-NEXT:    [[CONTINUE:%.*]] = icmp ult i64 [[I_NEXT]], [[N64]]
7825eb705d5SSam Parker; CHECK-V8A-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
7835eb705d5SSam Parker; CHECK-V8A:       exit:
7845eb705d5SSam Parker; CHECK-V8A-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
7855eb705d5SSam Parker; CHECK-V8A-NEXT:    ret i32 [[RESULT]]
7865eb705d5SSam Parker;
7875eb705d5SSam Parkerloop.preheader:
7885eb705d5SSam Parker  %j.start = sub nuw nsw i32 %length, 1
7895eb705d5SSam Parker  %n64 = zext i32 %n to i64
7905eb705d5SSam Parker  br label %loop
7915eb705d5SSam Parker
7925eb705d5SSam Parkerloop:
7935eb705d5SSam Parker  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
7945eb705d5SSam Parker  %i = phi i64 [ %i.next, %guarded ], [ 0, %loop.preheader ]
7955eb705d5SSam Parker  %j = phi i32 [ %j.next, %guarded ], [ %j.start, %loop.preheader ]
7965eb705d5SSam Parker  %within.bounds = icmp ne i32 %j, -1
7975eb705d5SSam Parker  br i1 %within.bounds, label %guarded, label %deopt, !prof !0
7985eb705d5SSam Parker
7995eb705d5SSam Parkerdeopt:
8005eb705d5SSam Parker  call void @prevent_merging()
8015eb705d5SSam Parker  ret i32 -1
8025eb705d5SSam Parker
8035eb705d5SSam Parkerguarded:
804*3ce360f1SNikita Popov  %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i
805*3ce360f1SNikita Popov  %array.i = load i32, ptr %array.i.ptr, align 4
8065eb705d5SSam Parker  %loop.acc.next = add i32 %loop.acc, %array.i
8075eb705d5SSam Parker  %i.next = add nuw i64 %i, 1
8085eb705d5SSam Parker  %j.next = sub nuw i32 %j, 1
8095eb705d5SSam Parker  %continue = icmp ult i64 %i.next, %n64
8105eb705d5SSam Parker  br i1 %continue, label %loop, label %exit
8115eb705d5SSam Parker
8125eb705d5SSam Parkerexit:
8135eb705d5SSam Parker  %result = phi i32 [ %loop.acc.next, %guarded ]
8145eb705d5SSam Parker  ret i32 %result
8155eb705d5SSam Parker}
8165eb705d5SSam Parker
8175eb705d5SSam Parkerdeclare void @prevent_merging()
8185eb705d5SSam Parkerdeclare void @call()
8195eb705d5SSam Parker
8205eb705d5SSam Parker!0 = !{!"branch_weights", i32 1048576, i32 1}
8215eb705d5SSam Parker!1 = !{i32 1, i32 -2147483648}
8225eb705d5SSam Parker!2 = !{i32 0, i32 50}
8235eb705d5SSam Parker
8245eb705d5SSam Parkerattributes #0 = { minsize optsize }
825