1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=loop-unroll -S %s | FileCheck %s 3 4declare void @foo() 5 6define i32 @peel_readonly_to_make_loads_derefenceable(ptr %ptr, i32 %N, ptr %inv, i1 %c.1) { 7; CHECK-LABEL: @peel_readonly_to_make_loads_derefenceable( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_BEGIN:%.*]] 10; CHECK: loop.header.peel.begin: 11; CHECK-NEXT: br label [[LOOP_HEADER_PEEL:%.*]] 12; CHECK: loop.header.peel: 13; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN_PEEL:%.*]], label [[UNREACHABLE_EXIT:%.*]] 14; CHECK: then.peel: 15; CHECK-NEXT: [[I_PEEL:%.*]] = load i32, ptr [[INV:%.*]], align 4 16; CHECK-NEXT: [[C_2_PEEL:%.*]] = icmp ult i32 [[I_PEEL]], 2 17; CHECK-NEXT: br i1 [[C_2_PEEL]], label [[LOOP_LATCH_PEEL:%.*]], label [[UNREACHABLE_EXIT]] 18; CHECK: loop.latch.peel: 19; CHECK-NEXT: [[GEP_PEEL:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 1 20; CHECK-NEXT: [[LV_PEEL:%.*]] = load i32, ptr [[GEP_PEEL]], align 4 21; CHECK-NEXT: [[SUM_NEXT_PEEL:%.*]] = add i32 0, [[LV_PEEL]] 22; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add nuw nsw i32 1, 1 23; CHECK-NEXT: [[C_3_PEEL:%.*]] = icmp ult i32 1, 1000 24; CHECK-NEXT: br i1 [[C_3_PEEL]], label [[LOOP_HEADER_PEEL_NEXT:%.*]], label [[EXIT:%.*]] 25; CHECK: loop.header.peel.next: 26; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_NEXT1:%.*]] 27; CHECK: loop.header.peel.next1: 28; CHECK-NEXT: br label [[ENTRY_PEEL_NEWPH:%.*]] 29; CHECK: entry.peel.newph: 30; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 31; CHECK: loop.header: 32; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT_PEEL]], [[ENTRY_PEEL_NEWPH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 33; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ [[SUM_NEXT_PEEL]], [[ENTRY_PEEL_NEWPH]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 34; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT_LOOPEXIT:%.*]] 35; CHECK: then: 36; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV]], align 4 37; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2 38; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT_LOOPEXIT]] 39; CHECK: loop.latch: 40; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[IV]] 41; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 42; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]] 43; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 44; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 45; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]] 46; CHECK: exit.loopexit: 47; CHECK-NEXT: [[SUM_NEXT_LCSSA_PH:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ] 48; CHECK-NEXT: br label [[EXIT]] 49; CHECK: exit: 50; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT_PEEL]], [[LOOP_LATCH_PEEL]] ], [ [[SUM_NEXT_LCSSA_PH]], [[EXIT_LOOPEXIT]] ] 51; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 52; CHECK: unreachable.exit.loopexit: 53; CHECK-NEXT: br label [[UNREACHABLE_EXIT]] 54; CHECK: unreachable.exit: 55; CHECK-NEXT: call void @foo() 56; CHECK-NEXT: unreachable 57; 58entry: 59 br label %loop.header 60 61loop.header: 62 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 63 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 64 br i1 %c.1, label %then, label %unreachable.exit 65 66then: 67 %i = load i32, ptr %inv 68 %c.2 = icmp ult i32 %i, 2 69 br i1 %c.2, label %loop.latch, label %unreachable.exit 70 71loop.latch: 72 %gep = getelementptr i32, ptr %ptr, i32 %iv 73 %lv = load i32, ptr %gep 74 %sum.next = add i32 %sum, %lv 75 %iv.next = add nuw nsw i32 %iv, 1 76 %c.3 = icmp ult i32 %iv, 1000 77 br i1 %c.3, label %loop.header, label %exit 78 79exit: 80 ret i32 %sum.next 81 82unreachable.exit: 83 call void @foo() 84 unreachable 85} 86 87define i32 @peel_readonly_to_make_loads_derefenceable_exits_lead_to_unreachable(ptr %ptr, i32 %N, ptr %inv, i1 %c.1) { 88; CHECK-LABEL: @peel_readonly_to_make_loads_derefenceable_exits_lead_to_unreachable( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 91; CHECK: loop.header: 92; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 93; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 94; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT_2:%.*]] 95; CHECK: then: 96; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4 97; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2 98; CHECK-NEXT: br i1 [[C_2]], label [[THEN_2:%.*]], label [[EXIT_2]] 99; CHECK: then.2: 100; CHECK-NEXT: [[C_4:%.*]] = icmp ult i32 [[I]], 4 101; CHECK-NEXT: br i1 [[C_4]], label [[LOOP_LATCH]], label [[EXIT_3:%.*]] 102; CHECK: loop.latch: 103; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 104; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 105; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]] 106; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 107; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 108; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 109; CHECK: exit: 110; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ] 111; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 112; CHECK: exit.2: 113; CHECK-NEXT: br label [[UNREACHABLE_BB:%.*]] 114; CHECK: exit.3: 115; CHECK-NEXT: br label [[UNREACHABLE_BB]] 116; CHECK: unreachable.bb: 117; CHECK-NEXT: call void @foo() 118; CHECK-NEXT: unreachable 119; 120entry: 121 br label %loop.header 122 123loop.header: 124 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 125 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 126 br i1 %c.1, label %then, label %exit.2 127 128then: 129 %i = load i32, ptr %inv 130 %c.2 = icmp ult i32 %i, 2 131 br i1 %c.2, label %then.2, label %exit.2 132 133then.2: 134 %c.4 = icmp ult i32 %i, 4 135 br i1 %c.4, label %loop.latch, label %exit.3 136 137loop.latch: 138 %gep = getelementptr i32, ptr %ptr, i32 %iv 139 %lv = load i32, ptr %gep 140 %sum.next = add i32 %sum, %lv 141 %iv.next = add nuw nsw i32 %iv, 1 142 %c.3 = icmp ult i32 %iv, 1000 143 br i1 %c.3, label %loop.header, label %exit 144 145exit: 146 ret i32 %sum.next 147 148exit.2: 149 br label %unreachable.bb 150 151exit.3: 152 br label %unreachable.bb 153 154unreachable.bb: 155 call void @foo() 156 unreachable 157} 158 159define i32 @do_not_peel_readonly_load_in_header(ptr %ptr, i32 %N, ptr %inv, i1 %c.1) { 160; CHECK-LABEL: @do_not_peel_readonly_load_in_header( 161; CHECK-NEXT: entry: 162; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 163; CHECK: loop.header: 164; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 165; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 166; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4 167; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2 168; CHECK-NEXT: br i1 [[C_2]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT:%.*]] 169; CHECK: then: 170; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]] 171; CHECK: loop.latch: 172; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 173; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 174; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]] 175; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 176; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 177; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 178; CHECK: exit: 179; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ] 180; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 181; CHECK: unreachable.exit: 182; CHECK-NEXT: call void @foo() 183; CHECK-NEXT: unreachable 184; 185entry: 186 br label %loop.header 187 188loop.header: 189 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 190 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 191 %i = load i32, ptr %inv 192 %c.2 = icmp ult i32 %i, 2 193 br i1 %c.2, label %then, label %unreachable.exit 194 195then: 196 br i1 %c.1, label %loop.latch, label %unreachable.exit 197 198loop.latch: 199 %gep = getelementptr i32, ptr %ptr, i32 %iv 200 %lv = load i32, ptr %gep 201 %sum.next = add i32 %sum, %lv 202 %iv.next = add nuw nsw i32 %iv, 1 203 %c.3 = icmp ult i32 %iv, 1000 204 br i1 %c.3, label %loop.header, label %exit 205 206exit: 207 ret i32 %sum.next 208 209unreachable.exit: 210 call void @foo() 211 unreachable 212} 213 214define i32 @do_not_peel_readonly_but_wont_turn_dereferenceable(ptr %ptr, i32 %N, i32 %x, ptr %inv) { 215; CHECK-LABEL: @do_not_peel_readonly_but_wont_turn_dereferenceable( 216; CHECK-NEXT: entry: 217; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 218; CHECK: loop.header: 219; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 220; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 221; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[IV]], [[X:%.*]] 222; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]] 223; CHECK: then: 224; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4 225; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[I]], 20 226; CHECK-NEXT: br i1 [[C_2]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH]] 227; CHECK: else: 228; CHECK-NEXT: br label [[LOOP_LATCH]] 229; CHECK: loop.latch: 230; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[I]], [[THEN]] ], [ 0, [[ELSE]] ] 231; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 232; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 233; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[LV]], [[P]] 234; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[ADD_1]] 235; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 236; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 237; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 238; CHECK: exit: 239; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ] 240; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 241; CHECK: unreachable.exit: 242; CHECK-NEXT: call void @foo() 243; CHECK-NEXT: unreachable 244; 245entry: 246 br label %loop.header 247 248loop.header: 249 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 250 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 251 %c.1 = icmp eq i32 %iv, %x 252 br i1 %c.1, label %then, label %else 253 254then: 255 %i = load i32, ptr %inv 256 %c.2 = icmp eq i32 %i, 20 257 br i1 %c.2, label %unreachable.exit, label %loop.latch 258 259else: 260 br label %loop.latch 261 262loop.latch: 263 %p = phi i32 [ %i, %then ], [ 0, %else ] 264 %gep = getelementptr i32, ptr %ptr, i32 %iv 265 %lv = load i32, ptr %gep 266 %add.1 = add i32 %lv, %p 267 %sum.next = add i32 %sum, %add.1 268 %iv.next = add nuw nsw i32 %iv, 1 269 %c.3 = icmp ult i32 %iv, 1000 270 br i1 %c.3, label %loop.header, label %exit 271 272exit: 273 ret i32 %sum.next 274 275unreachable.exit: 276 call void @foo() 277 unreachable 278} 279 280define i32 @do_not_peel_write1(ptr %ptr, i32 %N, i32 %x, ptr %inv, ptr %dst, i1 %c.1) { 281; CHECK-LABEL: @do_not_peel_write1( 282; CHECK-NEXT: entry: 283; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 284; CHECK: loop.header: 285; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 286; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 287; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT:%.*]] 288; CHECK: then: 289; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4 290; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2 291; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]] 292; CHECK: loop.latch: 293; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 294; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 295; CHECK-NEXT: store i32 [[LV]], ptr [[DST:%.*]], align 4 296; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]] 297; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 298; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 299; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 300; CHECK: exit: 301; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ] 302; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 303; CHECK: unreachable.exit: 304; CHECK-NEXT: call void @foo() 305; CHECK-NEXT: unreachable 306; 307entry: 308 br label %loop.header 309 310loop.header: 311 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 312 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 313 br i1 %c.1, label %then, label %unreachable.exit 314 315then: 316 %i = load i32, ptr %inv 317 %c.2 = icmp ult i32 %i, 2 318 br i1 %c.2, label %loop.latch, label %unreachable.exit 319 320loop.latch: 321 %gep = getelementptr i32, ptr %ptr, i32 %iv 322 %lv = load i32, ptr %gep 323 store i32 %lv, ptr %dst 324 %sum.next = add i32 %sum, %lv 325 %iv.next = add nuw nsw i32 %iv, 1 326 %c.3 = icmp ult i32 %iv, 1000 327 br i1 %c.3, label %loop.header, label %exit 328 329exit: 330 ret i32 %sum.next 331 332unreachable.exit: 333 call void @foo() 334 unreachable 335} 336 337define i32 @do_not_peel_write2(ptr %ptr, i32 %N, ptr %inv, ptr %dst) { 338; CHECK-LABEL: @do_not_peel_write2( 339; CHECK-NEXT: entry: 340; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 341; CHECK: loop.header: 342; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 343; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 344; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4 345; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[I]], 20 346; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]] 347; CHECK: then: 348; CHECK-NEXT: store i32 [[I]], ptr [[DST:%.*]], align 4 349; CHECK-NEXT: br label [[LOOP_LATCH]] 350; CHECK: else: 351; CHECK-NEXT: br label [[UNREACHABLE_EXIT:%.*]] 352; CHECK: loop.latch: 353; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 354; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 355; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[LV]], [[I]] 356; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[ADD_1]] 357; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 358; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 359; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 360; CHECK: exit: 361; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ] 362; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 363; CHECK: unreachable.exit: 364; CHECK-NEXT: call void @foo() 365; CHECK-NEXT: unreachable 366; 367entry: 368 br label %loop.header 369 370loop.header: 371 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 372 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 373 %i = load i32, ptr %inv 374 %c.1 = icmp eq i32 %i, 20 375 br i1 %c.1, label %then, label %else 376 377then: 378 store i32 %i, ptr %dst 379 br label %loop.latch 380 381else: 382 br label %unreachable.exit 383 384loop.latch: 385 %gep = getelementptr i32, ptr %ptr, i32 %iv 386 %lv = load i32, ptr %gep 387 %add.1 = add i32 %lv, %i 388 %sum.next = add i32 %sum, %add.1 389 %iv.next = add nuw nsw i32 %iv, 1 390 %c.3 = icmp ult i32 %iv, 1000 391 br i1 %c.3, label %loop.header, label %exit 392 393exit: 394 ret i32 %sum.next 395 396unreachable.exit: 397 call void @foo() 398 unreachable 399} 400 401declare i32 @llvm.experimental.deoptimize.i32(...) 402 403define i32 @peel_with_deopt_exit(ptr %ptr, i32 %N, ptr %inv, i1 %c.1) { 404; CHECK-LABEL: @peel_with_deopt_exit( 405; CHECK-NEXT: entry: 406; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 407; CHECK: loop.header: 408; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 409; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 410; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[DEOPT_EXIT:%.*]] 411; CHECK: then: 412; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4 413; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2 414; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[DEOPT_EXIT]] 415; CHECK: loop.latch: 416; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 417; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 418; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]] 419; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 420; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 421; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 422; CHECK: exit: 423; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ] 424; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 425; CHECK: deopt.exit: 426; CHECK-NEXT: [[SUM_LCSSA:%.*]] = phi i32 [ [[SUM]], [[THEN]] ], [ [[SUM]], [[LOOP_HEADER]] ] 427; CHECK-NEXT: [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_LCSSA]]) ] 428; CHECK-NEXT: ret i32 [[RVAL]] 429; 430entry: 431 br label %loop.header 432 433loop.header: 434 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 435 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 436 br i1 %c.1, label %then, label %deopt.exit 437 438then: 439 %i = load i32, ptr %inv 440 %c.2 = icmp ult i32 %i, 2 441 br i1 %c.2, label %loop.latch, label %deopt.exit 442 443loop.latch: 444 %gep = getelementptr i32, ptr %ptr, i32 %iv 445 %lv = load i32, ptr %gep 446 %sum.next = add i32 %sum, %lv 447 %iv.next = add nuw nsw i32 %iv, 1 448 %c.3 = icmp ult i32 %iv, 1000 449 br i1 %c.3, label %loop.header, label %exit 450 451exit: 452 ret i32 %sum.next 453 454deopt.exit: 455 %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %sum) ] 456 ret i32 %rval 457} 458 459define i32 @do_not_peel_when_header_exiting(ptr %ptr, i32 %N, ptr %inv) { 460; CHECK-LABEL: @do_not_peel_when_header_exiting( 461; CHECK-NEXT: entry: 462; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 463; CHECK: loop.header: 464; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 465; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 466; CHECK-NEXT: [[C_1:%.*]] = icmp ult i32 [[IV]], 1000 467; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[EXIT:%.*]] 468; CHECK: then: 469; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4 470; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2 471; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT:%.*]] 472; CHECK: loop.latch: 473; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 474; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 475; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]] 476; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 477; CHECK-NEXT: br label [[LOOP_HEADER]] 478; CHECK: exit: 479; CHECK-NEXT: [[SUM_LCSSA:%.*]] = phi i32 [ [[SUM]], [[LOOP_HEADER]] ] 480; CHECK-NEXT: ret i32 [[SUM_LCSSA]] 481; CHECK: unreachable.exit: 482; CHECK-NEXT: call void @foo() 483; CHECK-NEXT: unreachable 484; 485entry: 486 br label %loop.header 487 488loop.header: 489 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 490 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 491 %c.1 = icmp ult i32 %iv, 1000 492 br i1 %c.1, label %then, label %exit 493 494then: 495 %i = load i32, ptr %inv 496 %c.2 = icmp ult i32 %i, 2 497 br i1 %c.2, label %loop.latch, label %unreachable.exit 498 499loop.latch: 500 %gep = getelementptr i32, ptr %ptr, i32 %iv 501 %lv = load i32, ptr %gep 502 %sum.next = add i32 %sum, %lv 503 %iv.next = add nuw nsw i32 %iv, 1 504 br label %loop.header 505 506exit: 507 ret i32 %sum 508 509unreachable.exit: 510 call void @foo() 511 unreachable 512} 513 514define i32 @do_not_peel_readonly_to_make_loads_derefenceable_but_does_not_control_exit(ptr %ptr, i32 %N, ptr %inv, i1 %c.1, i32 %N.2) { 515; CHECK-LABEL: @do_not_peel_readonly_to_make_loads_derefenceable_but_does_not_control_exit( 516; CHECK-NEXT: entry: 517; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 518; CHECK: loop.header: 519; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 520; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 521; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT:%.*]] 522; CHECK: then: 523; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4 524; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[IV]], [[N_2:%.*]] 525; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]] 526; CHECK: loop.latch: 527; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 528; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 529; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]] 530; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 531; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 532; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 533; CHECK: exit: 534; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ] 535; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 536; CHECK: unreachable.exit: 537; CHECK-NEXT: call void @foo() 538; CHECK-NEXT: unreachable 539; 540entry: 541 br label %loop.header 542 543loop.header: 544 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 545 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 546 br i1 %c.1, label %then, label %unreachable.exit 547 548then: 549 %i = load i32, ptr %inv 550 %c.2 = icmp ult i32 %iv, %N.2 551 br i1 %c.2, label %loop.latch, label %unreachable.exit 552 553loop.latch: 554 %gep = getelementptr i32, ptr %ptr, i32 %iv 555 %lv = load i32, ptr %gep 556 %sum.next = add i32 %sum, %lv 557 %iv.next = add nuw nsw i32 %iv, 1 558 %c.3 = icmp ult i32 %iv, 1000 559 br i1 %c.3, label %loop.header, label %exit 560 561exit: 562 ret i32 %sum.next 563 564unreachable.exit: 565 call void @foo() 566 unreachable 567} 568 569@glob = global i32 10 570 571define i32 @do_not_peel_readonly_but_already_deref_glob(ptr %ptr, i32 %N, i1 %c.1) { 572; CHECK-LABEL: @do_not_peel_readonly_but_already_deref_glob( 573; CHECK-NEXT: entry: 574; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 575; CHECK: loop.header: 576; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 577; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ] 578; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT:%.*]] 579; CHECK: then: 580; CHECK-NEXT: [[I:%.*]] = load i32, ptr @glob, align 4 581; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2 582; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]] 583; CHECK: loop.latch: 584; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 585; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 586; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]] 587; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 588; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 589; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 590; CHECK: exit: 591; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ] 592; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]] 593; CHECK: unreachable.exit: 594; CHECK-NEXT: call void @foo() 595; CHECK-NEXT: unreachable 596; 597entry: 598 br label %loop.header 599 600loop.header: 601 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 602 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ] 603 br i1 %c.1, label %then, label %unreachable.exit 604 605then: 606 %i = load i32, ptr @glob 607 %c.2 = icmp ult i32 %i, 2 608 br i1 %c.2, label %loop.latch, label %unreachable.exit 609 610loop.latch: 611 %gep = getelementptr i32, ptr %ptr, i32 %iv 612 %lv = load i32, ptr %gep 613 %sum.next = add i32 %sum, %lv 614 %iv.next = add nuw nsw i32 %iv, 1 615 %c.3 = icmp ult i32 %iv, 1000 616 br i1 %c.3, label %loop.header, label %exit 617 618exit: 619 ret i32 %sum.next 620 621unreachable.exit: 622 call void @foo() 623 unreachable 624} 625