1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -loop-predication -S | FileCheck %s 3 4declare void @prevent_merging() 5 6; Base case - with side effects in loop 7define i32 @test1(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 8; CHECK-LABEL: @test1( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 11; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 12; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 13; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 14; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 15; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 16; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 17; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 18; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 19; CHECK: deopt: 20; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 21; CHECK-NEXT: ret i32 [[DEOPTRET]] 22; CHECK: loop.preheader: 23; CHECK-NEXT: br label [[LOOP:%.*]] 24; CHECK: loop: 25; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 26; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 27; CHECK-NEXT: call void @unknown() 28; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 29; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 30; CHECK: deopt2: 31; CHECK-NEXT: call void @unknown() 32; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 33; CHECK-NEXT: ret i32 [[DEOPTRET2]] 34; CHECK: guarded: 35; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 36; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 37; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 38; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 39; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 40; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 41; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 42; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 43; CHECK: exit: 44; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 45; CHECK-NEXT: ret i32 [[RESULT]] 46; 47entry: 48 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 49 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 50 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 51 52deopt: 53 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 54 ret i32 %deoptret 55 56loop.preheader: 57 br label %loop 58 59loop: 60 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 61 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 62 call void @unknown() 63 %within.bounds = icmp ult i32 %i, %length 64 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 65 66deopt2: 67 call void @unknown() 68 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 69 ret i32 %deoptret2 70 71guarded: 72 %i.i64 = zext i32 %i to i64 73 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 74 %array.i = load i32, i32* %array.i.ptr, align 4 75 store i32 0, i32* %array.i.ptr 76 %loop.acc.next = add i32 %loop.acc, %array.i 77 %i.next = add nuw i32 %i, 1 78 %continue = icmp ult i32 %i.next, %n 79 br i1 %continue, label %loop, label %exit 80 81exit: 82 %result = phi i32 [ %loop.acc.next, %guarded ] 83 ret i32 %result 84} 85 86 87 88define i32 @test_non_canonical(i32* %array, i32 %length, i1 %cond_0) { 89; CHECK-LABEL: @test_non_canonical( 90; CHECK-NEXT: entry: 91; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 92; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LENGTH:%.*]], i32 1) 93; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 94; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH]], i32 [[TMP0]]) 95; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 96; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 97; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 98; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 99; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 100; CHECK: deopt: 101; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 102; CHECK-NEXT: ret i32 [[DEOPTRET]] 103; CHECK: loop.preheader: 104; CHECK-NEXT: br label [[LOOP:%.*]] 105; CHECK: loop: 106; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 107; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 108; CHECK-NEXT: call void @unknown() 109; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 110; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 111; CHECK: deopt2: 112; CHECK-NEXT: call void @unknown() 113; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 114; CHECK-NEXT: ret i32 [[DEOPTRET2]] 115; CHECK: guarded: 116; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 117; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 118; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 119; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 120; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 121; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 122; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]] 123; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 124; CHECK: exit: 125; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 126; CHECK-NEXT: ret i32 [[RESULT]] 127; 128entry: 129 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 130 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 131 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 132 133deopt: 134 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 135 ret i32 %deoptret 136 137loop.preheader: 138 br label %loop 139 140loop: 141 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 142 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 143 call void @unknown() 144 %within.bounds = icmp ult i32 %i, %length 145 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 146 147deopt2: 148 call void @unknown() 149 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 150 ret i32 %deoptret2 151 152guarded: 153 %i.i64 = zext i32 %i to i64 154 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 155 %array.i = load i32, i32* %array.i.ptr, align 4 156 store i32 0, i32* %array.i.ptr 157 %loop.acc.next = add i32 %loop.acc, %array.i 158 %i.next = add nuw i32 %i, 1 159 %continue = icmp ult i32 %i.next, %length 160 br i1 %continue, label %loop, label %exit 161 162exit: 163 %result = phi i32 [ %loop.acc.next, %guarded ] 164 ret i32 %result 165} 166 167 168define i32 @test_two_range_checks(i32* %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) { 169; CHECK-LABEL: @test_two_range_checks( 170; CHECK-NEXT: entry: 171; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 172; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_2:%.*]], i32 [[LENGTH_1:%.*]]) 173; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 174; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 175; CHECK-NEXT: [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[TMP0]]) 176; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]] 177; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 178; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 179; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]] 180; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]] 181; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]] 182; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]] 183; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 184; CHECK: deopt: 185; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 186; CHECK-NEXT: ret i32 [[DEOPTRET]] 187; CHECK: loop.preheader: 188; CHECK-NEXT: br label [[LOOP:%.*]] 189; CHECK: loop: 190; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 191; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 192; CHECK-NEXT: call void @unknown() 193; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] 194; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0 195; CHECK: deopt2: 196; CHECK-NEXT: call void @unknown() 197; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 198; CHECK-NEXT: ret i32 [[DEOPTRET2]] 199; CHECK: guarded: 200; CHECK-NEXT: [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] 201; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 202; CHECK: deopt3: 203; CHECK-NEXT: call void @unknown() 204; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 205; CHECK-NEXT: ret i32 [[DEOPTRET3]] 206; CHECK: guarded2: 207; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 208; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 209; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 210; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 211; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 212; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 213; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 214; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 215; CHECK: exit: 216; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 217; CHECK-NEXT: ret i32 [[RESULT]] 218; 219entry: 220 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 221 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 222 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 223 224deopt: 225 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 226 ret i32 %deoptret 227 228loop.preheader: 229 br label %loop 230 231loop: 232 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 233 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 234 call void @unknown() 235 %within.bounds = icmp ult i32 %i, %length.1 236 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 237 238deopt2: 239 call void @unknown() 240 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 241 ret i32 %deoptret2 242 243guarded: 244 %within.bounds2 = icmp ult i32 %i, %length.2 245 br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0 246 247deopt3: 248 call void @unknown() 249 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 250 ret i32 %deoptret3 251 252guarded2: 253 %i.i64 = zext i32 %i to i64 254 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 255 %array.i = load i32, i32* %array.i.ptr, align 4 256 store i32 0, i32* %array.i.ptr 257 %loop.acc.next = add i32 %loop.acc, %array.i 258 %i.next = add nuw i32 %i, 1 259 %continue = icmp ult i32 %i.next, %n 260 br i1 %continue, label %loop, label %exit 261 262exit: 263 %result = phi i32 [ %loop.acc.next, %guarded2 ] 264 ret i32 %result 265} 266 267@G = external global i32 268 269define i32 @test_unanalyzeable_exit(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 270; CHECK-LABEL: @test_unanalyzeable_exit( 271; CHECK-NEXT: entry: 272; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 273; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 274; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 275; CHECK: deopt: 276; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 277; CHECK-NEXT: ret i32 [[DEOPTRET]] 278; CHECK: loop.preheader: 279; CHECK-NEXT: br label [[LOOP:%.*]] 280; CHECK: loop: 281; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 282; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 283; CHECK-NEXT: call void @unknown() 284; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G, align 4 285; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0 286; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 287; CHECK: deopt3: 288; CHECK-NEXT: call void @unknown() 289; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 290; CHECK-NEXT: ret i32 [[DEOPTRET3]] 291; CHECK: guarded2: 292; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 293; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 294; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 295; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 296; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 297; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 298; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N:%.*]] 299; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 300; CHECK: exit: 301; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 302; CHECK-NEXT: ret i32 [[RESULT]] 303; 304entry: 305 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 306 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 307 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 308 309deopt: 310 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 311 ret i32 %deoptret 312 313loop.preheader: 314 br label %loop 315 316loop: 317 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 318 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 319 call void @unknown() 320 %vol = load volatile i32, i32* @G 321 %unknown = icmp eq i32 %vol, 0 322 br i1 %unknown, label %guarded2, label %deopt3, !prof !0 323 324deopt3: 325 call void @unknown() 326 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 327 ret i32 %deoptret3 328 329guarded2: 330 %i.i64 = zext i32 %i to i64 331 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 332 %array.i = load i32, i32* %array.i.ptr, align 4 333 store i32 0, i32* %array.i.ptr 334 %loop.acc.next = add i32 %loop.acc, %array.i 335 %i.next = add nuw i32 %i, 1 336 %continue = icmp ult i32 %i.next, %n 337 br i1 %continue, label %loop, label %exit 338 339exit: 340 %result = phi i32 [ %loop.acc.next, %guarded2 ] 341 ret i32 %result 342} 343 344define i32 @test_unanalyzeable_exit2(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 345; CHECK-LABEL: @test_unanalyzeable_exit2( 346; CHECK-NEXT: entry: 347; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 348; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 349; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 350; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 351; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 352; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 353; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 354; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 355; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 356; CHECK: deopt: 357; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 358; CHECK-NEXT: ret i32 [[DEOPTRET]] 359; CHECK: loop.preheader: 360; CHECK-NEXT: br label [[LOOP:%.*]] 361; CHECK: loop: 362; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 363; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 364; CHECK-NEXT: call void @unknown() 365; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 366; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0 367; CHECK: deopt2: 368; CHECK-NEXT: call void @unknown() 369; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 370; CHECK-NEXT: ret i32 [[DEOPTRET2]] 371; CHECK: guarded: 372; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G, align 4 373; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0 374; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 375; CHECK: deopt3: 376; CHECK-NEXT: call void @unknown() 377; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 378; CHECK-NEXT: ret i32 [[DEOPTRET3]] 379; CHECK: guarded2: 380; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 381; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 382; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 383; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 384; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 385; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 386; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 387; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 388; CHECK: exit: 389; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 390; CHECK-NEXT: ret i32 [[RESULT]] 391; 392entry: 393 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 394 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 395 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 396 397deopt: 398 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 399 ret i32 %deoptret 400 401loop.preheader: 402 br label %loop 403 404loop: 405 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 406 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 407 call void @unknown() 408 %within.bounds = icmp ult i32 %i, %length 409 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 410 411deopt2: 412 call void @unknown() 413 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 414 ret i32 %deoptret2 415 416guarded: 417 %vol = load volatile i32, i32* @G 418 %unknown = icmp eq i32 %vol, 0 419 br i1 %unknown, label %guarded2, label %deopt3, !prof !0 420 421deopt3: 422 call void @unknown() 423 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 424 ret i32 %deoptret3 425 426guarded2: 427 %i.i64 = zext i32 %i to i64 428 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 429 %array.i = load i32, i32* %array.i.ptr, align 4 430 store i32 0, i32* %array.i.ptr 431 %loop.acc.next = add i32 %loop.acc, %array.i 432 %i.next = add nuw i32 %i, 1 433 %continue = icmp ult i32 %i.next, %n 434 br i1 %continue, label %loop, label %exit 435 436exit: 437 %result = phi i32 [ %loop.acc.next, %guarded2 ] 438 ret i32 %result 439} 440 441 442define i32 @test_unanalyzeable_latch(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 443; CHECK-LABEL: @test_unanalyzeable_latch( 444; CHECK-NEXT: entry: 445; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 446; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 447; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 448; CHECK: deopt: 449; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 450; CHECK-NEXT: ret i32 [[DEOPTRET]] 451; CHECK: loop.preheader: 452; CHECK-NEXT: br label [[LOOP:%.*]] 453; CHECK: loop: 454; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 455; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 456; CHECK-NEXT: call void @unknown() 457; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 458; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 459; CHECK: deopt2: 460; CHECK-NEXT: call void @unknown() 461; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 462; CHECK-NEXT: ret i32 [[DEOPTRET2]] 463; CHECK: guarded: 464; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 465; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 466; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 467; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 468; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 469; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 470; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G, align 4 471; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0 472; CHECK-NEXT: br i1 [[UNKNOWN]], label [[LOOP]], label [[EXIT:%.*]] 473; CHECK: exit: 474; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 475; CHECK-NEXT: ret i32 [[RESULT]] 476; 477entry: 478 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 479 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 480 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 481 482deopt: 483 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 484 ret i32 %deoptret 485 486loop.preheader: 487 br label %loop 488 489loop: 490 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 491 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 492 call void @unknown() 493 %within.bounds = icmp ult i32 %i, %length 494 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 495 496deopt2: 497 call void @unknown() 498 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 499 ret i32 %deoptret2 500 501guarded: 502 %i.i64 = zext i32 %i to i64 503 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 504 %array.i = load i32, i32* %array.i.ptr, align 4 505 store i32 0, i32* %array.i.ptr 506 %loop.acc.next = add i32 %loop.acc, %array.i 507 %i.next = add nuw i32 %i, 1 508 %vol = load volatile i32, i32* @G 509 %unknown = icmp eq i32 %vol, 0 510 br i1 %unknown, label %loop, label %exit 511 512exit: 513 %result = phi i32 [ %loop.acc.next, %guarded ] 514 ret i32 %result 515} 516 517 518define i32 @provably_taken(i32* %array, i1 %cond_0) { 519; CHECK-LABEL: @provably_taken( 520; CHECK-NEXT: entry: 521; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 522; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 false 523; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]] 524; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]] 525; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 526; CHECK: deopt: 527; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 528; CHECK-NEXT: ret i32 [[DEOPTRET]] 529; CHECK: loop.preheader: 530; CHECK-NEXT: br label [[LOOP:%.*]] 531; CHECK: loop: 532; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 533; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 534; CHECK-NEXT: call void @unknown() 535; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 198 536; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 537; CHECK: deopt2: 538; CHECK-NEXT: call void @unknown() 539; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 540; CHECK-NEXT: ret i32 [[DEOPTRET2]] 541; CHECK: guarded: 542; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 543; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 544; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 545; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 546; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 547; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 548; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200 549; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 550; CHECK: exit: 551; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 552; CHECK-NEXT: ret i32 [[RESULT]] 553; 554entry: 555 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 556 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 557 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 558 559deopt: 560 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 561 ret i32 %deoptret 562 563loop.preheader: 564 br label %loop 565 566loop: 567 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 568 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 569 call void @unknown() 570 %within.bounds = icmp ult i32 %i, 198 571 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 572 573deopt2: 574 call void @unknown() 575 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 576 ret i32 %deoptret2 577 578guarded: 579 %i.i64 = zext i32 %i to i64 580 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 581 %array.i = load i32, i32* %array.i.ptr, align 4 582 store i32 0, i32* %array.i.ptr 583 %loop.acc.next = add i32 %loop.acc, %array.i 584 %i.next = add nuw i32 %i, 1 585 %continue = icmp ult i32 %i.next, 200 586 br i1 %continue, label %loop, label %exit 587 588exit: 589 %result = phi i32 [ %loop.acc.next, %guarded ] 590 ret i32 %result 591} 592 593define i32 @provably_not_taken(i32* %array, i1 %cond_0) { 594; CHECK-LABEL: @provably_not_taken( 595; CHECK-NEXT: entry: 596; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 597; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 true 598; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]] 599; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]] 600; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 601; CHECK: deopt: 602; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 603; CHECK-NEXT: ret i32 [[DEOPTRET]] 604; CHECK: loop.preheader: 605; CHECK-NEXT: br label [[LOOP:%.*]] 606; CHECK: loop: 607; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 608; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 609; CHECK-NEXT: call void @unknown() 610; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 205 611; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 612; CHECK: deopt2: 613; CHECK-NEXT: call void @unknown() 614; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 615; CHECK-NEXT: ret i32 [[DEOPTRET2]] 616; CHECK: guarded: 617; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 618; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 619; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 620; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 621; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 622; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 623; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200 624; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 625; CHECK: exit: 626; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 627; CHECK-NEXT: ret i32 [[RESULT]] 628; 629entry: 630 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 631 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 632 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 633 634deopt: 635 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 636 ret i32 %deoptret 637 638loop.preheader: 639 br label %loop 640 641loop: 642 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 643 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 644 call void @unknown() 645 %within.bounds = icmp ult i32 %i, 205 646 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 647 648deopt2: 649 call void @unknown() 650 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 651 ret i32 %deoptret2 652 653guarded: 654 %i.i64 = zext i32 %i to i64 655 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 656 %array.i = load i32, i32* %array.i.ptr, align 4 657 store i32 0, i32* %array.i.ptr 658 %loop.acc.next = add i32 %loop.acc, %array.i 659 %i.next = add nuw i32 %i, 1 660 %continue = icmp ult i32 %i.next, 200 661 br i1 %continue, label %loop, label %exit 662 663exit: 664 %result = phi i32 [ %loop.acc.next, %guarded ] 665 ret i32 %result 666} 667 668 669;; Unswitch likes to produce some ugly exit blocks without simplifications 670;; being applied. Make sure we can handle that form. 671define i32 @unswitch_exit_form(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 672; CHECK-LABEL: @unswitch_exit_form( 673; CHECK-NEXT: entry: 674; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 675; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 676; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 677; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 678; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 679; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 680; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 681; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 682; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 683; CHECK: deopt.loopexit: 684; CHECK-NEXT: br label [[DEOPT]] 685; CHECK: deopt: 686; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[DEOPT_LOOPEXIT:%.*]] ] 687; CHECK-NEXT: call void @unknown() 688; CHECK-NEXT: br label [[ACTUAL_DEOPT:%.*]] 689; CHECK: actual_deopt: 690; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ] 691; CHECK-NEXT: ret i32 [[DEOPTRET]] 692; CHECK: loop.preheader: 693; CHECK-NEXT: br label [[LOOP:%.*]] 694; CHECK: loop: 695; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 696; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 697; CHECK-NEXT: call void @unknown() 698; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 699; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof !0 700; CHECK: guarded: 701; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 702; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 703; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 704; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 705; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 706; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 707; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 708; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 709; CHECK: exit: 710; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 711; CHECK-NEXT: ret i32 [[RESULT]] 712; 713entry: 714 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 715 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 716 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 717 718deopt: 719 ;; This is written to look like an unsimplified loop exit after unswitch 720 ;; (i.e. phis, merge, and branch to actual block) 721 %phi = phi i32 [0, %entry], [1, %loop] 722 call void @unknown() ;; it's okay to skip possible throws 723 br label %actual_deopt 724 725actual_deopt: 726 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ] 727 ret i32 %deoptret 728 729loop.preheader: 730 br label %loop 731 732loop: 733 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 734 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 735 call void @unknown() 736 %within.bounds = icmp ult i32 %i, %length 737 br i1 %within.bounds, label %guarded, label %deopt, !prof !0 738 739guarded: 740 %i.i64 = zext i32 %i to i64 741 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 742 %array.i = load i32, i32* %array.i.ptr, align 4 743 store i32 0, i32* %array.i.ptr 744 %loop.acc.next = add i32 %loop.acc, %array.i 745 %i.next = add nuw i32 %i, 1 746 %continue = icmp ult i32 %i.next, %n 747 br i1 %continue, label %loop, label %exit 748 749exit: 750 %result = phi i32 [ %loop.acc.next, %guarded ] 751 ret i32 %result 752} 753 754define i32 @swapped_wb(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 755; CHECK-LABEL: @swapped_wb( 756; CHECK-NEXT: entry: 757; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 758; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 759; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 760; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 761; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 762; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 763; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 764; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]] 765; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 766; CHECK: deopt: 767; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 768; CHECK-NEXT: ret i32 [[DEOPTRET]] 769; CHECK: loop.preheader: 770; CHECK-NEXT: br label [[LOOP:%.*]] 771; CHECK: loop: 772; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 773; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 774; CHECK-NEXT: call void @unknown() 775; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 776; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 777; CHECK: deopt2: 778; CHECK-NEXT: call void @unknown() 779; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 780; CHECK-NEXT: ret i32 [[DEOPTRET2]] 781; CHECK: guarded: 782; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 783; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 784; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 785; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 786; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 787; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 788; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 789; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 790; CHECK: exit: 791; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 792; CHECK-NEXT: ret i32 [[RESULT]] 793; 794entry: 795 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 796 %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0 797 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 798 799deopt: 800 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 801 ret i32 %deoptret 802 803loop.preheader: 804 br label %loop 805 806loop: 807 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 808 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 809 call void @unknown() 810 %within.bounds = icmp ult i32 %i, %length 811 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 812 813deopt2: 814 call void @unknown() 815 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 816 ret i32 %deoptret2 817 818guarded: 819 %i.i64 = zext i32 %i to i64 820 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 821 %array.i = load i32, i32* %array.i.ptr, align 4 822 store i32 0, i32* %array.i.ptr 823 %loop.acc.next = add i32 %loop.acc, %array.i 824 %i.next = add nuw i32 %i, 1 825 %continue = icmp ult i32 %i.next, %n 826 br i1 %continue, label %loop, label %exit 827 828exit: 829 %result = phi i32 [ %loop.acc.next, %guarded ] 830 ret i32 %result 831} 832 833define i32 @trivial_wb(i32* %array, i32 %length, i32 %n) { 834; CHECK-LABEL: @trivial_wb( 835; CHECK-NEXT: entry: 836; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 837; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 838; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 839; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 840; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 841; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 842; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] 843; CHECK-NEXT: br i1 [[TMP3]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 844; CHECK: deopt: 845; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 846; CHECK-NEXT: ret i32 [[DEOPTRET]] 847; CHECK: loop.preheader: 848; CHECK-NEXT: br label [[LOOP:%.*]] 849; CHECK: loop: 850; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 851; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 852; CHECK-NEXT: call void @unknown() 853; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 854; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 855; CHECK: deopt2: 856; CHECK-NEXT: call void @unknown() 857; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 858; CHECK-NEXT: ret i32 [[DEOPTRET2]] 859; CHECK: guarded: 860; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 861; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 862; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 863; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 864; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 865; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 866; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 867; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 868; CHECK: exit: 869; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 870; CHECK-NEXT: ret i32 [[RESULT]] 871; 872entry: 873 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 874 br i1 %widenable_cond, label %loop.preheader, label %deopt, !prof !0 875 876deopt: 877 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 878 ret i32 %deoptret 879 880loop.preheader: 881 br label %loop 882 883loop: 884 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 885 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 886 call void @unknown() 887 %within.bounds = icmp ult i32 %i, %length 888 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 889 890deopt2: 891 call void @unknown() 892 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 893 ret i32 %deoptret2 894 895guarded: 896 %i.i64 = zext i32 %i to i64 897 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 898 %array.i = load i32, i32* %array.i.ptr, align 4 899 store i32 0, i32* %array.i.ptr 900 %loop.acc.next = add i32 %loop.acc, %array.i 901 %i.next = add nuw i32 %i, 1 902 %continue = icmp ult i32 %i.next, %n 903 br i1 %continue, label %loop, label %exit 904 905exit: 906 %result = phi i32 [ %loop.acc.next, %guarded ] 907 ret i32 %result 908} 909 910; TODO: Non-latch exits can still be predicated 911; This is currently prevented by an overly restrictive profitability check. 912define i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) { 913; CHECK-LABEL: @todo_unconditional_latch( 914; CHECK-NEXT: entry: 915; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 916; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 917; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 918; CHECK: deopt: 919; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 920; CHECK-NEXT: ret i32 [[DEOPTRET]] 921; CHECK: loop.preheader: 922; CHECK-NEXT: br label [[LOOP:%.*]] 923; CHECK: loop: 924; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 925; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 926; CHECK-NEXT: call void @unknown() 927; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 928; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 929; CHECK: deopt2: 930; CHECK-NEXT: call void @unknown() 931; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 932; CHECK-NEXT: ret i32 [[DEOPTRET2]] 933; CHECK: guarded: 934; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 935; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 936; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 937; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 938; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 939; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 940; CHECK-NEXT: br label [[LOOP]] 941; 942entry: 943 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 944 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 945 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 946 947deopt: 948 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 949 ret i32 %deoptret 950 951loop.preheader: 952 br label %loop 953 954loop: 955 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 956 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 957 call void @unknown() 958 %within.bounds = icmp ult i32 %i, %length 959 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 960 961deopt2: 962 call void @unknown() 963 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 964 ret i32 %deoptret2 965 966guarded: 967 %i.i64 = zext i32 %i to i64 968 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 969 %array.i = load i32, i32* %array.i.ptr, align 4 970 store i32 0, i32* %array.i.ptr 971 %loop.acc.next = add i32 %loop.acc, %array.i 972 %i.next = add nuw i32 %i, 1 973 br label %loop 974} 975 976 977; If we have a stray widenable branch in the loop, we should still be able to 978; run. This can happen when unswitching's cost model avoids unswitching some 979; branches. 980define i32 @wb_in_loop(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 981; CHECK-LABEL: @wb_in_loop( 982; CHECK-NEXT: entry: 983; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 984; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() 985; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1) 986; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[UMAX]], -1 987; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]]) 988; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 989; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 990; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]] 991; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 992; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]] 993; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]] 994; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]] 995; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 996; CHECK: deopt: 997; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 998; CHECK-NEXT: ret i32 [[DEOPTRET]] 999; CHECK: loop.preheader: 1000; CHECK-NEXT: br label [[LOOP:%.*]] 1001; CHECK: loop: 1002; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1003; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 1004; CHECK-NEXT: call void @unknown() 1005; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 1006; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0 1007; CHECK: deopt2: 1008; CHECK-NEXT: call void @unknown() 1009; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1010; CHECK-NEXT: ret i32 [[DEOPTRET2]] 1011; CHECK: guarded: 1012; CHECK-NEXT: call void @unknown() 1013; CHECK-NEXT: [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 1014; CHECK-NEXT: [[WB_COND:%.*]] = and i1 [[WITHIN_BOUNDS2]], true 1015; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 1016; CHECK: deopt3: 1017; CHECK-NEXT: call void @unknown() 1018; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1019; CHECK-NEXT: ret i32 [[DEOPTRET3]] 1020; CHECK: guarded2: 1021; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1022; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 1023; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 1024; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4 1025; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1026; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1027; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1028; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 1029; CHECK: exit: 1030; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 1031; CHECK-NEXT: ret i32 [[RESULT]] 1032; 1033entry: 1034 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1035 %wc2 = call i1 @llvm.experimental.widenable.condition() 1036 %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 1037 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 1038 1039deopt: 1040 %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1041 ret i32 %deoptret 1042 1043loop.preheader: 1044 br label %loop 1045 1046loop: 1047 %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 1048 %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 1049 call void @unknown() 1050 %within.bounds = icmp ult i32 %i, %length 1051 br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 1052 1053deopt2: 1054 call void @unknown() 1055 %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1056 ret i32 %deoptret2 1057 1058guarded: 1059 call void @unknown() 1060 %within.bounds2 = icmp ult i32 %i, %length 1061 %wb_cond = and i1 %within.bounds2, %wc2 1062 br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0 1063 1064deopt3: 1065 call void @unknown() 1066 %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 1067 ret i32 %deoptret3 1068 1069guarded2: 1070 %i.i64 = zext i32 %i to i64 1071 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1072 %array.i = load i32, i32* %array.i.ptr, align 4 1073 store i32 0, i32* %array.i.ptr 1074 %loop.acc.next = add i32 %loop.acc, %array.i 1075 %i.next = add nuw i32 %i, 1 1076 %continue = icmp ult i32 %i.next, %n 1077 br i1 %continue, label %loop, label %exit 1078 1079exit: 1080 %result = phi i32 [ %loop.acc.next, %guarded2 ] 1081 ret i32 %result 1082} 1083 1084 1085 1086declare void @unknown() 1087 1088declare i1 @llvm.experimental.widenable.condition() 1089declare i32 @llvm.experimental.deoptimize.i32(...) 1090 1091!0 = !{!"branch_weights", i32 1048576, i32 1} 1092!1 = !{i32 1, i32 -2147483648} 1093!2 = !{i32 0, i32 50} 1094