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