1144 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=loop-predication -S | FileCheck %s3; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s4 5declare void @prevent_merging()6 7; Base case - with side effects in loop8define i32 @test1(ptr %array, i32 %length, i32 %n, i1 %cond_0) {9; CHECK-LABEL: @test1(10; CHECK-NEXT: entry:11; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()12; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)13; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -114; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])15; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]16; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]17; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]18; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]19; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]20; CHECK: deopt:21; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]22; CHECK-NEXT: ret i32 [[DEOPTRET]]23; CHECK: loop.preheader:24; CHECK-NEXT: br label [[LOOP:%.*]]25; CHECK: loop:26; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]27; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]28; CHECK-NEXT: call void @unknown()29; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]30; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]31; CHECK: deopt2:32; CHECK-NEXT: call void @unknown()33; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]34; CHECK-NEXT: ret i32 [[DEOPTRET2]]35; CHECK: guarded:36; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i6437; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]38; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 439; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 440; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]41; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 142; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]43; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]44; CHECK: exit:45; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]46; CHECK-NEXT: ret i32 [[RESULT]]47;48entry:49 %widenable_cond = call i1 @llvm.experimental.widenable.condition()50 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond51 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !052 53deopt:54 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]55 ret i32 %deoptret56 57loop.preheader:58 br label %loop59 60loop:61 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]62 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]63 call void @unknown()64 %within.bounds = icmp ult i32 %i, %length65 br i1 %within.bounds, label %guarded, label %deopt2, !prof !066 67deopt2:68 call void @unknown()69 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]70 ret i32 %deoptret271 72guarded:73 %i.i64 = zext i32 %i to i6474 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i6475 %array.i = load i32, ptr %array.i.ptr, align 476 store i32 0, ptr %array.i.ptr77 %loop.acc.next = add i32 %loop.acc, %array.i78 %i.next = add nuw i32 %i, 179 %continue = icmp ult i32 %i.next, %n80 br i1 %continue, label %loop, label %exit81 82exit:83 %result = phi i32 [ %loop.acc.next, %guarded ]84 ret i32 %result85}86 87 88 89define i32 @test_non_canonical(ptr %array, i32 %length, i1 %cond_0) {90; CHECK-LABEL: @test_non_canonical(91; CHECK-NEXT: entry:92; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()93; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LENGTH:%.*]], i32 1)94; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -195; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH]], i32 [[TMP0]])96; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]97; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]98; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]99; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]100; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]101; CHECK: deopt:102; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]103; CHECK-NEXT: ret i32 [[DEOPTRET]]104; CHECK: loop.preheader:105; CHECK-NEXT: br label [[LOOP:%.*]]106; CHECK: loop:107; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]108; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]109; CHECK-NEXT: call void @unknown()110; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]111; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]112; CHECK: deopt2:113; CHECK-NEXT: call void @unknown()114; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]115; CHECK-NEXT: ret i32 [[DEOPTRET2]]116; CHECK: guarded:117; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64118; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]119; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4120; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4121; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]122; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1123; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]124; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]125; CHECK: exit:126; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]127; CHECK-NEXT: ret i32 [[RESULT]]128;129entry:130 %widenable_cond = call i1 @llvm.experimental.widenable.condition()131 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond132 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0133 134deopt:135 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]136 ret i32 %deoptret137 138loop.preheader:139 br label %loop140 141loop:142 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]143 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]144 call void @unknown()145 %within.bounds = icmp ult i32 %i, %length146 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0147 148deopt2:149 call void @unknown()150 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]151 ret i32 %deoptret2152 153guarded:154 %i.i64 = zext i32 %i to i64155 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64156 %array.i = load i32, ptr %array.i.ptr, align 4157 store i32 0, ptr %array.i.ptr158 %loop.acc.next = add i32 %loop.acc, %array.i159 %i.next = add nuw i32 %i, 1160 %continue = icmp ult i32 %i.next, %length161 br i1 %continue, label %loop, label %exit162 163exit:164 %result = phi i32 [ %loop.acc.next, %guarded ]165 ret i32 %result166}167 168 169define i32 @test_two_range_checks(ptr %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) {170; CHECK-LABEL: @test_two_range_checks(171; CHECK-NEXT: entry:172; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()173; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_2:%.*]], i32 [[LENGTH_1:%.*]])174; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)175; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1176; CHECK-NEXT: [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[TMP0]])177; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]]178; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]179; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]180; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]]181; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]]182; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]]183; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]184; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]185; CHECK: deopt:186; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]187; CHECK-NEXT: ret i32 [[DEOPTRET]]188; CHECK: loop.preheader:189; CHECK-NEXT: br label [[LOOP:%.*]]190; CHECK: loop:191; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]192; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]193; CHECK-NEXT: call void @unknown()194; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]195; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]196; CHECK: deopt2:197; CHECK-NEXT: call void @unknown()198; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]199; CHECK-NEXT: ret i32 [[DEOPTRET2]]200; CHECK: guarded:201; CHECK-NEXT: [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]202; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof [[PROF0]]203; CHECK: deopt3:204; CHECK-NEXT: call void @unknown()205; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]206; CHECK-NEXT: ret i32 [[DEOPTRET3]]207; CHECK: guarded2:208; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64209; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]210; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4211; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4212; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]213; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1214; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]215; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]216; CHECK: exit:217; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]218; CHECK-NEXT: ret i32 [[RESULT]]219;220entry:221 %widenable_cond = call i1 @llvm.experimental.widenable.condition()222 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond223 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0224 225deopt:226 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]227 ret i32 %deoptret228 229loop.preheader:230 br label %loop231 232loop:233 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]234 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]235 call void @unknown()236 %within.bounds = icmp ult i32 %i, %length.1237 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0238 239deopt2:240 call void @unknown()241 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]242 ret i32 %deoptret2243 244guarded:245 %within.bounds2 = icmp ult i32 %i, %length.2246 br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0247 248deopt3:249 call void @unknown()250 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]251 ret i32 %deoptret3252 253guarded2:254 %i.i64 = zext i32 %i to i64255 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64256 %array.i = load i32, ptr %array.i.ptr, align 4257 store i32 0, ptr %array.i.ptr258 %loop.acc.next = add i32 %loop.acc, %array.i259 %i.next = add nuw i32 %i, 1260 %continue = icmp ult i32 %i.next, %n261 br i1 %continue, label %loop, label %exit262 263exit:264 %result = phi i32 [ %loop.acc.next, %guarded2 ]265 ret i32 %result266}267 268@G = external global i32269 270define i32 @test_unanalyzeable_exit(ptr %array, i32 %length, i32 %n, i1 %cond_0) {271; CHECK-LABEL: @test_unanalyzeable_exit(272; CHECK-NEXT: entry:273; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()274; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]275; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]276; CHECK: deopt:277; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]278; CHECK-NEXT: ret i32 [[DEOPTRET]]279; CHECK: loop.preheader:280; CHECK-NEXT: br label [[LOOP:%.*]]281; CHECK: loop:282; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]283; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]284; CHECK-NEXT: call void @unknown()285; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, ptr @G, align 4286; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0287; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof [[PROF0]]288; CHECK: deopt3:289; CHECK-NEXT: call void @unknown()290; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]291; CHECK-NEXT: ret i32 [[DEOPTRET3]]292; CHECK: guarded2:293; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64294; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]295; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4296; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4297; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]298; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1299; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N:%.*]]300; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]301; CHECK: exit:302; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]303; CHECK-NEXT: ret i32 [[RESULT]]304;305entry:306 %widenable_cond = call i1 @llvm.experimental.widenable.condition()307 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond308 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0309 310deopt:311 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]312 ret i32 %deoptret313 314loop.preheader:315 br label %loop316 317loop:318 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]319 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]320 call void @unknown()321 %vol = load volatile i32, ptr @G322 %unknown = icmp eq i32 %vol, 0323 br i1 %unknown, label %guarded2, label %deopt3, !prof !0324 325deopt3:326 call void @unknown()327 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]328 ret i32 %deoptret3329 330guarded2:331 %i.i64 = zext i32 %i to i64332 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64333 %array.i = load i32, ptr %array.i.ptr, align 4334 store i32 0, ptr %array.i.ptr335 %loop.acc.next = add i32 %loop.acc, %array.i336 %i.next = add nuw i32 %i, 1337 %continue = icmp ult i32 %i.next, %n338 br i1 %continue, label %loop, label %exit339 340exit:341 %result = phi i32 [ %loop.acc.next, %guarded2 ]342 ret i32 %result343}344 345define i32 @test_unanalyzeable_exit2(ptr %array, i32 %length, i32 %n, i1 %cond_0) {346; CHECK-LABEL: @test_unanalyzeable_exit2(347; CHECK-NEXT: entry:348; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()349; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)350; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1351; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])352; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]353; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]354; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]355; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]356; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]357; CHECK: deopt:358; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]359; CHECK-NEXT: ret i32 [[DEOPTRET]]360; CHECK: loop.preheader:361; CHECK-NEXT: br label [[LOOP:%.*]]362; CHECK: loop:363; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]364; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]365; CHECK-NEXT: call void @unknown()366; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]367; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]368; CHECK: deopt2:369; CHECK-NEXT: call void @unknown()370; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]371; CHECK-NEXT: ret i32 [[DEOPTRET2]]372; CHECK: guarded:373; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, ptr @G, align 4374; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0375; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof [[PROF0]]376; CHECK: deopt3:377; CHECK-NEXT: call void @unknown()378; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]379; CHECK-NEXT: ret i32 [[DEOPTRET3]]380; CHECK: guarded2:381; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64382; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]383; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4384; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4385; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]386; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1387; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]388; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]389; CHECK: exit:390; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]391; CHECK-NEXT: ret i32 [[RESULT]]392;393entry:394 %widenable_cond = call i1 @llvm.experimental.widenable.condition()395 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond396 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0397 398deopt:399 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]400 ret i32 %deoptret401 402loop.preheader:403 br label %loop404 405loop:406 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]407 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]408 call void @unknown()409 %within.bounds = icmp ult i32 %i, %length410 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0411 412deopt2:413 call void @unknown()414 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]415 ret i32 %deoptret2416 417guarded:418 %vol = load volatile i32, ptr @G419 %unknown = icmp eq i32 %vol, 0420 br i1 %unknown, label %guarded2, label %deopt3, !prof !0421 422deopt3:423 call void @unknown()424 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]425 ret i32 %deoptret3426 427guarded2:428 %i.i64 = zext i32 %i to i64429 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64430 %array.i = load i32, ptr %array.i.ptr, align 4431 store i32 0, ptr %array.i.ptr432 %loop.acc.next = add i32 %loop.acc, %array.i433 %i.next = add nuw i32 %i, 1434 %continue = icmp ult i32 %i.next, %n435 br i1 %continue, label %loop, label %exit436 437exit:438 %result = phi i32 [ %loop.acc.next, %guarded2 ]439 ret i32 %result440}441 442 443define i32 @test_unanalyzeable_latch(ptr %array, i32 %length, i32 %n, i1 %cond_0) {444; CHECK-LABEL: @test_unanalyzeable_latch(445; CHECK-NEXT: entry:446; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()447; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]448; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]449; CHECK: deopt:450; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]451; CHECK-NEXT: ret i32 [[DEOPTRET]]452; CHECK: loop.preheader:453; CHECK-NEXT: br label [[LOOP:%.*]]454; CHECK: loop:455; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]456; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]457; CHECK-NEXT: call void @unknown()458; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]459; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]460; CHECK: deopt2:461; CHECK-NEXT: call void @unknown()462; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]463; CHECK-NEXT: ret i32 [[DEOPTRET2]]464; CHECK: guarded:465; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64466; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]467; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4468; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4469; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]470; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1471; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, ptr @G, align 4472; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0473; CHECK-NEXT: br i1 [[UNKNOWN]], label [[LOOP]], label [[EXIT:%.*]]474; CHECK: exit:475; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]476; CHECK-NEXT: ret i32 [[RESULT]]477;478entry:479 %widenable_cond = call i1 @llvm.experimental.widenable.condition()480 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond481 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0482 483deopt:484 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]485 ret i32 %deoptret486 487loop.preheader:488 br label %loop489 490loop:491 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]492 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]493 call void @unknown()494 %within.bounds = icmp ult i32 %i, %length495 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0496 497deopt2:498 call void @unknown()499 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]500 ret i32 %deoptret2501 502guarded:503 %i.i64 = zext i32 %i to i64504 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64505 %array.i = load i32, ptr %array.i.ptr, align 4506 store i32 0, ptr %array.i.ptr507 %loop.acc.next = add i32 %loop.acc, %array.i508 %i.next = add nuw i32 %i, 1509 %vol = load volatile i32, ptr @G510 %unknown = icmp eq i32 %vol, 0511 br i1 %unknown, label %loop, label %exit512 513exit:514 %result = phi i32 [ %loop.acc.next, %guarded ]515 ret i32 %result516}517 518 519define i32 @provably_taken(ptr %array, i1 %cond_0) {520; CHECK-LABEL: @provably_taken(521; CHECK-NEXT: entry:522; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()523; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 false524; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]525; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]526; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]527; CHECK: deopt:528; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]529; CHECK-NEXT: ret i32 [[DEOPTRET]]530; CHECK: loop.preheader:531; CHECK-NEXT: br label [[LOOP:%.*]]532; CHECK: loop:533; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]534; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]535; CHECK-NEXT: call void @unknown()536; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 198537; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]538; CHECK: deopt2:539; CHECK-NEXT: call void @unknown()540; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]541; CHECK-NEXT: ret i32 [[DEOPTRET2]]542; CHECK: guarded:543; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64544; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]545; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4546; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4547; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]548; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1549; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200550; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]551; CHECK: exit:552; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]553; CHECK-NEXT: ret i32 [[RESULT]]554;555entry:556 %widenable_cond = call i1 @llvm.experimental.widenable.condition()557 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond558 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0559 560deopt:561 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]562 ret i32 %deoptret563 564loop.preheader:565 br label %loop566 567loop:568 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]569 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]570 call void @unknown()571 %within.bounds = icmp ult i32 %i, 198572 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0573 574deopt2:575 call void @unknown()576 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]577 ret i32 %deoptret2578 579guarded:580 %i.i64 = zext i32 %i to i64581 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64582 %array.i = load i32, ptr %array.i.ptr, align 4583 store i32 0, ptr %array.i.ptr584 %loop.acc.next = add i32 %loop.acc, %array.i585 %i.next = add nuw i32 %i, 1586 %continue = icmp ult i32 %i.next, 200587 br i1 %continue, label %loop, label %exit588 589exit:590 %result = phi i32 [ %loop.acc.next, %guarded ]591 ret i32 %result592}593 594define i32 @provably_not_taken(ptr %array, i1 %cond_0) {595; CHECK-LABEL: @provably_not_taken(596; CHECK-NEXT: entry:597; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()598; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 true599; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]600; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]601; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]602; CHECK: deopt:603; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]604; CHECK-NEXT: ret i32 [[DEOPTRET]]605; CHECK: loop.preheader:606; CHECK-NEXT: br label [[LOOP:%.*]]607; CHECK: loop:608; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]609; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]610; CHECK-NEXT: call void @unknown()611; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 205612; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]613; CHECK: deopt2:614; CHECK-NEXT: call void @unknown()615; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]616; CHECK-NEXT: ret i32 [[DEOPTRET2]]617; CHECK: guarded:618; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64619; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]620; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4621; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4622; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]623; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1624; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200625; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]626; CHECK: exit:627; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]628; CHECK-NEXT: ret i32 [[RESULT]]629;630entry:631 %widenable_cond = call i1 @llvm.experimental.widenable.condition()632 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond633 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0634 635deopt:636 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]637 ret i32 %deoptret638 639loop.preheader:640 br label %loop641 642loop:643 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]644 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]645 call void @unknown()646 %within.bounds = icmp ult i32 %i, 205647 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0648 649deopt2:650 call void @unknown()651 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]652 ret i32 %deoptret2653 654guarded:655 %i.i64 = zext i32 %i to i64656 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64657 %array.i = load i32, ptr %array.i.ptr, align 4658 store i32 0, ptr %array.i.ptr659 %loop.acc.next = add i32 %loop.acc, %array.i660 %i.next = add nuw i32 %i, 1661 %continue = icmp ult i32 %i.next, 200662 br i1 %continue, label %loop, label %exit663 664exit:665 %result = phi i32 [ %loop.acc.next, %guarded ]666 ret i32 %result667}668 669 670;; Unswitch likes to produce some ugly exit blocks without simplifications671;; being applied. Make sure we can handle that form.672define i32 @unswitch_exit_form(ptr %array, i32 %length, i32 %n, i1 %cond_0) {673; CHECK-LABEL: @unswitch_exit_form(674; CHECK-NEXT: entry:675; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()676; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)677; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1678; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])679; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]680; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]681; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]682; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]683; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]684; CHECK: deopt.loopexit:685; CHECK-NEXT: br label [[DEOPT]]686; CHECK: deopt:687; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[DEOPT_LOOPEXIT:%.*]] ]688; CHECK-NEXT: call void @unknown()689; CHECK-NEXT: br label [[ACTUAL_DEOPT:%.*]]690; CHECK: actual_deopt:691; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ]692; CHECK-NEXT: ret i32 [[DEOPTRET]]693; CHECK: loop.preheader:694; CHECK-NEXT: br label [[LOOP:%.*]]695; CHECK: loop:696; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]697; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]698; CHECK-NEXT: call void @unknown()699; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]700; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof [[PROF0]]701; CHECK: guarded:702; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64703; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]704; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4705; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4706; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]707; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1708; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]709; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]710; CHECK: exit:711; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]712; CHECK-NEXT: ret i32 [[RESULT]]713;714entry:715 %widenable_cond = call i1 @llvm.experimental.widenable.condition()716 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond717 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0718 719deopt:720 ;; This is written to look like an unsimplified loop exit after unswitch721 ;; (i.e. phis, merge, and branch to actual block)722 %phi = phi i32 [0, %entry], [1, %loop]723 call void @unknown() ;; it's okay to skip possible throws724 br label %actual_deopt725 726actual_deopt:727 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ]728 ret i32 %deoptret729 730loop.preheader:731 br label %loop732 733loop:734 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]735 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]736 call void @unknown()737 %within.bounds = icmp ult i32 %i, %length738 br i1 %within.bounds, label %guarded, label %deopt, !prof !0739 740guarded:741 %i.i64 = zext i32 %i to i64742 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64743 %array.i = load i32, ptr %array.i.ptr, align 4744 store i32 0, ptr %array.i.ptr745 %loop.acc.next = add i32 %loop.acc, %array.i746 %i.next = add nuw i32 %i, 1747 %continue = icmp ult i32 %i.next, %n748 br i1 %continue, label %loop, label %exit749 750exit:751 %result = phi i32 [ %loop.acc.next, %guarded ]752 ret i32 %result753}754 755define i32 @swapped_wb(ptr %array, i32 %length, i32 %n, i1 %cond_0) {756; CHECK-LABEL: @swapped_wb(757; CHECK-NEXT: entry:758; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()759; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)760; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1761; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])762; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]763; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]764; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]765; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]]766; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]767; CHECK: deopt:768; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]769; CHECK-NEXT: ret i32 [[DEOPTRET]]770; CHECK: loop.preheader:771; CHECK-NEXT: br label [[LOOP:%.*]]772; CHECK: loop:773; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]774; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]775; CHECK-NEXT: call void @unknown()776; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]777; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]778; CHECK: deopt2:779; CHECK-NEXT: call void @unknown()780; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]781; CHECK-NEXT: ret i32 [[DEOPTRET2]]782; CHECK: guarded:783; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64784; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]785; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4786; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4787; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]788; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1789; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]790; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]791; CHECK: exit:792; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]793; CHECK-NEXT: ret i32 [[RESULT]]794;795entry:796 %widenable_cond = call i1 @llvm.experimental.widenable.condition()797 %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0798 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0799 800deopt:801 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]802 ret i32 %deoptret803 804loop.preheader:805 br label %loop806 807loop:808 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]809 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]810 call void @unknown()811 %within.bounds = icmp ult i32 %i, %length812 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0813 814deopt2:815 call void @unknown()816 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]817 ret i32 %deoptret2818 819guarded:820 %i.i64 = zext i32 %i to i64821 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64822 %array.i = load i32, ptr %array.i.ptr, align 4823 store i32 0, ptr %array.i.ptr824 %loop.acc.next = add i32 %loop.acc, %array.i825 %i.next = add nuw i32 %i, 1826 %continue = icmp ult i32 %i.next, %n827 br i1 %continue, label %loop, label %exit828 829exit:830 %result = phi i32 [ %loop.acc.next, %guarded ]831 ret i32 %result832}833 834define i32 @trivial_wb(ptr %array, i32 %length, i32 %n) {835; CHECK-LABEL: @trivial_wb(836; CHECK-NEXT: entry:837; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)838; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1839; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])840; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]841; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]842; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()843; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]844; CHECK-NEXT: br i1 [[TMP3]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]845; CHECK: deopt:846; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]847; CHECK-NEXT: ret i32 [[DEOPTRET]]848; CHECK: loop.preheader:849; CHECK-NEXT: br label [[LOOP:%.*]]850; CHECK: loop:851; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]852; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]853; CHECK-NEXT: call void @unknown()854; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]855; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]856; CHECK: deopt2:857; CHECK-NEXT: call void @unknown()858; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]859; CHECK-NEXT: ret i32 [[DEOPTRET2]]860; CHECK: guarded:861; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64862; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]863; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4864; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4865; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]866; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1867; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]868; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]869; CHECK: exit:870; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]871; CHECK-NEXT: ret i32 [[RESULT]]872;873entry:874 %widenable_cond = call i1 @llvm.experimental.widenable.condition()875 br i1 %widenable_cond, label %loop.preheader, label %deopt, !prof !0876 877deopt:878 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]879 ret i32 %deoptret880 881loop.preheader:882 br label %loop883 884loop:885 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]886 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]887 call void @unknown()888 %within.bounds = icmp ult i32 %i, %length889 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0890 891deopt2:892 call void @unknown()893 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]894 ret i32 %deoptret2895 896guarded:897 %i.i64 = zext i32 %i to i64898 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64899 %array.i = load i32, ptr %array.i.ptr, align 4900 store i32 0, ptr %array.i.ptr901 %loop.acc.next = add i32 %loop.acc, %array.i902 %i.next = add nuw i32 %i, 1903 %continue = icmp ult i32 %i.next, %n904 br i1 %continue, label %loop, label %exit905 906exit:907 %result = phi i32 [ %loop.acc.next, %guarded ]908 ret i32 %result909}910 911; TODO: Non-latch exits can still be predicated912; This is currently prevented by an overly restrictive profitability check.913define i32 @todo_unconditional_latch(ptr %array, i32 %length, i1 %cond_0) {914; CHECK-LABEL: @todo_unconditional_latch(915; CHECK-NEXT: entry:916; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()917; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]918; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]919; CHECK: deopt:920; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]921; CHECK-NEXT: ret i32 [[DEOPTRET]]922; CHECK: loop.preheader:923; CHECK-NEXT: br label [[LOOP:%.*]]924; CHECK: loop:925; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]926; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]927; CHECK-NEXT: call void @unknown()928; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]929; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof [[PROF0]]930; CHECK: deopt2:931; CHECK-NEXT: call void @unknown()932; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]933; CHECK-NEXT: ret i32 [[DEOPTRET2]]934; CHECK: guarded:935; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64936; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]937; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4938; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4939; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]940; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1941; CHECK-NEXT: br label [[LOOP]]942;943entry:944 %widenable_cond = call i1 @llvm.experimental.widenable.condition()945 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond946 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0947 948deopt:949 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]950 ret i32 %deoptret951 952loop.preheader:953 br label %loop954 955loop:956 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]957 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]958 call void @unknown()959 %within.bounds = icmp ult i32 %i, %length960 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0961 962deopt2:963 call void @unknown()964 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]965 ret i32 %deoptret2966 967guarded:968 %i.i64 = zext i32 %i to i64969 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64970 %array.i = load i32, ptr %array.i.ptr, align 4971 store i32 0, ptr %array.i.ptr972 %loop.acc.next = add i32 %loop.acc, %array.i973 %i.next = add nuw i32 %i, 1974 br label %loop975}976 977 978; If we have a stray widenable branch in the loop, we should still be able to979; run. This can happen when unswitching's cost model avoids unswitching some980; branches.981define i32 @wb_in_loop(ptr %array, i32 %length, i32 %n, i1 %cond_0) {982; CHECK-LABEL: @wb_in_loop(983; CHECK-NEXT: entry:984; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()985; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()986; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)987; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1988; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])989; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]990; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]]991; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]992; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]993; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]]994; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]]995; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]996; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]997; CHECK: deopt:998; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]999; CHECK-NEXT: ret i32 [[DEOPTRET]]1000; CHECK: loop.preheader:1001; CHECK-NEXT: br label [[LOOP:%.*]]1002; CHECK: loop:1003; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]1004; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]1005; CHECK-NEXT: call void @unknown()1006; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]1007; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]1008; CHECK: deopt2:1009; CHECK-NEXT: call void @unknown()1010; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]1011; CHECK-NEXT: ret i32 [[DEOPTRET2]]1012; CHECK: guarded:1013; CHECK-NEXT: call void @unknown()1014; CHECK-NEXT: [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH]]1015; CHECK-NEXT: [[WB_COND:%.*]] = and i1 [[WITHIN_BOUNDS2]], true1016; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof [[PROF0]]1017; CHECK: deopt3:1018; CHECK-NEXT: call void @unknown()1019; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]1020; CHECK-NEXT: ret i32 [[DEOPTRET3]]1021; CHECK: guarded2:1022; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i641023; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]]1024; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 41025; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 41026; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]1027; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 11028; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]1029; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]1030; CHECK: exit:1031; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]1032; CHECK-NEXT: ret i32 [[RESULT]]1033;1034entry:1035 %widenable_cond = call i1 @llvm.experimental.widenable.condition()1036 %wc2 = call i1 @llvm.experimental.widenable.condition()1037 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond1038 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !01039 1040deopt:1041 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]1042 ret i32 %deoptret1043 1044loop.preheader:1045 br label %loop1046 1047loop:1048 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]1049 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]1050 call void @unknown()1051 %within.bounds = icmp ult i32 %i, %length1052 br i1 %within.bounds, label %guarded, label %deopt2, !prof !01053 1054deopt2:1055 call void @unknown()1056 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]1057 ret i32 %deoptret21058 1059guarded:1060 call void @unknown()1061 %within.bounds2 = icmp ult i32 %i, %length1062 %wb_cond = and i1 %within.bounds2, %wc21063 br i1 %wb_cond, label %guarded2, label %deopt3, !prof !01064 1065deopt3:1066 call void @unknown()1067 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]1068 ret i32 %deoptret31069 1070guarded2:1071 %i.i64 = zext i32 %i to i641072 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i641073 %array.i = load i32, ptr %array.i.ptr, align 41074 store i32 0, ptr %array.i.ptr1075 %loop.acc.next = add i32 %loop.acc, %array.i1076 %i.next = add nuw i32 %i, 11077 %continue = icmp ult i32 %i.next, %n1078 br i1 %continue, label %loop, label %exit1079 1080exit:1081 %result = phi i32 [ %loop.acc.next, %guarded2 ]1082 ret i32 %result1083}1084 1085define void @test_memssa() {1086; CHECK-LABEL: @test_memssa(1087; CHECK-NEXT: bb:1088; CHECK-NEXT: [[TMP:%.*]] = call i1 @llvm.experimental.widenable.condition()1089; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.experimental.widenable.condition()1090; CHECK-NEXT: br i1 [[TMP]], label [[BB3:%.*]], label [[BB2:%.*]]1091; CHECK: bb2:1092; CHECK-NEXT: unreachable1093; CHECK: bb3:1094; CHECK-NEXT: br label [[BB4:%.*]]1095; CHECK: bb4:1096; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP7:%.*]], [[BB6:%.*]] ], [ 0, [[BB3]] ]1097; CHECK-NEXT: br i1 true, label [[BB10:%.*]], label [[BB6]]1098; CHECK: bb6:1099; CHECK-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], 11100; CHECK-NEXT: [[TMP8:%.*]] = icmp ult i32 [[TMP7]], undef1101; CHECK-NEXT: br i1 [[TMP8]], label [[BB4]], label [[BB9:%.*]]1102; CHECK: bb9:1103; CHECK-NEXT: ret void1104; CHECK: bb10:1105; CHECK-NEXT: ret void1106;1107bb:1108 %tmp = call i1 @llvm.experimental.widenable.condition()1109 %tmp1 = call i1 @llvm.experimental.widenable.condition()1110 br i1 %tmp, label %bb3, label %bb21111 1112bb2: ; preds = %bb1113 unreachable1114 1115bb3: ; preds = %bb1116 br label %bb41117 1118bb4: ; preds = %bb6, %bb31119 %tmp5 = phi i32 [ %tmp7, %bb6 ], [ 0, %bb3 ]1120 br i1 true, label %bb10, label %bb61121 1122bb6: ; preds = %bb41123 %tmp7 = add nuw nsw i32 %tmp5, 11124 %tmp8 = icmp ult i32 %tmp7, undef1125 br i1 %tmp8, label %bb4, label %bb91126 1127bb9: ; preds = %bb61128 ret void1129 1130bb10: ; preds = %bb41131 ret void1132}1133 1134 1135 1136declare void @unknown()1137 1138declare i1 @llvm.experimental.widenable.condition()1139declare i32 @llvm.experimental.deoptimize.i32(...)1140 1141!0 = !{!"branch_weights", i32 1048576, i32 1}1142!1 = !{i32 1, i32 -2147483648}1143!2 = !{i32 0, i32 50}1144