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