107142b30SJingu Kang; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 207142b30SJingu Kang; RUN: opt -passes='loop-mssa(unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s 307142b30SJingu Kang 407142b30SJingu Kangdeclare void @clobber() 507142b30SJingu Kang 607142b30SJingu Kangdefine i32 @partial_unswitch_true_successor(i32* %ptr, i32 %N) { 707142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor( 807142b30SJingu Kang; CHECK-NEXT: entry: 9*88b259c0SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 10*88b259c0SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 11*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 12*88b259c0SJingu Kang; CHECK: entry.split.us: 13*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 14*88b259c0SJingu Kang; CHECK: loop.header.us: 15*88b259c0SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 16*88b259c0SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 17*88b259c0SJingu Kang; CHECK: noclobber.us: 18*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 19*88b259c0SJingu Kang; CHECK: loop.latch.us: 20*88b259c0SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 21*88b259c0SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 22*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 23*88b259c0SJingu Kang; CHECK: exit.split.us: 24*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 25*88b259c0SJingu Kang; CHECK: entry.split: 2607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 2707142b30SJingu Kang; CHECK: loop.header: 28*88b259c0SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 29*88b259c0SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 3007142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 3107142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 3207142b30SJingu Kang; CHECK: noclobber: 3307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 3407142b30SJingu Kang; CHECK: clobber: 3507142b30SJingu Kang; CHECK-NEXT: call void @clobber() 3607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 3707142b30SJingu Kang; CHECK: loop.latch: 38*88b259c0SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 3907142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 40*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 41*88b259c0SJingu Kang; CHECK: exit.split: 42*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT]] 4307142b30SJingu Kang; CHECK: exit: 4407142b30SJingu Kang; CHECK-NEXT: ret i32 10 4507142b30SJingu Kang; 4607142b30SJingu Kangentry: 4707142b30SJingu Kang br label %loop.header 4807142b30SJingu Kang 4907142b30SJingu Kangloop.header: 5007142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 5107142b30SJingu Kang %lv = load i32, i32* %ptr 5207142b30SJingu Kang %sc = icmp eq i32 %lv, 100 5307142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 5407142b30SJingu Kang 5507142b30SJingu Kangnoclobber: 5607142b30SJingu Kang br label %loop.latch 5707142b30SJingu Kang 5807142b30SJingu Kangclobber: 5907142b30SJingu Kang call void @clobber() 6007142b30SJingu Kang br label %loop.latch 6107142b30SJingu Kang 6207142b30SJingu Kangloop.latch: 6307142b30SJingu Kang %c = icmp ult i32 %iv, %N 6407142b30SJingu Kang %iv.next = add i32 %iv, 1 6507142b30SJingu Kang br i1 %c, label %loop.header, label %exit 6607142b30SJingu Kang 6707142b30SJingu Kangexit: 6807142b30SJingu Kang ret i32 10 6907142b30SJingu Kang} 7007142b30SJingu Kang 7107142b30SJingu Kangdefine i32 @partial_unswitch_false_successor(i32* %ptr, i32 %N) { 7207142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_false_successor( 7307142b30SJingu Kang; CHECK-NEXT: entry: 74*88b259c0SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 75*88b259c0SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 76*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]] 77*88b259c0SJingu Kang; CHECK: entry.split.us: 78*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 79*88b259c0SJingu Kang; CHECK: loop.header.us: 80*88b259c0SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 81*88b259c0SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 82*88b259c0SJingu Kang; CHECK: noclobber.us: 83*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 84*88b259c0SJingu Kang; CHECK: loop.latch.us: 85*88b259c0SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 86*88b259c0SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 87*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 88*88b259c0SJingu Kang; CHECK: exit.split.us: 89*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 90*88b259c0SJingu Kang; CHECK: entry.split: 9107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 9207142b30SJingu Kang; CHECK: loop.header: 93*88b259c0SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 94*88b259c0SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 9507142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 9607142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 9707142b30SJingu Kang; CHECK: clobber: 9807142b30SJingu Kang; CHECK-NEXT: call void @clobber() 9907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 10007142b30SJingu Kang; CHECK: noclobber: 10107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 10207142b30SJingu Kang; CHECK: loop.latch: 103*88b259c0SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 10407142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 105*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 106*88b259c0SJingu Kang; CHECK: exit.split: 107*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT]] 10807142b30SJingu Kang; CHECK: exit: 10907142b30SJingu Kang; CHECK-NEXT: ret i32 10 11007142b30SJingu Kang; 11107142b30SJingu Kangentry: 11207142b30SJingu Kang br label %loop.header 11307142b30SJingu Kang 11407142b30SJingu Kangloop.header: 11507142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 11607142b30SJingu Kang %lv = load i32, i32* %ptr 11707142b30SJingu Kang %sc = icmp eq i32 %lv, 100 11807142b30SJingu Kang br i1 %sc, label %clobber, label %noclobber 11907142b30SJingu Kang 12007142b30SJingu Kangclobber: 12107142b30SJingu Kang call void @clobber() 12207142b30SJingu Kang br label %loop.latch 12307142b30SJingu Kang 12407142b30SJingu Kangnoclobber: 12507142b30SJingu Kang br label %loop.latch 12607142b30SJingu Kang 12707142b30SJingu Kangloop.latch: 12807142b30SJingu Kang %c = icmp ult i32 %iv, %N 12907142b30SJingu Kang %iv.next = add i32 %iv, 1 13007142b30SJingu Kang br i1 %c, label %loop.header, label %exit 13107142b30SJingu Kang 13207142b30SJingu Kangexit: 13307142b30SJingu Kang ret i32 10 13407142b30SJingu Kang} 13507142b30SJingu Kang 13607142b30SJingu Kangdefine i32 @partial_unswtich_gep_load_icmp(i32** %ptr, i32 %N) { 13707142b30SJingu Kang; CHECK-LABEL: @partial_unswtich_gep_load_icmp( 13807142b30SJingu Kang; CHECK-NEXT: entry: 139*88b259c0SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32*, i32** [[PTR:%.*]], i32 1 140*88b259c0SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 8 141*88b259c0SJingu Kang; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 142*88b259c0SJingu Kang; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 100 143*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP3]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 144*88b259c0SJingu Kang; CHECK: entry.split.us: 145*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 146*88b259c0SJingu Kang; CHECK: loop.header.us: 147*88b259c0SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 148*88b259c0SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 149*88b259c0SJingu Kang; CHECK: noclobber.us: 150*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 151*88b259c0SJingu Kang; CHECK: loop.latch.us: 152*88b259c0SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 153*88b259c0SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 154*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 155*88b259c0SJingu Kang; CHECK: exit.split.us: 156*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 157*88b259c0SJingu Kang; CHECK: entry.split: 15807142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 15907142b30SJingu Kang; CHECK: loop.header: 160*88b259c0SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 161*88b259c0SJingu Kang; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32*, i32** [[PTR]], i32 1 16207142b30SJingu Kang; CHECK-NEXT: [[LV_1:%.*]] = load i32*, i32** [[GEP]], align 8 16307142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[LV_1]], align 4 16407142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 16507142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 16607142b30SJingu Kang; CHECK: noclobber: 16707142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 16807142b30SJingu Kang; CHECK: clobber: 16907142b30SJingu Kang; CHECK-NEXT: call void @clobber() 17007142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 17107142b30SJingu Kang; CHECK: loop.latch: 172*88b259c0SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 17307142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 174*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 175*88b259c0SJingu Kang; CHECK: exit.split: 176*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT]] 17707142b30SJingu Kang; CHECK: exit: 17807142b30SJingu Kang; CHECK-NEXT: ret i32 10 17907142b30SJingu Kang; 18007142b30SJingu Kangentry: 18107142b30SJingu Kang br label %loop.header 18207142b30SJingu Kang 18307142b30SJingu Kangloop.header: 18407142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 18507142b30SJingu Kang %gep = getelementptr i32*, i32** %ptr, i32 1 18607142b30SJingu Kang %lv.1 = load i32*, i32** %gep 18707142b30SJingu Kang %lv = load i32, i32* %lv.1 18807142b30SJingu Kang %sc = icmp eq i32 %lv, 100 18907142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 19007142b30SJingu Kang 19107142b30SJingu Kangnoclobber: 19207142b30SJingu Kang br label %loop.latch 19307142b30SJingu Kang 19407142b30SJingu Kangclobber: 19507142b30SJingu Kang call void @clobber() 19607142b30SJingu Kang br label %loop.latch 19707142b30SJingu Kang 19807142b30SJingu Kangloop.latch: 19907142b30SJingu Kang %c = icmp ult i32 %iv, %N 20007142b30SJingu Kang %iv.next = add i32 %iv, 1 20107142b30SJingu Kang br i1 %c, label %loop.header, label %exit 20207142b30SJingu Kang 20307142b30SJingu Kangexit: 20407142b30SJingu Kang ret i32 10 20507142b30SJingu Kang} 20607142b30SJingu Kang 20707142b30SJingu Kangdefine i32 @partial_unswitch_reduction_phi(i32* %ptr, i32 %N) { 20807142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_reduction_phi( 20907142b30SJingu Kang; CHECK-NEXT: entry: 210*88b259c0SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 211*88b259c0SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 212*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]] 213*88b259c0SJingu Kang; CHECK: entry.split.us: 214*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 215*88b259c0SJingu Kang; CHECK: loop.header.us: 216*88b259c0SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 217*88b259c0SJingu Kang; CHECK-NEXT: [[RED_US:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT_US]] ], [ [[RED_NEXT_US:%.*]], [[LOOP_LATCH_US]] ] 218*88b259c0SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 219*88b259c0SJingu Kang; CHECK: noclobber.us: 220*88b259c0SJingu Kang; CHECK-NEXT: [[ADD_10_US:%.*]] = add i32 [[RED_US]], 10 221*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 222*88b259c0SJingu Kang; CHECK: loop.latch.us: 223*88b259c0SJingu Kang; CHECK-NEXT: [[RED_NEXT_US]] = phi i32 [ [[ADD_10_US]], [[NOCLOBBER_US]] ] 224*88b259c0SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 225*88b259c0SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 226*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 227*88b259c0SJingu Kang; CHECK: exit.split.us: 228*88b259c0SJingu Kang; CHECK-NEXT: [[RED_NEXT_LCSSA_US:%.*]] = phi i32 [ [[RED_NEXT_US]], [[LOOP_LATCH_US]] ] 229*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 230*88b259c0SJingu Kang; CHECK: entry.split: 23107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 23207142b30SJingu Kang; CHECK: loop.header: 233*88b259c0SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 234*88b259c0SJingu Kang; CHECK-NEXT: [[RED:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT]] ], [ [[RED_NEXT:%.*]], [[LOOP_LATCH]] ] 235*88b259c0SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 23607142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 23707142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 23807142b30SJingu Kang; CHECK: clobber: 23907142b30SJingu Kang; CHECK-NEXT: call void @clobber() 24007142b30SJingu Kang; CHECK-NEXT: [[ADD_5:%.*]] = add i32 [[RED]], 5 24107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 24207142b30SJingu Kang; CHECK: noclobber: 24307142b30SJingu Kang; CHECK-NEXT: [[ADD_10:%.*]] = add i32 [[RED]], 10 24407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 24507142b30SJingu Kang; CHECK: loop.latch: 24607142b30SJingu Kang; CHECK-NEXT: [[RED_NEXT]] = phi i32 [ [[ADD_5]], [[CLOBBER]] ], [ [[ADD_10]], [[NOCLOBBER]] ] 247*88b259c0SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 24807142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 249*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 250*88b259c0SJingu Kang; CHECK: exit.split: 251ab728717SJingu Kang; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ] 252*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT]] 253*88b259c0SJingu Kang; CHECK: exit: 254*88b259c0SJingu Kang; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RED_NEXT_LCSSA]], [[EXIT_SPLIT]] ], [ [[RED_NEXT_LCSSA_US]], [[EXIT_SPLIT_US]] ] 255*88b259c0SJingu Kang; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 25607142b30SJingu Kang; 25707142b30SJingu Kangentry: 25807142b30SJingu Kang br label %loop.header 25907142b30SJingu Kang 26007142b30SJingu Kangloop.header: 26107142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 26207142b30SJingu Kang %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ] 26307142b30SJingu Kang %lv = load i32, i32* %ptr 26407142b30SJingu Kang %sc = icmp eq i32 %lv, 100 26507142b30SJingu Kang br i1 %sc, label %clobber, label %noclobber 26607142b30SJingu Kang 26707142b30SJingu Kangclobber: 26807142b30SJingu Kang call void @clobber() 26907142b30SJingu Kang %add.5 = add i32 %red, 5 27007142b30SJingu Kang br label %loop.latch 27107142b30SJingu Kang 27207142b30SJingu Kangnoclobber: 27307142b30SJingu Kang %add.10 = add i32 %red, 10 27407142b30SJingu Kang br label %loop.latch 27507142b30SJingu Kang 27607142b30SJingu Kangloop.latch: 27707142b30SJingu Kang %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ] 27807142b30SJingu Kang %c = icmp ult i32 %iv, %N 27907142b30SJingu Kang %iv.next = add i32 %iv, 1 28007142b30SJingu Kang br i1 %c, label %loop.header, label %exit 28107142b30SJingu Kang 28207142b30SJingu Kangexit: 28307142b30SJingu Kang %red.next.lcssa = phi i32 [ %red.next, %loop.latch ] 28407142b30SJingu Kang ret i32 %red.next.lcssa 28507142b30SJingu Kang} 28607142b30SJingu Kang 28707142b30SJingu Kang; Partial unswitching is possible, because the store in %noclobber does not 28807142b30SJingu Kang; alias the load of the condition. 28907142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_noclobber(i32* noalias %ptr.1, i32* noalias %ptr.2, i32 %N) { 29007142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_noclobber( 29107142b30SJingu Kang; CHECK-NEXT: entry: 292*88b259c0SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4 293*88b259c0SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 294*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 295*88b259c0SJingu Kang; CHECK: entry.split.us: 296*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 297*88b259c0SJingu Kang; CHECK: loop.header.us: 298*88b259c0SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 299*88b259c0SJingu Kang; CHECK-NEXT: [[LV_US:%.*]] = load i32, i32* [[PTR_1]], align 4 300*88b259c0SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 301*88b259c0SJingu Kang; CHECK: noclobber.us: 302*88b259c0SJingu Kang; CHECK-NEXT: [[GEP_1_US:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV_US]] 303*88b259c0SJingu Kang; CHECK-NEXT: store i32 [[LV_US]], i32* [[GEP_1_US]], align 4 304*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 305*88b259c0SJingu Kang; CHECK: loop.latch.us: 306*88b259c0SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 307*88b259c0SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 308*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 309*88b259c0SJingu Kang; CHECK: exit.split.us: 310*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 311*88b259c0SJingu Kang; CHECK: entry.split: 31207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 31307142b30SJingu Kang; CHECK: loop.header: 314*88b259c0SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 315*88b259c0SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR_1]], align 4 31607142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 31707142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 31807142b30SJingu Kang; CHECK: noclobber: 319*88b259c0SJingu Kang; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2]], i32 [[IV]] 32007142b30SJingu Kang; CHECK-NEXT: store i32 [[LV]], i32* [[GEP_1]], align 4 32107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 32207142b30SJingu Kang; CHECK: clobber: 32307142b30SJingu Kang; CHECK-NEXT: call void @clobber() 32407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 32507142b30SJingu Kang; CHECK: loop.latch: 326*88b259c0SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 32707142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 328*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 329*88b259c0SJingu Kang; CHECK: exit.split: 330*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT]] 33107142b30SJingu Kang; CHECK: exit: 33207142b30SJingu Kang; CHECK-NEXT: ret i32 10 33307142b30SJingu Kang; 33407142b30SJingu Kangentry: 33507142b30SJingu Kang br label %loop.header 33607142b30SJingu Kang 33707142b30SJingu Kangloop.header: 33807142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 33907142b30SJingu Kang %lv = load i32, i32* %ptr.1 34007142b30SJingu Kang %sc = icmp eq i32 %lv, 100 34107142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 34207142b30SJingu Kang 34307142b30SJingu Kangnoclobber: 34407142b30SJingu Kang %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv 34507142b30SJingu Kang store i32 %lv, i32* %gep.1 34607142b30SJingu Kang br label %loop.latch 34707142b30SJingu Kang 34807142b30SJingu Kangclobber: 34907142b30SJingu Kang call void @clobber() 35007142b30SJingu Kang br label %loop.latch 35107142b30SJingu Kang 35207142b30SJingu Kangloop.latch: 35307142b30SJingu Kang %c = icmp ult i32 %iv, %N 35407142b30SJingu Kang %iv.next = add i32 %iv, 1 35507142b30SJingu Kang br i1 %c, label %loop.header, label %exit 35607142b30SJingu Kang 35707142b30SJingu Kangexit: 35807142b30SJingu Kang ret i32 10 35907142b30SJingu Kang} 36007142b30SJingu Kang 36107142b30SJingu Kangdefine void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) { 36207142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_phi_cond( 36307142b30SJingu Kang; CHECK-NEXT: entry: 36407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 36507142b30SJingu Kang; CHECK: loop.header: 36607142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 36707142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = phi i1 [ [[LC:%.*]], [[ENTRY]] ], [ true, [[LOOP_LATCH]] ] 36807142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 36907142b30SJingu Kang; CHECK: clobber: 37007142b30SJingu Kang; CHECK-NEXT: call void @clobber() 37107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 37207142b30SJingu Kang; CHECK: noclobber: 37307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 37407142b30SJingu Kang; CHECK: loop.latch: 37507142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 37607142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 37707142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 37807142b30SJingu Kang; CHECK: exit: 37907142b30SJingu Kang; CHECK-NEXT: ret void 38007142b30SJingu Kang; 38107142b30SJingu Kangentry: 38207142b30SJingu Kang br label %loop.header 38307142b30SJingu Kang 38407142b30SJingu Kangloop.header: 38507142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 38607142b30SJingu Kang %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ] 38707142b30SJingu Kang br i1 %sc, label %clobber, label %noclobber 38807142b30SJingu Kang 38907142b30SJingu Kangclobber: 39007142b30SJingu Kang call void @clobber() 39107142b30SJingu Kang br label %loop.latch 39207142b30SJingu Kang 39307142b30SJingu Kangnoclobber: 39407142b30SJingu Kang br label %loop.latch 39507142b30SJingu Kang 39607142b30SJingu Kangloop.latch: 39707142b30SJingu Kang %c = icmp ult i32 %iv, %N 39807142b30SJingu Kang %iv.next = add i32 %iv, 1 39907142b30SJingu Kang br i1 %c, label %loop.header, label %exit 40007142b30SJingu Kang 40107142b30SJingu Kangexit: 40207142b30SJingu Kang ret void 40307142b30SJingu Kang} 40407142b30SJingu Kang 40507142b30SJingu Kangdefine void @no_partial_unswitch_clobber_latch(i32* %ptr, i32 %N) { 40607142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_latch( 40707142b30SJingu Kang; CHECK-NEXT: entry: 40807142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 40907142b30SJingu Kang; CHECK: loop.header: 41007142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 41107142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 41207142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 41307142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 41407142b30SJingu Kang; CHECK: noclobber: 41507142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 41607142b30SJingu Kang; CHECK: clobber: 41707142b30SJingu Kang; CHECK-NEXT: call void @clobber() 41807142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 41907142b30SJingu Kang; CHECK: loop.latch: 42007142b30SJingu Kang; CHECK-NEXT: call void @clobber() 42107142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 42207142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 42307142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 42407142b30SJingu Kang; CHECK: exit: 42507142b30SJingu Kang; CHECK-NEXT: ret void 42607142b30SJingu Kang; 42707142b30SJingu Kangentry: 42807142b30SJingu Kang br label %loop.header 42907142b30SJingu Kang 43007142b30SJingu Kangloop.header: 43107142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 43207142b30SJingu Kang %lv = load i32, i32* %ptr 43307142b30SJingu Kang %sc = icmp eq i32 %lv, 100 43407142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 43507142b30SJingu Kang 43607142b30SJingu Kangnoclobber: 43707142b30SJingu Kang br label %loop.latch 43807142b30SJingu Kang 43907142b30SJingu Kangclobber: 44007142b30SJingu Kang call void @clobber() 44107142b30SJingu Kang br label %loop.latch 44207142b30SJingu Kang 44307142b30SJingu Kangloop.latch: 44407142b30SJingu Kang call void @clobber() 44507142b30SJingu Kang %c = icmp ult i32 %iv, %N 44607142b30SJingu Kang %iv.next = add i32 %iv, 1 44707142b30SJingu Kang br i1 %c, label %loop.header, label %exit 44807142b30SJingu Kang 44907142b30SJingu Kangexit: 45007142b30SJingu Kang ret void 45107142b30SJingu Kang} 45207142b30SJingu Kang 45307142b30SJingu Kangdefine void @no_partial_unswitch_clobber_header(i32* %ptr, i32 %N) { 45407142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_header( 45507142b30SJingu Kang; CHECK-NEXT: entry: 45607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 45707142b30SJingu Kang; CHECK: loop.header: 45807142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 45907142b30SJingu Kang; CHECK-NEXT: call void @clobber() 46007142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 46107142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 46207142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 46307142b30SJingu Kang; CHECK: noclobber: 46407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 46507142b30SJingu Kang; CHECK: clobber: 46607142b30SJingu Kang; CHECK-NEXT: call void @clobber() 46707142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 46807142b30SJingu Kang; CHECK: loop.latch: 46907142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 47007142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 47107142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 47207142b30SJingu Kang; CHECK: exit: 47307142b30SJingu Kang; CHECK-NEXT: ret void 47407142b30SJingu Kang; 47507142b30SJingu Kangentry: 47607142b30SJingu Kang br label %loop.header 47707142b30SJingu Kang 47807142b30SJingu Kangloop.header: 47907142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 48007142b30SJingu Kang call void @clobber() 48107142b30SJingu Kang %lv = load i32, i32* %ptr 48207142b30SJingu Kang %sc = icmp eq i32 %lv, 100 48307142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 48407142b30SJingu Kang 48507142b30SJingu Kangnoclobber: 48607142b30SJingu Kang br label %loop.latch 48707142b30SJingu Kang 48807142b30SJingu Kangclobber: 48907142b30SJingu Kang call void @clobber() 49007142b30SJingu Kang br label %loop.latch 49107142b30SJingu Kang 49207142b30SJingu Kangloop.latch: 49307142b30SJingu Kang %c = icmp ult i32 %iv, %N 49407142b30SJingu Kang %iv.next = add i32 %iv, 1 49507142b30SJingu Kang br i1 %c, label %loop.header, label %exit 49607142b30SJingu Kang 49707142b30SJingu Kangexit: 49807142b30SJingu Kang ret void 49907142b30SJingu Kang} 50007142b30SJingu Kang 50107142b30SJingu Kangdefine void @no_partial_unswitch_clobber_both(i32* %ptr, i32 %N) { 50207142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_both( 50307142b30SJingu Kang; CHECK-NEXT: entry: 50407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 50507142b30SJingu Kang; CHECK: loop.header: 50607142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 50707142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 50807142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 50907142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 51007142b30SJingu Kang; CHECK: noclobber: 51107142b30SJingu Kang; CHECK-NEXT: call void @clobber() 51207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 51307142b30SJingu Kang; CHECK: clobber: 51407142b30SJingu Kang; CHECK-NEXT: call void @clobber() 51507142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 51607142b30SJingu Kang; CHECK: loop.latch: 51707142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 51807142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 51907142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 52007142b30SJingu Kang; CHECK: exit: 52107142b30SJingu Kang; CHECK-NEXT: ret void 52207142b30SJingu Kang; 52307142b30SJingu Kangentry: 52407142b30SJingu Kang br label %loop.header 52507142b30SJingu Kang 52607142b30SJingu Kangloop.header: 52707142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 52807142b30SJingu Kang %lv = load i32, i32* %ptr 52907142b30SJingu Kang %sc = icmp eq i32 %lv, 100 53007142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 53107142b30SJingu Kang 53207142b30SJingu Kangnoclobber: 53307142b30SJingu Kang call void @clobber() 53407142b30SJingu Kang br label %loop.latch 53507142b30SJingu Kang 53607142b30SJingu Kangclobber: 53707142b30SJingu Kang call void @clobber() 53807142b30SJingu Kang br label %loop.latch 53907142b30SJingu Kang 54007142b30SJingu Kangloop.latch: 54107142b30SJingu Kang %c = icmp ult i32 %iv, %N 54207142b30SJingu Kang %iv.next = add i32 %iv, 1 54307142b30SJingu Kang br i1 %c, label %loop.header, label %exit 54407142b30SJingu Kang 54507142b30SJingu Kangexit: 54607142b30SJingu Kang ret void 54707142b30SJingu Kang} 54807142b30SJingu Kang 54907142b30SJingu Kangdefine i32 @no_partial_unswitch_true_successor_storeclobber(i32* %ptr.1, i32* %ptr.2, i32 %N) { 55007142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber( 55107142b30SJingu Kang; CHECK-NEXT: entry: 55207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 55307142b30SJingu Kang; CHECK: loop.header: 55407142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 55507142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4 55607142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 55707142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 55807142b30SJingu Kang; CHECK: noclobber: 55907142b30SJingu Kang; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV]] 56007142b30SJingu Kang; CHECK-NEXT: store i32 [[LV]], i32* [[GEP_1]], align 4 56107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 56207142b30SJingu Kang; CHECK: clobber: 56307142b30SJingu Kang; CHECK-NEXT: call void @clobber() 56407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 56507142b30SJingu Kang; CHECK: loop.latch: 56607142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 56707142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 56807142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 56907142b30SJingu Kang; CHECK: exit: 57007142b30SJingu Kang; CHECK-NEXT: ret i32 10 57107142b30SJingu Kang; 57207142b30SJingu Kangentry: 57307142b30SJingu Kang br label %loop.header 57407142b30SJingu Kang 57507142b30SJingu Kangloop.header: 57607142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 57707142b30SJingu Kang %lv = load i32, i32* %ptr.1 57807142b30SJingu Kang %sc = icmp eq i32 %lv, 100 57907142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 58007142b30SJingu Kang 58107142b30SJingu Kangnoclobber: 58207142b30SJingu Kang %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv 58307142b30SJingu Kang store i32 %lv, i32* %gep.1 58407142b30SJingu Kang br label %loop.latch 58507142b30SJingu Kang 58607142b30SJingu Kangclobber: 58707142b30SJingu Kang call void @clobber() 58807142b30SJingu Kang br label %loop.latch 58907142b30SJingu Kang 59007142b30SJingu Kangloop.latch: 59107142b30SJingu Kang %c = icmp ult i32 %iv, %N 59207142b30SJingu Kang %iv.next = add i32 %iv, 1 59307142b30SJingu Kang br i1 %c, label %loop.header, label %exit 59407142b30SJingu Kang 59507142b30SJingu Kangexit: 59607142b30SJingu Kang ret i32 10 59707142b30SJingu Kang} 59807142b30SJingu Kang 59907142b30SJingu Kang; Make sure the duplicated instructions are moved to a preheader that always 60007142b30SJingu Kang; executes when the loop body also executes. Do not check the unswitched code, 60107142b30SJingu Kang; because it is already checked in the @partial_unswitch_true_successor test 60207142b30SJingu Kang; case. 60307142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_preheader_insertion(i32* %ptr, i32 %N) { 60407142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion( 60507142b30SJingu Kang; CHECK-NEXT: entry: 60607142b30SJingu Kang; CHECK-NEXT: [[EC:%.*]] = icmp ne i32* [[PTR:%.*]], null 60707142b30SJingu Kang; CHECK-NEXT: br i1 [[EC]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]] 60807142b30SJingu Kang; CHECK: loop.ph: 609*88b259c0SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR]], align 4 610*88b259c0SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 611*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PH_SPLIT_US:%.*]], label [[LOOP_PH_SPLIT:%.*]] 612*88b259c0SJingu Kang; CHECK: loop.ph.split.us: 613*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 614*88b259c0SJingu Kang; CHECK: loop.header.us: 615*88b259c0SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 616*88b259c0SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 617*88b259c0SJingu Kang; CHECK: noclobber.us: 618*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 619*88b259c0SJingu Kang; CHECK: loop.latch.us: 620*88b259c0SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 621*88b259c0SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 622*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_LOOPEXIT_SPLIT_US:%.*]] 623*88b259c0SJingu Kang; CHECK: exit.loopexit.split.us: 624*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT_LOOPEXIT:%.*]] 625*88b259c0SJingu Kang; CHECK: loop.ph.split: 62607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 62707142b30SJingu Kang; CHECK: loop.header: 628*88b259c0SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 62907142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 63007142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 63107142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 63207142b30SJingu Kang; CHECK: noclobber: 63307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 63407142b30SJingu Kang; CHECK: clobber: 63507142b30SJingu Kang; CHECK-NEXT: call void @clobber() 63607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 63707142b30SJingu Kang; CHECK: loop.latch: 638*88b259c0SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 63907142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 640*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT_SPLIT:%.*]] 641*88b259c0SJingu Kang; CHECK: exit.loopexit.split: 642*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT_LOOPEXIT]] 64307142b30SJingu Kang; CHECK: exit.loopexit: 64407142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 64507142b30SJingu Kang; CHECK: exit: 64607142b30SJingu Kang; CHECK-NEXT: ret i32 10 64707142b30SJingu Kang; 64807142b30SJingu Kang 64907142b30SJingu Kangentry: 65007142b30SJingu Kang %ec = icmp ne i32* %ptr, null 65107142b30SJingu Kang br i1 %ec, label %loop.ph, label %exit 65207142b30SJingu Kang 65307142b30SJingu Kangloop.ph: 65407142b30SJingu Kang br label %loop.header 65507142b30SJingu Kang 65607142b30SJingu Kangloop.header: 65707142b30SJingu Kang %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ] 65807142b30SJingu Kang %lv = load i32, i32* %ptr 65907142b30SJingu Kang %sc = icmp eq i32 %lv, 100 66007142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 66107142b30SJingu Kang 66207142b30SJingu Kangnoclobber: 66307142b30SJingu Kang br label %loop.latch 66407142b30SJingu Kang 66507142b30SJingu Kangclobber: 66607142b30SJingu Kang call void @clobber() 66707142b30SJingu Kang br label %loop.latch 66807142b30SJingu Kang 66907142b30SJingu Kangloop.latch: 67007142b30SJingu Kang %c = icmp ult i32 %iv, %N 67107142b30SJingu Kang %iv.next = add i32 %iv, 1 67207142b30SJingu Kang br i1 %c, label %loop.header, label %exit 67307142b30SJingu Kang 67407142b30SJingu Kangexit: 67507142b30SJingu Kang ret i32 10 67607142b30SJingu Kang} 67707142b30SJingu Kang 67807142b30SJingu Kang; Make sure the duplicated instructions are hoisted just before the branch of 67907142b30SJingu Kang; the preheader. Do not check the unswitched code, because it is already checked 68007142b30SJingu Kang; in the @partial_unswitch_true_successor test case 68107142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_insert_point(i32* %ptr, i32 %N) { 68207142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_insert_point( 68307142b30SJingu Kang; CHECK-NEXT: entry: 68407142b30SJingu Kang; CHECK-NEXT: call void @clobber() 685*88b259c0SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 686*88b259c0SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 687*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 688*88b259c0SJingu Kang; CHECK: entry.split.us: 689*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 690*88b259c0SJingu Kang; CHECK: loop.header.us: 691*88b259c0SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 692*88b259c0SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 693*88b259c0SJingu Kang; CHECK: noclobber.us: 694*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 695*88b259c0SJingu Kang; CHECK: loop.latch.us: 696*88b259c0SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 697*88b259c0SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 698*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 699*88b259c0SJingu Kang; CHECK: exit.split.us: 700*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 701*88b259c0SJingu Kang; CHECK: entry.split: 70207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 70307142b30SJingu Kang; CHECK: loop.header: 704*88b259c0SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 705*88b259c0SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 70607142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 70707142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 70807142b30SJingu Kang; CHECK: noclobber: 70907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 71007142b30SJingu Kang; CHECK: clobber: 71107142b30SJingu Kang; CHECK-NEXT: call void @clobber() 71207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 71307142b30SJingu Kang; CHECK: loop.latch: 714*88b259c0SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 71507142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 716*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 717*88b259c0SJingu Kang; CHECK: exit.split: 718*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT]] 71907142b30SJingu Kang; CHECK: exit: 72007142b30SJingu Kang; CHECK-NEXT: ret i32 10 72107142b30SJingu Kang; 72207142b30SJingu Kangentry: 72307142b30SJingu Kang call void @clobber() 72407142b30SJingu Kang br label %loop.header 72507142b30SJingu Kang 72607142b30SJingu Kangloop.header: 72707142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 72807142b30SJingu Kang %lv = load i32, i32* %ptr 72907142b30SJingu Kang %sc = icmp eq i32 %lv, 100 73007142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 73107142b30SJingu Kang 73207142b30SJingu Kangnoclobber: 73307142b30SJingu Kang br label %loop.latch 73407142b30SJingu Kang 73507142b30SJingu Kangclobber: 73607142b30SJingu Kang call void @clobber() 73707142b30SJingu Kang br label %loop.latch 73807142b30SJingu Kang 73907142b30SJingu Kangloop.latch: 74007142b30SJingu Kang %c = icmp ult i32 %iv, %N 74107142b30SJingu Kang %iv.next = add i32 %iv, 1 74207142b30SJingu Kang br i1 %c, label %loop.header, label %exit 74307142b30SJingu Kang 74407142b30SJingu Kangexit: 74507142b30SJingu Kang ret i32 10 74607142b30SJingu Kang} 74707142b30SJingu Kang 74807142b30SJingu Kang; Make sure invariant instructions in the loop are also hoisted to the preheader. 74907142b30SJingu Kang; Do not check the unswitched code, because it is already checked in the 75007142b30SJingu Kang; @partial_unswitch_true_successor test case 75107142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_hoist_invariant(i32* %ptr, i32 %N) { 75207142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant( 75307142b30SJingu Kang; CHECK-NEXT: entry: 754*88b259c0SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 1 755*88b259c0SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 756*88b259c0SJingu Kang; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 100 757*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP2]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 758*88b259c0SJingu Kang; CHECK: entry.split.us: 759*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 760*88b259c0SJingu Kang; CHECK: loop.header.us: 761*88b259c0SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 762*88b259c0SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 763*88b259c0SJingu Kang; CHECK: noclobber.us: 764*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 765*88b259c0SJingu Kang; CHECK: loop.latch.us: 766*88b259c0SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 767*88b259c0SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 768*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 769*88b259c0SJingu Kang; CHECK: exit.split.us: 770*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 771*88b259c0SJingu Kang; CHECK: entry.split: 77207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 77307142b30SJingu Kang; CHECK: loop.header: 774*88b259c0SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 775*88b259c0SJingu Kang; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR]], i64 1 77607142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[GEP]], align 4 77707142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 77807142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 77907142b30SJingu Kang; CHECK: noclobber: 78007142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 78107142b30SJingu Kang; CHECK: clobber: 78207142b30SJingu Kang; CHECK-NEXT: call void @clobber() 78307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 78407142b30SJingu Kang; CHECK: loop.latch: 785*88b259c0SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 78607142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 787*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 788*88b259c0SJingu Kang; CHECK: exit.split: 789*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT]] 79007142b30SJingu Kang; CHECK: exit: 79107142b30SJingu Kang; CHECK-NEXT: ret i32 10 79207142b30SJingu Kang; 79307142b30SJingu Kangentry: 79407142b30SJingu Kang br label %loop.header 79507142b30SJingu Kang 79607142b30SJingu Kangloop.header: 79707142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 79807142b30SJingu Kang %gep = getelementptr i32, i32* %ptr, i64 1 79907142b30SJingu Kang %lv = load i32, i32* %gep 80007142b30SJingu Kang %sc = icmp eq i32 %lv, 100 80107142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 80207142b30SJingu Kang 80307142b30SJingu Kangnoclobber: 80407142b30SJingu Kang br label %loop.latch 80507142b30SJingu Kang 80607142b30SJingu Kangclobber: 80707142b30SJingu Kang call void @clobber() 80807142b30SJingu Kang br label %loop.latch 80907142b30SJingu Kang 81007142b30SJingu Kangloop.latch: 81107142b30SJingu Kang %c = icmp ult i32 %iv, %N 81207142b30SJingu Kang %iv.next = add i32 %iv, 1 81307142b30SJingu Kang br i1 %c, label %loop.header, label %exit 81407142b30SJingu Kang 81507142b30SJingu Kangexit: 81607142b30SJingu Kang ret i32 10 81707142b30SJingu Kang} 81807142b30SJingu Kang 81907142b30SJingu Kang; Do not unswitch if the condition depends on an atomic load. Duplicating such 82007142b30SJingu Kang; loads is not safe. 82107142b30SJingu Kangdefine i32 @no_partial_unswitch_atomic_load_unordered(i32* %ptr, i32 %N) { 82207142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered( 82307142b30SJingu Kang; CHECK-NEXT: entry: 82407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 82507142b30SJingu Kang; CHECK: loop.header: 82607142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 82707142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] unordered, align 4 82807142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 82907142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 83007142b30SJingu Kang; CHECK: noclobber: 83107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 83207142b30SJingu Kang; CHECK: clobber: 83307142b30SJingu Kang; CHECK-NEXT: call void @clobber() 83407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 83507142b30SJingu Kang; CHECK: loop.latch: 83607142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 83707142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 83807142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 83907142b30SJingu Kang; CHECK: exit: 84007142b30SJingu Kang; CHECK-NEXT: ret i32 10 84107142b30SJingu Kang; 84207142b30SJingu Kangentry: 84307142b30SJingu Kang br label %loop.header 84407142b30SJingu Kang 84507142b30SJingu Kangloop.header: 84607142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 84707142b30SJingu Kang %lv = load atomic i32, i32* %ptr unordered, align 4 84807142b30SJingu Kang %sc = icmp eq i32 %lv, 100 84907142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 85007142b30SJingu Kang 85107142b30SJingu Kangnoclobber: 85207142b30SJingu Kang br label %loop.latch 85307142b30SJingu Kang 85407142b30SJingu Kangclobber: 85507142b30SJingu Kang call void @clobber() 85607142b30SJingu Kang br label %loop.latch 85707142b30SJingu Kang 85807142b30SJingu Kangloop.latch: 85907142b30SJingu Kang %c = icmp ult i32 %iv, %N 86007142b30SJingu Kang %iv.next = add i32 %iv, 1 86107142b30SJingu Kang br i1 %c, label %loop.header, label %exit 86207142b30SJingu Kang 86307142b30SJingu Kangexit: 86407142b30SJingu Kang ret i32 10 86507142b30SJingu Kang} 86607142b30SJingu Kang 86707142b30SJingu Kang; Do not unswitch if the condition depends on an atomic load. Duplicating such 86807142b30SJingu Kang; loads is not safe. 86907142b30SJingu Kangdefine i32 @no_partial_unswitch_atomic_load_monotonic(i32* %ptr, i32 %N) { 87007142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic( 87107142b30SJingu Kang; CHECK-NEXT: entry: 87207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 87307142b30SJingu Kang; CHECK: loop.header: 87407142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 87507142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] monotonic, align 4 87607142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 87707142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 87807142b30SJingu Kang; CHECK: noclobber: 87907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 88007142b30SJingu Kang; CHECK: clobber: 88107142b30SJingu Kang; CHECK-NEXT: call void @clobber() 88207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 88307142b30SJingu Kang; CHECK: loop.latch: 88407142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 88507142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 88607142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 88707142b30SJingu Kang; CHECK: exit: 88807142b30SJingu Kang; CHECK-NEXT: ret i32 10 88907142b30SJingu Kang; 89007142b30SJingu Kangentry: 89107142b30SJingu Kang br label %loop.header 89207142b30SJingu Kang 89307142b30SJingu Kangloop.header: 89407142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 89507142b30SJingu Kang %lv = load atomic i32, i32* %ptr monotonic, align 4 89607142b30SJingu Kang %sc = icmp eq i32 %lv, 100 89707142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 89807142b30SJingu Kang 89907142b30SJingu Kangnoclobber: 90007142b30SJingu Kang br label %loop.latch 90107142b30SJingu Kang 90207142b30SJingu Kangclobber: 90307142b30SJingu Kang call void @clobber() 90407142b30SJingu Kang br label %loop.latch 90507142b30SJingu Kang 90607142b30SJingu Kangloop.latch: 90707142b30SJingu Kang %c = icmp ult i32 %iv, %N 90807142b30SJingu Kang %iv.next = add i32 %iv, 1 90907142b30SJingu Kang br i1 %c, label %loop.header, label %exit 91007142b30SJingu Kang 91107142b30SJingu Kangexit: 91207142b30SJingu Kang ret i32 10 91307142b30SJingu Kang} 91407142b30SJingu Kang 91507142b30SJingu Kang 91607142b30SJingu Kangdeclare i32 @get_value() 91707142b30SJingu Kang 91807142b30SJingu Kang; Do not unswitch if the condition depends on a call, that may clobber memory. 91907142b30SJingu Kang; Duplicating such a call is not safe. 92007142b30SJingu Kangdefine i32 @no_partial_unswitch_cond_call(i32* %ptr, i32 %N) { 92107142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_cond_call( 92207142b30SJingu Kang; CHECK-NEXT: entry: 92307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 92407142b30SJingu Kang; CHECK: loop.header: 92507142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 92607142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = call i32 @get_value() 92707142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 92807142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 92907142b30SJingu Kang; CHECK: noclobber: 93007142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 93107142b30SJingu Kang; CHECK: clobber: 93207142b30SJingu Kang; CHECK-NEXT: call void @clobber() 93307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 93407142b30SJingu Kang; CHECK: loop.latch: 93507142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 93607142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 93707142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 93807142b30SJingu Kang; CHECK: exit: 93907142b30SJingu Kang; CHECK-NEXT: ret i32 10 94007142b30SJingu Kang; 94107142b30SJingu Kangentry: 94207142b30SJingu Kang br label %loop.header 94307142b30SJingu Kang 94407142b30SJingu Kangloop.header: 94507142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 94607142b30SJingu Kang %lv = call i32 @get_value() 94707142b30SJingu Kang %sc = icmp eq i32 %lv, 100 94807142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 94907142b30SJingu Kang 95007142b30SJingu Kangnoclobber: 95107142b30SJingu Kang br label %loop.latch 95207142b30SJingu Kang 95307142b30SJingu Kangclobber: 95407142b30SJingu Kang call void @clobber() 95507142b30SJingu Kang br label %loop.latch 95607142b30SJingu Kang 95707142b30SJingu Kangloop.latch: 95807142b30SJingu Kang %c = icmp ult i32 %iv, %N 95907142b30SJingu Kang %iv.next = add i32 %iv, 1 96007142b30SJingu Kang br i1 %c, label %loop.header, label %exit 96107142b30SJingu Kang 96207142b30SJingu Kangexit: 96307142b30SJingu Kang ret i32 10 96407142b30SJingu Kang} 96507142b30SJingu Kang 96607142b30SJingu Kangdefine i32 @no_partial_unswitch_true_successor_exit(i32* %ptr, i32 %N) { 96707142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_successor_exit( 96807142b30SJingu Kang; CHECK-NEXT: entry: 96907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 97007142b30SJingu Kang; CHECK: loop.header: 97107142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 97207142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 97307142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 97407142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[EXIT:%.*]], label [[CLOBBER:%.*]] 97507142b30SJingu Kang; CHECK: clobber: 97607142b30SJingu Kang; CHECK-NEXT: call void @clobber() 97707142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 97807142b30SJingu Kang; CHECK: loop.latch: 97907142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 98007142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 98107142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT]] 98207142b30SJingu Kang; CHECK: exit: 98307142b30SJingu Kang; CHECK-NEXT: ret i32 10 98407142b30SJingu Kang; 98507142b30SJingu Kangentry: 98607142b30SJingu Kang br label %loop.header 98707142b30SJingu Kang 98807142b30SJingu Kangloop.header: 98907142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 99007142b30SJingu Kang %lv = load i32, i32* %ptr 99107142b30SJingu Kang %sc = icmp eq i32 %lv, 100 99207142b30SJingu Kang br i1 %sc, label %exit, label %clobber 99307142b30SJingu Kang 99407142b30SJingu Kangclobber: 99507142b30SJingu Kang call void @clobber() 99607142b30SJingu Kang br label %loop.latch 99707142b30SJingu Kang 99807142b30SJingu Kangloop.latch: 99907142b30SJingu Kang %c = icmp ult i32 %iv, %N 100007142b30SJingu Kang %iv.next = add i32 %iv, 1 100107142b30SJingu Kang br i1 %c, label %loop.header, label %exit 100207142b30SJingu Kang 100307142b30SJingu Kangexit: 100407142b30SJingu Kang ret i32 10 100507142b30SJingu Kang} 100607142b30SJingu Kang 100707142b30SJingu Kangdefine i32 @no_partial_unswitch_true_same_successor(i32* %ptr, i32 %N) { 100807142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_same_successor( 100907142b30SJingu Kang; CHECK-NEXT: entry: 101007142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 101107142b30SJingu Kang; CHECK: loop.header: 101207142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 101307142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 101407142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 101507142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[NOCLOBBER]] 101607142b30SJingu Kang; CHECK: noclobber: 101707142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 101807142b30SJingu Kang; CHECK: loop.latch: 101907142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 102007142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 102107142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 102207142b30SJingu Kang; CHECK: exit: 102307142b30SJingu Kang; CHECK-NEXT: ret i32 10 102407142b30SJingu Kang; 102507142b30SJingu Kangentry: 102607142b30SJingu Kang br label %loop.header 102707142b30SJingu Kang 102807142b30SJingu Kangloop.header: 102907142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 103007142b30SJingu Kang %lv = load i32, i32* %ptr 103107142b30SJingu Kang %sc = icmp eq i32 %lv, 100 103207142b30SJingu Kang br i1 %sc, label %noclobber, label %noclobber 103307142b30SJingu Kang 103407142b30SJingu Kangnoclobber: 103507142b30SJingu Kang br label %loop.latch 103607142b30SJingu Kang 103707142b30SJingu Kangloop.latch: 103807142b30SJingu Kang %c = icmp ult i32 %iv, %N 103907142b30SJingu Kang %iv.next = add i32 %iv, 1 104007142b30SJingu Kang br i1 %c, label %loop.header, label %exit 104107142b30SJingu Kang 104207142b30SJingu Kangexit: 104307142b30SJingu Kang ret i32 10 104407142b30SJingu Kang} 104507142b30SJingu Kang 104607142b30SJingu Kangdefine i32 @partial_unswitch_true_to_latch(i32* %ptr, i32 %N) { 104707142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_to_latch( 104807142b30SJingu Kang; CHECK-NEXT: entry: 1049*88b259c0SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 1050*88b259c0SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 1051*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 1052*88b259c0SJingu Kang; CHECK: entry.split.us: 1053*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 1054*88b259c0SJingu Kang; CHECK: loop.header.us: 1055*88b259c0SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 1056*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 1057*88b259c0SJingu Kang; CHECK: loop.latch.us: 1058*88b259c0SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 1059*88b259c0SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 1060*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 1061*88b259c0SJingu Kang; CHECK: exit.split.us: 1062*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 1063*88b259c0SJingu Kang; CHECK: entry.split: 106407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 106507142b30SJingu Kang; CHECK: loop.header: 1066*88b259c0SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 1067*88b259c0SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 106807142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 106907142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[LOOP_LATCH]], label [[CLOBBER:%.*]] 107007142b30SJingu Kang; CHECK: clobber: 107107142b30SJingu Kang; CHECK-NEXT: call void @clobber() 107207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 107307142b30SJingu Kang; CHECK: loop.latch: 1074*88b259c0SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 107507142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 1076*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 1077*88b259c0SJingu Kang; CHECK: exit.split: 1078*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT]] 107907142b30SJingu Kang; CHECK: exit: 108007142b30SJingu Kang; CHECK-NEXT: ret i32 10 108107142b30SJingu Kang; 108207142b30SJingu Kangentry: 108307142b30SJingu Kang br label %loop.header 108407142b30SJingu Kang 108507142b30SJingu Kangloop.header: 108607142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 108707142b30SJingu Kang %lv = load i32, i32* %ptr 108807142b30SJingu Kang %sc = icmp eq i32 %lv, 100 108907142b30SJingu Kang br i1 %sc, label %loop.latch, label %clobber 109007142b30SJingu Kang 109107142b30SJingu Kangclobber: 109207142b30SJingu Kang call void @clobber() 109307142b30SJingu Kang br label %loop.latch 109407142b30SJingu Kang 109507142b30SJingu Kangloop.latch: 109607142b30SJingu Kang %c = icmp ult i32 %iv, %N 109707142b30SJingu Kang %iv.next = add i32 %iv, 1 109807142b30SJingu Kang br i1 %c, label %loop.header, label %exit 109907142b30SJingu Kang 110007142b30SJingu Kangexit: 110107142b30SJingu Kang ret i32 10 110207142b30SJingu Kang} 1103*88b259c0SJingu Kang 1104*88b259c0SJingu Kang; There could be multiple unswitch candidates which include partially invariant 1105*88b259c0SJingu Kang; condition. When the exiting block is selected as best unswitch one, clone loop 1106*88b259c0SJingu Kang; blocks. 1107*88b259c0SJingu Kangdefine i32 @partial_unswitch_exiting_block_with_multiple_unswitch_candidates(i32 %0, i32 %1, i32* %ptr) { 1108*88b259c0SJingu Kang; CHECK-LABEL: @partial_unswitch_exiting_block_with_multiple_unswitch_candidates( 1109*88b259c0SJingu Kang; CHECK-NEXT: entry: 1110*88b259c0SJingu Kang; CHECK-NEXT: [[EXIT_COND:%.*]] = icmp ne i32 [[TMP0:%.*]], 0 1111*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[EXIT_COND]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 1112*88b259c0SJingu Kang; CHECK: entry.split.us: 1113*88b259c0SJingu Kang; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[PTR:%.*]], align 16 1114*88b259c0SJingu Kang; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[TMP2]], 41 1115*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[TMP3]], label [[ENTRY_SPLIT_US_SPLIT:%.*]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]] 1116*88b259c0SJingu Kang; CHECK: entry.split.us.split.us: 1117*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_US_US:%.*]] 1118*88b259c0SJingu Kang; CHECK: loop.us.us: 1119*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXITING_US_US:%.*]] 1120*88b259c0SJingu Kang; CHECK: exiting.us.us: 1121*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_US_US]] 1122*88b259c0SJingu Kang; CHECK: entry.split.us.split: 1123*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_US:%.*]] 1124*88b259c0SJingu Kang; CHECK: loop.us: 1125*88b259c0SJingu Kang; CHECK-NEXT: [[VAL_US:%.*]] = load i32, i32* [[PTR]], align 16 1126*88b259c0SJingu Kang; CHECK-NEXT: [[IF_COND_US:%.*]] = icmp ult i32 [[VAL_US]], 41 1127*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[IF_COND_US]], label [[IF_THEN_US:%.*]], label [[EXITING_US:%.*]] 1128*88b259c0SJingu Kang; CHECK: if.then.us: 1129*88b259c0SJingu Kang; CHECK-NEXT: store i32 [[TMP1:%.*]], i32* [[PTR]], align 16 1130*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXITING_US]] 1131*88b259c0SJingu Kang; CHECK: exiting.us: 1132*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP_US]] 1133*88b259c0SJingu Kang; CHECK: entry.split: 1134*88b259c0SJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 1135*88b259c0SJingu Kang; CHECK: loop: 1136*88b259c0SJingu Kang; CHECK-NEXT: [[VAL:%.*]] = load i32, i32* [[PTR]], align 16 1137*88b259c0SJingu Kang; CHECK-NEXT: [[IF_COND:%.*]] = icmp ult i32 [[VAL]], 41 1138*88b259c0SJingu Kang; CHECK-NEXT: br i1 [[IF_COND]], label [[IF_THEN:%.*]], label [[EXITING:%.*]] 1139*88b259c0SJingu Kang; CHECK: if.then: 1140*88b259c0SJingu Kang; CHECK-NEXT: store i32 [[TMP1]], i32* [[PTR]], align 16 1141*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXITING]] 1142*88b259c0SJingu Kang; CHECK: exiting: 1143*88b259c0SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 1144*88b259c0SJingu Kang; CHECK: exit: 1145*88b259c0SJingu Kang; CHECK-NEXT: [[RET_VAL:%.*]] = phi i32 [ 1, [[EXITING]] ] 1146*88b259c0SJingu Kang; CHECK-NEXT: ret i32 [[RET_VAL]] 1147*88b259c0SJingu Kang; 1148*88b259c0SJingu Kangentry: 1149*88b259c0SJingu Kang %exit.cond = icmp ne i32 %0, 0 1150*88b259c0SJingu Kang br label %loop 1151*88b259c0SJingu Kang 1152*88b259c0SJingu Kangloop: 1153*88b259c0SJingu Kang %val = load i32, i32* %ptr, align 16 1154*88b259c0SJingu Kang %if.cond = icmp ult i32 %val, 41 1155*88b259c0SJingu Kang br i1 %if.cond, label %if.then, label %exiting 1156*88b259c0SJingu Kang 1157*88b259c0SJingu Kangif.then: 1158*88b259c0SJingu Kang store i32 %1, i32* %ptr, align 16 1159*88b259c0SJingu Kang br label %exiting 1160*88b259c0SJingu Kang 1161*88b259c0SJingu Kangexiting: 1162*88b259c0SJingu Kang br i1 %exit.cond, label %loop, label %exit 1163*88b259c0SJingu Kang 1164*88b259c0SJingu Kangexit: 1165*88b259c0SJingu Kang %ret.val = phi i32 [ 1, %exiting ] 1166*88b259c0SJingu Kang ret i32 %ret.val 1167*88b259c0SJingu Kang} 1168