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