1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s 3 4declare void @clobber() 5 6define i32 @partial_unswitch_true_successor(ptr %ptr, i32 %N) { 7; CHECK-LABEL: @partial_unswitch_true_successor( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4 10; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 11; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 12; CHECK: entry.split.us: 13; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 14; CHECK: loop.header.us: 15; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 16; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 17; CHECK: noclobber.us: 18; CHECK-NEXT: br label [[LOOP_LATCH_US]] 19; CHECK: loop.latch.us: 20; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 21; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 22; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 23; CHECK: exit.split.us: 24; CHECK-NEXT: br label [[EXIT:%.*]] 25; CHECK: entry.split: 26; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 27; CHECK: loop.header: 28; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 29; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 30; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 31; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 32; CHECK: noclobber: 33; CHECK-NEXT: br label [[LOOP_LATCH]] 34; CHECK: clobber: 35; CHECK-NEXT: call void @clobber() 36; CHECK-NEXT: br label [[LOOP_LATCH]] 37; CHECK: loop.latch: 38; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 39; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 40; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]] 41; CHECK: exit.split: 42; CHECK-NEXT: br label [[EXIT]] 43; CHECK: exit: 44; CHECK-NEXT: ret i32 10 45; 46entry: 47 br label %loop.header 48 49loop.header: 50 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 51 %lv = load i32, ptr %ptr 52 %sc = icmp eq i32 %lv, 100 53 br i1 %sc, label %noclobber, label %clobber 54 55noclobber: 56 br label %loop.latch 57 58clobber: 59 call void @clobber() 60 br label %loop.latch 61 62loop.latch: 63 %c = icmp ult i32 %iv, %N 64 %iv.next = add i32 %iv, 1 65 br i1 %c, label %loop.header, label %exit 66 67exit: 68 ret i32 10 69} 70 71define i32 @partial_unswitch_false_successor(ptr %ptr, i32 %N) { 72; CHECK-LABEL: @partial_unswitch_false_successor( 73; CHECK-NEXT: entry: 74; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4 75; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 76; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]] 77; CHECK: entry.split.us: 78; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 79; CHECK: loop.header.us: 80; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 81; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 82; CHECK: noclobber.us: 83; CHECK-NEXT: br label [[LOOP_LATCH_US]] 84; CHECK: loop.latch.us: 85; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 86; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 87; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 88; CHECK: exit.split.us: 89; CHECK-NEXT: br label [[EXIT:%.*]] 90; CHECK: entry.split: 91; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 92; CHECK: loop.header: 93; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 94; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 95; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 96; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 97; CHECK: clobber: 98; CHECK-NEXT: call void @clobber() 99; CHECK-NEXT: br label [[LOOP_LATCH]] 100; CHECK: noclobber: 101; CHECK-NEXT: br label [[LOOP_LATCH]] 102; CHECK: loop.latch: 103; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 104; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 105; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP2:![0-9]+]] 106; CHECK: exit.split: 107; CHECK-NEXT: br label [[EXIT]] 108; CHECK: exit: 109; CHECK-NEXT: ret i32 10 110; 111entry: 112 br label %loop.header 113 114loop.header: 115 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 116 %lv = load i32, ptr %ptr 117 %sc = icmp eq i32 %lv, 100 118 br i1 %sc, label %clobber, label %noclobber 119 120clobber: 121 call void @clobber() 122 br label %loop.latch 123 124noclobber: 125 br label %loop.latch 126 127loop.latch: 128 %c = icmp ult i32 %iv, %N 129 %iv.next = add i32 %iv, 1 130 br i1 %c, label %loop.header, label %exit 131 132exit: 133 ret i32 10 134} 135 136define i32 @partial_unswtich_gep_load_icmp(ptr %ptr, i32 %N) { 137; CHECK-LABEL: @partial_unswtich_gep_load_icmp( 138; CHECK-NEXT: entry: 139; CHECK-NEXT: [[TMP0:%.*]] = getelementptr ptr, ptr [[PTR:%.*]], i32 1 140; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8 141; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4 142; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 100 143; CHECK-NEXT: br i1 [[TMP3]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 144; CHECK: entry.split.us: 145; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 146; CHECK: loop.header.us: 147; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 148; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 149; CHECK: noclobber.us: 150; CHECK-NEXT: br label [[LOOP_LATCH_US]] 151; CHECK: loop.latch.us: 152; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 153; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 154; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 155; CHECK: exit.split.us: 156; CHECK-NEXT: br label [[EXIT:%.*]] 157; CHECK: entry.split: 158; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 159; CHECK: loop.header: 160; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 161; CHECK-NEXT: [[GEP:%.*]] = getelementptr ptr, ptr [[PTR]], i32 1 162; CHECK-NEXT: [[LV_1:%.*]] = load ptr, ptr [[GEP]], align 8 163; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[LV_1]], align 4 164; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 165; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 166; CHECK: noclobber: 167; CHECK-NEXT: br label [[LOOP_LATCH]] 168; CHECK: clobber: 169; CHECK-NEXT: call void @clobber() 170; CHECK-NEXT: br label [[LOOP_LATCH]] 171; CHECK: loop.latch: 172; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 173; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 174; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]] 175; CHECK: exit.split: 176; CHECK-NEXT: br label [[EXIT]] 177; CHECK: exit: 178; CHECK-NEXT: ret i32 10 179; 180entry: 181 br label %loop.header 182 183loop.header: 184 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 185 %gep = getelementptr ptr, ptr %ptr, i32 1 186 %lv.1 = load ptr, ptr %gep 187 %lv = load i32, ptr %lv.1 188 %sc = icmp eq i32 %lv, 100 189 br i1 %sc, label %noclobber, label %clobber 190 191noclobber: 192 br label %loop.latch 193 194clobber: 195 call void @clobber() 196 br label %loop.latch 197 198loop.latch: 199 %c = icmp ult i32 %iv, %N 200 %iv.next = add i32 %iv, 1 201 br i1 %c, label %loop.header, label %exit 202 203exit: 204 ret i32 10 205} 206 207define i32 @partial_unswitch_reduction_phi(ptr %ptr, i32 %N) { 208; CHECK-LABEL: @partial_unswitch_reduction_phi( 209; CHECK-NEXT: entry: 210; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4 211; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 212; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]] 213; CHECK: entry.split.us: 214; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 215; CHECK: loop.header.us: 216; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 217; CHECK-NEXT: [[RED_US:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT_US]] ], [ [[RED_NEXT_US:%.*]], [[LOOP_LATCH_US]] ] 218; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 219; CHECK: noclobber.us: 220; CHECK-NEXT: [[ADD_10_US:%.*]] = add i32 [[RED_US]], 10 221; CHECK-NEXT: br label [[LOOP_LATCH_US]] 222; CHECK: loop.latch.us: 223; CHECK-NEXT: [[RED_NEXT_US]] = phi i32 [ [[ADD_10_US]], [[NOCLOBBER_US]] ] 224; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 225; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 226; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 227; CHECK: exit.split.us: 228; CHECK-NEXT: [[RED_NEXT_LCSSA_US:%.*]] = phi i32 [ [[RED_NEXT_US]], [[LOOP_LATCH_US]] ] 229; CHECK-NEXT: br label [[EXIT:%.*]] 230; CHECK: entry.split: 231; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 232; CHECK: loop.header: 233; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 234; CHECK-NEXT: [[RED:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT]] ], [ [[RED_NEXT:%.*]], [[LOOP_LATCH]] ] 235; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 236; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 237; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 238; CHECK: clobber: 239; CHECK-NEXT: call void @clobber() 240; CHECK-NEXT: [[ADD_5:%.*]] = add i32 [[RED]], 5 241; CHECK-NEXT: br label [[LOOP_LATCH]] 242; CHECK: noclobber: 243; CHECK-NEXT: [[ADD_10:%.*]] = add i32 [[RED]], 10 244; CHECK-NEXT: br label [[LOOP_LATCH]] 245; CHECK: loop.latch: 246; CHECK-NEXT: [[RED_NEXT]] = phi i32 [ [[ADD_5]], [[CLOBBER]] ], [ [[ADD_10]], [[NOCLOBBER]] ] 247; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 248; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 249; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP4:![0-9]+]] 250; CHECK: exit.split: 251; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ] 252; CHECK-NEXT: br label [[EXIT]] 253; CHECK: exit: 254; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RED_NEXT_LCSSA]], [[EXIT_SPLIT]] ], [ [[RED_NEXT_LCSSA_US]], [[EXIT_SPLIT_US]] ] 255; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 256; 257entry: 258 br label %loop.header 259 260loop.header: 261 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 262 %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ] 263 %lv = load i32, ptr %ptr 264 %sc = icmp eq i32 %lv, 100 265 br i1 %sc, label %clobber, label %noclobber 266 267clobber: 268 call void @clobber() 269 %add.5 = add i32 %red, 5 270 br label %loop.latch 271 272noclobber: 273 %add.10 = add i32 %red, 10 274 br label %loop.latch 275 276loop.latch: 277 %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ] 278 %c = icmp ult i32 %iv, %N 279 %iv.next = add i32 %iv, 1 280 br i1 %c, label %loop.header, label %exit 281 282exit: 283 %red.next.lcssa = phi i32 [ %red.next, %loop.latch ] 284 ret i32 %red.next.lcssa 285} 286 287; Partial unswitching is possible, because the store in %noclobber does not 288; alias the load of the condition. 289define i32 @partial_unswitch_true_successor_noclobber(ptr noalias %ptr.1, ptr noalias %ptr.2, i32 %N) { 290; CHECK-LABEL: @partial_unswitch_true_successor_noclobber( 291; CHECK-NEXT: entry: 292; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR_1:%.*]], align 4 293; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 294; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 295; CHECK: entry.split.us: 296; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 297; CHECK: loop.header.us: 298; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 299; CHECK-NEXT: [[LV_US:%.*]] = load i32, ptr [[PTR_1]], align 4 300; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 301; CHECK: noclobber.us: 302; CHECK-NEXT: [[GEP_1_US:%.*]] = getelementptr i32, ptr [[PTR_2:%.*]], i32 [[IV_US]] 303; CHECK-NEXT: store i32 [[LV_US]], ptr [[GEP_1_US]], align 4 304; CHECK-NEXT: br label [[LOOP_LATCH_US]] 305; CHECK: loop.latch.us: 306; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 307; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 308; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 309; CHECK: exit.split.us: 310; CHECK-NEXT: br label [[EXIT:%.*]] 311; CHECK: entry.split: 312; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 313; CHECK: loop.header: 314; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 315; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR_1]], align 4 316; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 317; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 318; CHECK: noclobber: 319; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[PTR_2]], i32 [[IV]] 320; CHECK-NEXT: store i32 [[LV]], ptr [[GEP_1]], align 4 321; CHECK-NEXT: br label [[LOOP_LATCH]] 322; CHECK: clobber: 323; CHECK-NEXT: call void @clobber() 324; CHECK-NEXT: br label [[LOOP_LATCH]] 325; CHECK: loop.latch: 326; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 327; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 328; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP5:![0-9]+]] 329; CHECK: exit.split: 330; CHECK-NEXT: br label [[EXIT]] 331; CHECK: exit: 332; CHECK-NEXT: ret i32 10 333; 334entry: 335 br label %loop.header 336 337loop.header: 338 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 339 %lv = load i32, ptr %ptr.1 340 %sc = icmp eq i32 %lv, 100 341 br i1 %sc, label %noclobber, label %clobber 342 343noclobber: 344 %gep.1 = getelementptr i32, ptr %ptr.2, i32 %iv 345 store i32 %lv, ptr %gep.1 346 br label %loop.latch 347 348clobber: 349 call void @clobber() 350 br label %loop.latch 351 352loop.latch: 353 %c = icmp ult i32 %iv, %N 354 %iv.next = add i32 %iv, 1 355 br i1 %c, label %loop.header, label %exit 356 357exit: 358 ret i32 10 359} 360 361define void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) { 362; CHECK-LABEL: @no_partial_unswitch_phi_cond( 363; CHECK-NEXT: entry: 364; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 365; CHECK: loop.header: 366; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 367; CHECK-NEXT: [[SC:%.*]] = phi i1 [ [[LC:%.*]], [[ENTRY]] ], [ true, [[LOOP_LATCH]] ] 368; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 369; CHECK: clobber: 370; CHECK-NEXT: call void @clobber() 371; CHECK-NEXT: br label [[LOOP_LATCH]] 372; CHECK: noclobber: 373; CHECK-NEXT: br label [[LOOP_LATCH]] 374; CHECK: loop.latch: 375; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 376; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 377; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 378; CHECK: exit: 379; CHECK-NEXT: ret void 380; 381entry: 382 br label %loop.header 383 384loop.header: 385 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 386 %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ] 387 br i1 %sc, label %clobber, label %noclobber 388 389clobber: 390 call void @clobber() 391 br label %loop.latch 392 393noclobber: 394 br label %loop.latch 395 396loop.latch: 397 %c = icmp ult i32 %iv, %N 398 %iv.next = add i32 %iv, 1 399 br i1 %c, label %loop.header, label %exit 400 401exit: 402 ret void 403} 404 405define void @no_partial_unswitch_clobber_latch(ptr %ptr, i32 %N) { 406; CHECK-LABEL: @no_partial_unswitch_clobber_latch( 407; CHECK-NEXT: entry: 408; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 409; CHECK: loop.header: 410; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 411; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4 412; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 413; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 414; CHECK: noclobber: 415; CHECK-NEXT: br label [[LOOP_LATCH]] 416; CHECK: clobber: 417; CHECK-NEXT: call void @clobber() 418; CHECK-NEXT: br label [[LOOP_LATCH]] 419; CHECK: loop.latch: 420; CHECK-NEXT: call void @clobber() 421; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 422; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 423; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 424; CHECK: exit: 425; CHECK-NEXT: ret void 426; 427entry: 428 br label %loop.header 429 430loop.header: 431 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 432 %lv = load i32, ptr %ptr 433 %sc = icmp eq i32 %lv, 100 434 br i1 %sc, label %noclobber, label %clobber 435 436noclobber: 437 br label %loop.latch 438 439clobber: 440 call void @clobber() 441 br label %loop.latch 442 443loop.latch: 444 call void @clobber() 445 %c = icmp ult i32 %iv, %N 446 %iv.next = add i32 %iv, 1 447 br i1 %c, label %loop.header, label %exit 448 449exit: 450 ret void 451} 452 453define void @no_partial_unswitch_clobber_header(ptr %ptr, i32 %N) { 454; CHECK-LABEL: @no_partial_unswitch_clobber_header( 455; CHECK-NEXT: entry: 456; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 457; CHECK: loop.header: 458; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 459; CHECK-NEXT: call void @clobber() 460; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4 461; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 462; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 463; CHECK: noclobber: 464; CHECK-NEXT: br label [[LOOP_LATCH]] 465; CHECK: clobber: 466; CHECK-NEXT: call void @clobber() 467; CHECK-NEXT: br label [[LOOP_LATCH]] 468; CHECK: loop.latch: 469; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 470; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 471; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 472; CHECK: exit: 473; CHECK-NEXT: ret void 474; 475entry: 476 br label %loop.header 477 478loop.header: 479 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 480 call void @clobber() 481 %lv = load i32, ptr %ptr 482 %sc = icmp eq i32 %lv, 100 483 br i1 %sc, label %noclobber, label %clobber 484 485noclobber: 486 br label %loop.latch 487 488clobber: 489 call void @clobber() 490 br label %loop.latch 491 492loop.latch: 493 %c = icmp ult i32 %iv, %N 494 %iv.next = add i32 %iv, 1 495 br i1 %c, label %loop.header, label %exit 496 497exit: 498 ret void 499} 500 501define void @no_partial_unswitch_clobber_both(ptr %ptr, i32 %N) { 502; CHECK-LABEL: @no_partial_unswitch_clobber_both( 503; CHECK-NEXT: entry: 504; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 505; CHECK: loop.header: 506; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 507; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4 508; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 509; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 510; CHECK: noclobber: 511; CHECK-NEXT: call void @clobber() 512; CHECK-NEXT: br label [[LOOP_LATCH]] 513; CHECK: clobber: 514; CHECK-NEXT: call void @clobber() 515; CHECK-NEXT: br label [[LOOP_LATCH]] 516; CHECK: loop.latch: 517; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 518; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 519; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 520; CHECK: exit: 521; CHECK-NEXT: ret void 522; 523entry: 524 br label %loop.header 525 526loop.header: 527 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 528 %lv = load i32, ptr %ptr 529 %sc = icmp eq i32 %lv, 100 530 br i1 %sc, label %noclobber, label %clobber 531 532noclobber: 533 call void @clobber() 534 br label %loop.latch 535 536clobber: 537 call void @clobber() 538 br label %loop.latch 539 540loop.latch: 541 %c = icmp ult i32 %iv, %N 542 %iv.next = add i32 %iv, 1 543 br i1 %c, label %loop.header, label %exit 544 545exit: 546 ret void 547} 548 549define i32 @no_partial_unswitch_true_successor_storeclobber(ptr %ptr.1, ptr %ptr.2, i32 %N) { 550; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber( 551; CHECK-NEXT: entry: 552; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 553; CHECK: loop.header: 554; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 555; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR_1:%.*]], align 4 556; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 557; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 558; CHECK: noclobber: 559; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[PTR_2:%.*]], i32 [[IV]] 560; CHECK-NEXT: store i32 [[LV]], ptr [[GEP_1]], align 4 561; CHECK-NEXT: br label [[LOOP_LATCH]] 562; CHECK: clobber: 563; CHECK-NEXT: call void @clobber() 564; CHECK-NEXT: br label [[LOOP_LATCH]] 565; CHECK: loop.latch: 566; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 567; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 568; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 569; CHECK: exit: 570; CHECK-NEXT: ret i32 10 571; 572entry: 573 br label %loop.header 574 575loop.header: 576 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 577 %lv = load i32, ptr %ptr.1 578 %sc = icmp eq i32 %lv, 100 579 br i1 %sc, label %noclobber, label %clobber 580 581noclobber: 582 %gep.1 = getelementptr i32, ptr %ptr.2, i32 %iv 583 store i32 %lv, ptr %gep.1 584 br label %loop.latch 585 586clobber: 587 call void @clobber() 588 br label %loop.latch 589 590loop.latch: 591 %c = icmp ult i32 %iv, %N 592 %iv.next = add i32 %iv, 1 593 br i1 %c, label %loop.header, label %exit 594 595exit: 596 ret i32 10 597} 598 599; Make sure the duplicated instructions are moved to a preheader that always 600; executes when the loop body also executes. Do not check the unswitched code, 601; because it is already checked in the @partial_unswitch_true_successor test 602; case. 603define i32 @partial_unswitch_true_successor_preheader_insertion(ptr %ptr, i32 %N) { 604; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion( 605; CHECK-NEXT: entry: 606; CHECK-NEXT: [[EC:%.*]] = icmp ne ptr [[PTR:%.*]], null 607; CHECK-NEXT: br i1 [[EC]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]] 608; CHECK: loop.ph: 609; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR]], align 4 610; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 611; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PH_SPLIT_US:%.*]], label [[LOOP_PH_SPLIT:%.*]] 612; CHECK: loop.ph.split.us: 613; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 614; CHECK: loop.header.us: 615; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 616; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 617; CHECK: noclobber.us: 618; CHECK-NEXT: br label [[LOOP_LATCH_US]] 619; CHECK: loop.latch.us: 620; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 621; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 622; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_LOOPEXIT_SPLIT_US:%.*]] 623; CHECK: exit.loopexit.split.us: 624; CHECK-NEXT: br label [[EXIT_LOOPEXIT:%.*]] 625; CHECK: loop.ph.split: 626; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 627; CHECK: loop.header: 628; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 629; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 630; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 631; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 632; CHECK: noclobber: 633; CHECK-NEXT: br label [[LOOP_LATCH]] 634; CHECK: clobber: 635; CHECK-NEXT: call void @clobber() 636; CHECK-NEXT: br label [[LOOP_LATCH]] 637; CHECK: loop.latch: 638; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 639; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 640; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT_SPLIT:%.*]], !llvm.loop [[LOOP6:![0-9]+]] 641; CHECK: exit.loopexit.split: 642; CHECK-NEXT: br label [[EXIT_LOOPEXIT]] 643; CHECK: exit.loopexit: 644; CHECK-NEXT: br label [[EXIT]] 645; CHECK: exit: 646; CHECK-NEXT: ret i32 10 647; 648 649entry: 650 %ec = icmp ne ptr %ptr, null 651 br i1 %ec, label %loop.ph, label %exit 652 653loop.ph: 654 br label %loop.header 655 656loop.header: 657 %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ] 658 %lv = load i32, ptr %ptr 659 %sc = icmp eq i32 %lv, 100 660 br i1 %sc, label %noclobber, label %clobber 661 662noclobber: 663 br label %loop.latch 664 665clobber: 666 call void @clobber() 667 br label %loop.latch 668 669loop.latch: 670 %c = icmp ult i32 %iv, %N 671 %iv.next = add i32 %iv, 1 672 br i1 %c, label %loop.header, label %exit 673 674exit: 675 ret i32 10 676} 677 678; Make sure the duplicated instructions are hoisted just before the branch of 679; the preheader. Do not check the unswitched code, because it is already checked 680; in the @partial_unswitch_true_successor test case 681define i32 @partial_unswitch_true_successor_insert_point(ptr %ptr, i32 %N) { 682; CHECK-LABEL: @partial_unswitch_true_successor_insert_point( 683; CHECK-NEXT: entry: 684; CHECK-NEXT: call void @clobber() 685; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4 686; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 687; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 688; CHECK: entry.split.us: 689; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 690; CHECK: loop.header.us: 691; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 692; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 693; CHECK: noclobber.us: 694; CHECK-NEXT: br label [[LOOP_LATCH_US]] 695; CHECK: loop.latch.us: 696; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 697; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 698; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 699; CHECK: exit.split.us: 700; CHECK-NEXT: br label [[EXIT:%.*]] 701; CHECK: entry.split: 702; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 703; CHECK: loop.header: 704; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 705; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 706; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 707; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 708; CHECK: noclobber: 709; CHECK-NEXT: br label [[LOOP_LATCH]] 710; CHECK: clobber: 711; CHECK-NEXT: call void @clobber() 712; CHECK-NEXT: br label [[LOOP_LATCH]] 713; CHECK: loop.latch: 714; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 715; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 716; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP7:![0-9]+]] 717; CHECK: exit.split: 718; CHECK-NEXT: br label [[EXIT]] 719; CHECK: exit: 720; CHECK-NEXT: ret i32 10 721; 722entry: 723 call void @clobber() 724 br label %loop.header 725 726loop.header: 727 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 728 %lv = load i32, ptr %ptr 729 %sc = icmp eq i32 %lv, 100 730 br i1 %sc, label %noclobber, label %clobber 731 732noclobber: 733 br label %loop.latch 734 735clobber: 736 call void @clobber() 737 br label %loop.latch 738 739loop.latch: 740 %c = icmp ult i32 %iv, %N 741 %iv.next = add i32 %iv, 1 742 br i1 %c, label %loop.header, label %exit 743 744exit: 745 ret i32 10 746} 747 748; Make sure invariant instructions in the loop are also hoisted to the preheader. 749; Do not check the unswitched code, because it is already checked in the 750; @partial_unswitch_true_successor test case 751define i32 @partial_unswitch_true_successor_hoist_invariant(ptr %ptr, i32 %N) { 752; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant( 753; CHECK-NEXT: entry: 754; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i64 1 755; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 756; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 100 757; CHECK-NEXT: br i1 [[TMP2]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 758; CHECK: entry.split.us: 759; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 760; CHECK: loop.header.us: 761; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 762; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 763; CHECK: noclobber.us: 764; CHECK-NEXT: br label [[LOOP_LATCH_US]] 765; CHECK: loop.latch.us: 766; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 767; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 768; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 769; CHECK: exit.split.us: 770; CHECK-NEXT: br label [[EXIT:%.*]] 771; CHECK: entry.split: 772; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 773; CHECK: loop.header: 774; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 775; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i64 1 776; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4 777; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 778; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 779; CHECK: noclobber: 780; CHECK-NEXT: br label [[LOOP_LATCH]] 781; CHECK: clobber: 782; CHECK-NEXT: call void @clobber() 783; CHECK-NEXT: br label [[LOOP_LATCH]] 784; CHECK: loop.latch: 785; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 786; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 787; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]] 788; CHECK: exit.split: 789; CHECK-NEXT: br label [[EXIT]] 790; CHECK: exit: 791; CHECK-NEXT: ret i32 10 792; 793entry: 794 br label %loop.header 795 796loop.header: 797 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 798 %gep = getelementptr i32, ptr %ptr, i64 1 799 %lv = load i32, ptr %gep 800 %sc = icmp eq i32 %lv, 100 801 br i1 %sc, label %noclobber, label %clobber 802 803noclobber: 804 br label %loop.latch 805 806clobber: 807 call void @clobber() 808 br label %loop.latch 809 810loop.latch: 811 %c = icmp ult i32 %iv, %N 812 %iv.next = add i32 %iv, 1 813 br i1 %c, label %loop.header, label %exit 814 815exit: 816 ret i32 10 817} 818 819; Do not unswitch if the condition depends on an atomic load. Duplicating such 820; loads is not safe. 821define i32 @no_partial_unswitch_atomic_load_unordered(ptr %ptr, i32 %N) { 822; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered( 823; CHECK-NEXT: entry: 824; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 825; CHECK: loop.header: 826; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 827; CHECK-NEXT: [[LV:%.*]] = load atomic i32, ptr [[PTR:%.*]] unordered, align 4 828; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 829; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 830; CHECK: noclobber: 831; CHECK-NEXT: br label [[LOOP_LATCH]] 832; CHECK: clobber: 833; CHECK-NEXT: call void @clobber() 834; CHECK-NEXT: br label [[LOOP_LATCH]] 835; CHECK: loop.latch: 836; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 837; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 838; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 839; CHECK: exit: 840; CHECK-NEXT: ret i32 10 841; 842entry: 843 br label %loop.header 844 845loop.header: 846 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 847 %lv = load atomic i32, ptr %ptr unordered, align 4 848 %sc = icmp eq i32 %lv, 100 849 br i1 %sc, label %noclobber, label %clobber 850 851noclobber: 852 br label %loop.latch 853 854clobber: 855 call void @clobber() 856 br label %loop.latch 857 858loop.latch: 859 %c = icmp ult i32 %iv, %N 860 %iv.next = add i32 %iv, 1 861 br i1 %c, label %loop.header, label %exit 862 863exit: 864 ret i32 10 865} 866 867; Do not unswitch if the condition depends on an atomic load. Duplicating such 868; loads is not safe. 869define i32 @no_partial_unswitch_atomic_load_monotonic(ptr %ptr, i32 %N) { 870; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic( 871; CHECK-NEXT: entry: 872; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 873; CHECK: loop.header: 874; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 875; CHECK-NEXT: [[LV:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4 876; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 877; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 878; CHECK: noclobber: 879; CHECK-NEXT: br label [[LOOP_LATCH]] 880; CHECK: clobber: 881; CHECK-NEXT: call void @clobber() 882; CHECK-NEXT: br label [[LOOP_LATCH]] 883; CHECK: loop.latch: 884; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 885; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 886; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 887; CHECK: exit: 888; CHECK-NEXT: ret i32 10 889; 890entry: 891 br label %loop.header 892 893loop.header: 894 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 895 %lv = load atomic i32, ptr %ptr monotonic, align 4 896 %sc = icmp eq i32 %lv, 100 897 br i1 %sc, label %noclobber, label %clobber 898 899noclobber: 900 br label %loop.latch 901 902clobber: 903 call void @clobber() 904 br label %loop.latch 905 906loop.latch: 907 %c = icmp ult i32 %iv, %N 908 %iv.next = add i32 %iv, 1 909 br i1 %c, label %loop.header, label %exit 910 911exit: 912 ret i32 10 913} 914 915 916declare i32 @get_value() 917 918; Do not unswitch if the condition depends on a call, that may clobber memory. 919; Duplicating such a call is not safe. 920define i32 @no_partial_unswitch_cond_call(ptr %ptr, i32 %N) { 921; CHECK-LABEL: @no_partial_unswitch_cond_call( 922; CHECK-NEXT: entry: 923; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 924; CHECK: loop.header: 925; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 926; CHECK-NEXT: [[LV:%.*]] = call i32 @get_value() 927; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 928; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 929; CHECK: noclobber: 930; CHECK-NEXT: br label [[LOOP_LATCH]] 931; CHECK: clobber: 932; CHECK-NEXT: call void @clobber() 933; CHECK-NEXT: br label [[LOOP_LATCH]] 934; CHECK: loop.latch: 935; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 936; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 937; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 938; CHECK: exit: 939; CHECK-NEXT: ret i32 10 940; 941entry: 942 br label %loop.header 943 944loop.header: 945 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 946 %lv = call i32 @get_value() 947 %sc = icmp eq i32 %lv, 100 948 br i1 %sc, label %noclobber, label %clobber 949 950noclobber: 951 br label %loop.latch 952 953clobber: 954 call void @clobber() 955 br label %loop.latch 956 957loop.latch: 958 %c = icmp ult i32 %iv, %N 959 %iv.next = add i32 %iv, 1 960 br i1 %c, label %loop.header, label %exit 961 962exit: 963 ret i32 10 964} 965 966define i32 @no_partial_unswitch_true_successor_exit(ptr %ptr, i32 %N) { 967; CHECK-LABEL: @no_partial_unswitch_true_successor_exit( 968; CHECK-NEXT: entry: 969; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 970; CHECK: loop.header: 971; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 972; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4 973; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 974; CHECK-NEXT: br i1 [[SC]], label [[EXIT:%.*]], label [[CLOBBER:%.*]] 975; CHECK: clobber: 976; CHECK-NEXT: call void @clobber() 977; CHECK-NEXT: br label [[LOOP_LATCH]] 978; CHECK: loop.latch: 979; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 980; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 981; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT]] 982; CHECK: exit: 983; CHECK-NEXT: ret i32 10 984; 985entry: 986 br label %loop.header 987 988loop.header: 989 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 990 %lv = load i32, ptr %ptr 991 %sc = icmp eq i32 %lv, 100 992 br i1 %sc, label %exit, label %clobber 993 994clobber: 995 call void @clobber() 996 br label %loop.latch 997 998loop.latch: 999 %c = icmp ult i32 %iv, %N 1000 %iv.next = add i32 %iv, 1 1001 br i1 %c, label %loop.header, label %exit 1002 1003exit: 1004 ret i32 10 1005} 1006 1007define i32 @no_partial_unswitch_true_same_successor(ptr %ptr, i32 %N) { 1008; CHECK-LABEL: @no_partial_unswitch_true_same_successor( 1009; CHECK-NEXT: entry: 1010; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 1011; CHECK: loop.header: 1012; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 1013; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4 1014; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 1015; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[NOCLOBBER]] 1016; CHECK: noclobber: 1017; CHECK-NEXT: br label [[LOOP_LATCH]] 1018; CHECK: loop.latch: 1019; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 1020; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 1021; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 1022; CHECK: exit: 1023; CHECK-NEXT: ret i32 10 1024; 1025entry: 1026 br label %loop.header 1027 1028loop.header: 1029 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 1030 %lv = load i32, ptr %ptr 1031 %sc = icmp eq i32 %lv, 100 1032 br i1 %sc, label %noclobber, label %noclobber 1033 1034noclobber: 1035 br label %loop.latch 1036 1037loop.latch: 1038 %c = icmp ult i32 %iv, %N 1039 %iv.next = add i32 %iv, 1 1040 br i1 %c, label %loop.header, label %exit 1041 1042exit: 1043 ret i32 10 1044} 1045 1046define i32 @partial_unswitch_true_to_latch(ptr %ptr, i32 %N) { 1047; CHECK-LABEL: @partial_unswitch_true_to_latch( 1048; CHECK-NEXT: entry: 1049; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4 1050; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 1051; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 1052; CHECK: entry.split.us: 1053; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 1054; CHECK: loop.header.us: 1055; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 1056; CHECK-NEXT: br label [[LOOP_LATCH_US]] 1057; CHECK: loop.latch.us: 1058; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 1059; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 1060; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 1061; CHECK: exit.split.us: 1062; CHECK-NEXT: br label [[EXIT:%.*]] 1063; CHECK: entry.split: 1064; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 1065; CHECK: loop.header: 1066; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 1067; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 1068; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 1069; CHECK-NEXT: br i1 [[SC]], label [[LOOP_LATCH]], label [[CLOBBER:%.*]] 1070; CHECK: clobber: 1071; CHECK-NEXT: call void @clobber() 1072; CHECK-NEXT: br label [[LOOP_LATCH]] 1073; CHECK: loop.latch: 1074; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 1075; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 1076; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP9:![0-9]+]] 1077; CHECK: exit.split: 1078; CHECK-NEXT: br label [[EXIT]] 1079; CHECK: exit: 1080; CHECK-NEXT: ret i32 10 1081; 1082entry: 1083 br label %loop.header 1084 1085loop.header: 1086 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 1087 %lv = load i32, ptr %ptr 1088 %sc = icmp eq i32 %lv, 100 1089 br i1 %sc, label %loop.latch, label %clobber 1090 1091clobber: 1092 call void @clobber() 1093 br label %loop.latch 1094 1095loop.latch: 1096 %c = icmp ult i32 %iv, %N 1097 %iv.next = add i32 %iv, 1 1098 br i1 %c, label %loop.header, label %exit 1099 1100exit: 1101 ret i32 10 1102} 1103 1104; There could be multiple unswitch candidates which include partially invariant 1105; condition. When the exiting block is selected as best unswitch one, clone loop 1106; blocks. 1107define i32 @partial_unswitch_exiting_block_with_multiple_unswitch_candidates(i32 %0, i32 %1, ptr %ptr) { 1108; CHECK-LABEL: @partial_unswitch_exiting_block_with_multiple_unswitch_candidates( 1109; CHECK-NEXT: entry: 1110; CHECK-NEXT: [[EXIT_COND:%.*]] = icmp ne i32 [[TMP0:%.*]], 0 1111; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[PTR:%.*]], align 16 1112; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[TMP2]], 41 1113; CHECK-NEXT: br i1 [[TMP3]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]] 1114; CHECK: entry.split.us: 1115; CHECK-NEXT: br i1 [[EXIT_COND]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]], label [[ENTRY_SPLIT_US_SPLIT:%.*]] 1116; CHECK: entry.split.us.split.us: 1117; CHECK-NEXT: br label [[LOOP_US_US:%.*]] 1118; CHECK: loop.us.us: 1119; CHECK-NEXT: br label [[EXITING_US_US:%.*]] 1120; CHECK: exiting.us.us: 1121; CHECK-NEXT: br label [[LOOP_US_US]] 1122; CHECK: entry.split.us.split: 1123; CHECK-NEXT: br label [[LOOP_US:%.*]] 1124; CHECK: loop.us: 1125; CHECK-NEXT: br label [[EXITING_US:%.*]] 1126; CHECK: exiting.us: 1127; CHECK-NEXT: br label [[EXIT_SPLIT_US:%.*]] 1128; CHECK: exit.split.us: 1129; CHECK-NEXT: [[RET_VAL_US:%.*]] = phi i32 [ 1, [[EXITING_US]] ] 1130; CHECK-NEXT: br label [[EXIT:%.*]] 1131; CHECK: entry.split: 1132; CHECK-NEXT: br label [[LOOP:%.*]] 1133; CHECK: loop: 1134; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[PTR]], align 16 1135; CHECK-NEXT: [[IF_COND:%.*]] = icmp ult i32 [[VAL]], 41 1136; CHECK-NEXT: br i1 [[IF_COND]], label [[IF_THEN:%.*]], label [[EXITING:%.*]] 1137; CHECK: if.then: 1138; CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[PTR]], align 16 1139; CHECK-NEXT: br label [[EXITING]] 1140; CHECK: exiting: 1141; CHECK-NEXT: br i1 [[EXIT_COND]], label [[LOOP]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP10:![0-9]+]] 1142; CHECK: exit.split: 1143; CHECK-NEXT: [[RET_VAL:%.*]] = phi i32 [ 1, [[EXITING]] ] 1144; CHECK-NEXT: br label [[EXIT]] 1145; CHECK: exit: 1146; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RET_VAL]], [[EXIT_SPLIT]] ], [ [[RET_VAL_US]], [[EXIT_SPLIT_US]] ] 1147; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 1148; 1149entry: 1150 %exit.cond = icmp ne i32 %0, 0 1151 br label %loop 1152 1153loop: 1154 %val = load i32, ptr %ptr, align 16 1155 %if.cond = icmp ult i32 %val, 41 1156 br i1 %if.cond, label %if.then, label %exiting 1157 1158if.then: 1159 store i32 %1, ptr %ptr, align 16 1160 br label %exiting 1161 1162exiting: 1163 br i1 %exit.cond, label %loop, label %exit 1164 1165exit: 1166 %ret.val = phi i32 [ 1, %exiting ] 1167 ret i32 %ret.val 1168} 1169 1170; The path with noclobber block is only duplicated so we need to calculate only 1171; the cost of the path with noclobber. 1172define i32 @partial_unswitch_true_successor_for_cost_calculation(ptr %ptr, i32 %N) { 1173; CHECK-LABEL: @partial_unswitch_true_successor_for_cost_calculation( 1174; CHECK-NEXT: entry: 1175; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4 1176; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 1177; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 1178; CHECK: entry.split.us: 1179; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 1180; CHECK: loop.header.us: 1181; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 1182; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 1183; CHECK: noclobber.us: 1184; CHECK-NEXT: br label [[LOOP_LATCH_US]] 1185; CHECK: loop.latch.us: 1186; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 1187; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 1188; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 1189; CHECK: exit.split.us: 1190; CHECK-NEXT: br label [[EXIT:%.*]] 1191; CHECK: entry.split: 1192; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 1193; CHECK: loop.header: 1194; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 1195; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 1196; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 1197; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 1198; CHECK: noclobber: 1199; CHECK-NEXT: br label [[LOOP_LATCH]] 1200; CHECK: clobber: 1201; CHECK-NEXT: call void @clobber() 1202; CHECK-NEXT: call void @clobber() 1203; CHECK-NEXT: call void @clobber() 1204; CHECK-NEXT: call void @clobber() 1205; CHECK-NEXT: call void @clobber() 1206; CHECK-NEXT: call void @clobber() 1207; CHECK-NEXT: call void @clobber() 1208; CHECK-NEXT: call void @clobber() 1209; CHECK-NEXT: call void @clobber() 1210; CHECK-NEXT: call void @clobber() 1211; CHECK-NEXT: call void @clobber() 1212; CHECK-NEXT: call void @clobber() 1213; CHECK-NEXT: call void @clobber() 1214; CHECK-NEXT: call void @clobber() 1215; CHECK-NEXT: call void @clobber() 1216; CHECK-NEXT: call void @clobber() 1217; CHECK-NEXT: call void @clobber() 1218; CHECK-NEXT: call void @clobber() 1219; CHECK-NEXT: call void @clobber() 1220; CHECK-NEXT: call void @clobber() 1221; CHECK-NEXT: call void @clobber() 1222; CHECK-NEXT: call void @clobber() 1223; CHECK-NEXT: call void @clobber() 1224; CHECK-NEXT: call void @clobber() 1225; CHECK-NEXT: call void @clobber() 1226; CHECK-NEXT: call void @clobber() 1227; CHECK-NEXT: call void @clobber() 1228; CHECK-NEXT: call void @clobber() 1229; CHECK-NEXT: call void @clobber() 1230; CHECK-NEXT: call void @clobber() 1231; CHECK-NEXT: call void @clobber() 1232; CHECK-NEXT: call void @clobber() 1233; CHECK-NEXT: call void @clobber() 1234; CHECK-NEXT: call void @clobber() 1235; CHECK-NEXT: call void @clobber() 1236; CHECK-NEXT: call void @clobber() 1237; CHECK-NEXT: call void @clobber() 1238; CHECK-NEXT: call void @clobber() 1239; CHECK-NEXT: call void @clobber() 1240; CHECK-NEXT: call void @clobber() 1241; CHECK-NEXT: call void @clobber() 1242; CHECK-NEXT: call void @clobber() 1243; CHECK-NEXT: call void @clobber() 1244; CHECK-NEXT: call void @clobber() 1245; CHECK-NEXT: call void @clobber() 1246; CHECK-NEXT: call void @clobber() 1247; CHECK-NEXT: call void @clobber() 1248; CHECK-NEXT: br label [[LOOP_LATCH]] 1249; CHECK: loop.latch: 1250; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 1251; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 1252; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP11:![0-9]+]] 1253; CHECK: exit.split: 1254; CHECK-NEXT: br label [[EXIT]] 1255; CHECK: exit: 1256; CHECK-NEXT: ret i32 10 1257; 1258entry: 1259 br label %loop.header 1260 1261loop.header: 1262 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 1263 %lv = load i32, ptr %ptr 1264 %sc = icmp eq i32 %lv, 100 1265 br i1 %sc, label %noclobber, label %clobber 1266 1267noclobber: 1268 br label %loop.latch 1269 1270clobber: 1271 call void @clobber() 1272 call void @clobber() 1273 call void @clobber() 1274 call void @clobber() 1275 call void @clobber() 1276 call void @clobber() 1277 call void @clobber() 1278 call void @clobber() 1279 call void @clobber() 1280 call void @clobber() 1281 call void @clobber() 1282 call void @clobber() 1283 call void @clobber() 1284 call void @clobber() 1285 call void @clobber() 1286 call void @clobber() 1287 call void @clobber() 1288 call void @clobber() 1289 call void @clobber() 1290 call void @clobber() 1291 call void @clobber() 1292 call void @clobber() 1293 call void @clobber() 1294 call void @clobber() 1295 call void @clobber() 1296 call void @clobber() 1297 call void @clobber() 1298 call void @clobber() 1299 call void @clobber() 1300 call void @clobber() 1301 call void @clobber() 1302 call void @clobber() 1303 call void @clobber() 1304 call void @clobber() 1305 call void @clobber() 1306 call void @clobber() 1307 call void @clobber() 1308 call void @clobber() 1309 call void @clobber() 1310 call void @clobber() 1311 call void @clobber() 1312 call void @clobber() 1313 call void @clobber() 1314 call void @clobber() 1315 call void @clobber() 1316 call void @clobber() 1317 call void @clobber() 1318 br label %loop.latch 1319 1320loop.latch: 1321 %c = icmp ult i32 %iv, %N 1322 %iv.next = add i32 %iv, 1 1323 br i1 %c, label %loop.header, label %exit 1324 1325exit: 1326 ret i32 10 1327} 1328 1329define i32 @partial_unswitch_true_successor_trunc(ptr %ptr, i32 %N) { 1330; CHECK-LABEL: @partial_unswitch_true_successor_trunc( 1331; CHECK-NEXT: entry: 1332; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4 1333; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i1 1334; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 1335; CHECK: entry.split.us: 1336; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 1337; CHECK: loop.header.us: 1338; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 1339; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 1340; CHECK: noclobber.us: 1341; CHECK-NEXT: br label [[LOOP_LATCH_US]] 1342; CHECK: loop.latch.us: 1343; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 1344; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 1345; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 1346; CHECK: exit.split.us: 1347; CHECK-NEXT: br label [[EXIT:%.*]] 1348; CHECK: entry.split: 1349; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 1350; CHECK: loop.header: 1351; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 1352; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 1353; CHECK-NEXT: [[SC:%.*]] = trunc i32 [[LV]] to i1 1354; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 1355; CHECK: noclobber: 1356; CHECK-NEXT: br label [[LOOP_LATCH]] 1357; CHECK: clobber: 1358; CHECK-NEXT: call void @clobber() 1359; CHECK-NEXT: br label [[LOOP_LATCH]] 1360; CHECK: loop.latch: 1361; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 1362; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 1363; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP12:![0-9]+]] 1364; CHECK: exit.split: 1365; CHECK-NEXT: br label [[EXIT]] 1366; CHECK: exit: 1367; CHECK-NEXT: ret i32 10 1368; 1369entry: 1370 br label %loop.header 1371 1372loop.header: 1373 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 1374 %lv = load i32, ptr %ptr 1375 %sc = trunc i32 %lv to i1 1376 br i1 %sc, label %noclobber, label %clobber 1377 1378noclobber: 1379 br label %loop.latch 1380 1381clobber: 1382 call void @clobber() 1383 br label %loop.latch 1384 1385loop.latch: 1386 %c = icmp ult i32 %iv, %N 1387 %iv.next = add i32 %iv, 1 1388 br i1 %c, label %loop.header, label %exit 1389 1390exit: 1391 ret i32 10 1392} 1393 1394define i32 @partial_unswitch_false_successor_trunc(ptr %ptr, i32 %N) { 1395; CHECK-LABEL: @partial_unswitch_false_successor_trunc( 1396; CHECK-NEXT: entry: 1397; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4 1398; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i1 1399; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]] 1400; CHECK: entry.split.us: 1401; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 1402; CHECK: loop.header.us: 1403; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 1404; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 1405; CHECK: noclobber.us: 1406; CHECK-NEXT: br label [[LOOP_LATCH_US]] 1407; CHECK: loop.latch.us: 1408; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 1409; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 1410; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 1411; CHECK: exit.split.us: 1412; CHECK-NEXT: br label [[EXIT:%.*]] 1413; CHECK: entry.split: 1414; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 1415; CHECK: loop.header: 1416; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 1417; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 1418; CHECK-NEXT: [[SC:%.*]] = trunc i32 [[LV]] to i1 1419; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 1420; CHECK: clobber: 1421; CHECK-NEXT: call void @clobber() 1422; CHECK-NEXT: br label [[LOOP_LATCH]] 1423; CHECK: noclobber: 1424; CHECK-NEXT: br label [[LOOP_LATCH]] 1425; CHECK: loop.latch: 1426; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 1427; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 1428; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP13:![0-9]+]] 1429; CHECK: exit.split: 1430; CHECK-NEXT: br label [[EXIT]] 1431; CHECK: exit: 1432; CHECK-NEXT: ret i32 10 1433; 1434entry: 1435 br label %loop.header 1436 1437loop.header: 1438 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 1439 %lv = load i32, ptr %ptr 1440 %sc = trunc i32 %lv to i1 1441 br i1 %sc, label %clobber, label %noclobber 1442 1443clobber: 1444 call void @clobber() 1445 br label %loop.latch 1446 1447noclobber: 1448 br label %loop.latch 1449 1450loop.latch: 1451 %c = icmp ult i32 %iv, %N 1452 %iv.next = add i32 %iv, 1 1453 br i1 %c, label %loop.header, label %exit 1454 1455exit: 1456 ret i32 10 1457} 1458 1459; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[UNSWITCH_PARTIAL_DISABLE:![0-9]+]]} 1460; CHECK: [[UNSWITCH_PARTIAL_DISABLE]] = !{!"llvm.loop.unswitch.partial.disable"} 1461; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[UNSWITCH_PARTIAL_DISABLE]]} 1462; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[UNSWITCH_PARTIAL_DISABLE]]} 1463; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[UNSWITCH_PARTIAL_DISABLE]]} 1464; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[UNSWITCH_PARTIAL_DISABLE]]} 1465; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[UNSWITCH_PARTIAL_DISABLE]]} 1466; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[UNSWITCH_PARTIAL_DISABLE]]} 1467; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[UNSWITCH_PARTIAL_DISABLE]]} 1468; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[UNSWITCH_PARTIAL_DISABLE]]} 1469; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[UNSWITCH_PARTIAL_DISABLE]]} 1470; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[UNSWITCH_PARTIAL_DISABLE]]} 1471