1*07142b30SJingu Kang; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2*07142b30SJingu Kang; RUN: opt -passes='loop-mssa(unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s 3*07142b30SJingu Kang 4*07142b30SJingu Kangdeclare void @clobber() 5*07142b30SJingu Kang 6*07142b30SJingu Kangdefine i32 @partial_unswitch_true_successor(i32* %ptr, i32 %N) { 7*07142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor( 8*07142b30SJingu Kang; CHECK-NEXT: entry: 9*07142b30SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 10*07142b30SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 11*07142b30SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 12*07142b30SJingu Kang; CHECK: entry.split.us: 13*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 14*07142b30SJingu Kang; CHECK: loop.header.us: 15*07142b30SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 16*07142b30SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 17*07142b30SJingu Kang; CHECK: noclobber.us: 18*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 19*07142b30SJingu Kang; CHECK: loop.latch.us: 20*07142b30SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 21*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 22*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 23*07142b30SJingu Kang; CHECK: exit.split.us: 24*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 25*07142b30SJingu Kang; CHECK: entry.split: 26*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 27*07142b30SJingu Kang; CHECK: loop.header: 28*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 29*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 30*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 31*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 32*07142b30SJingu Kang; CHECK: noclobber: 33*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 34*07142b30SJingu Kang; CHECK: clobber: 35*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 36*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 37*07142b30SJingu Kang; CHECK: loop.latch: 38*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 39*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 40*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 41*07142b30SJingu Kang; CHECK: exit.split: 42*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 43*07142b30SJingu Kang; CHECK: exit: 44*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 45*07142b30SJingu Kang; 46*07142b30SJingu Kangentry: 47*07142b30SJingu Kang br label %loop.header 48*07142b30SJingu Kang 49*07142b30SJingu Kangloop.header: 50*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 51*07142b30SJingu Kang %lv = load i32, i32* %ptr 52*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 53*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 54*07142b30SJingu Kang 55*07142b30SJingu Kangnoclobber: 56*07142b30SJingu Kang br label %loop.latch 57*07142b30SJingu Kang 58*07142b30SJingu Kangclobber: 59*07142b30SJingu Kang call void @clobber() 60*07142b30SJingu Kang br label %loop.latch 61*07142b30SJingu Kang 62*07142b30SJingu Kangloop.latch: 63*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 64*07142b30SJingu Kang %iv.next = add i32 %iv, 1 65*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 66*07142b30SJingu Kang 67*07142b30SJingu Kangexit: 68*07142b30SJingu Kang ret i32 10 69*07142b30SJingu Kang} 70*07142b30SJingu Kang 71*07142b30SJingu Kangdefine i32 @partial_unswitch_false_successor(i32* %ptr, i32 %N) { 72*07142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_false_successor( 73*07142b30SJingu Kang; CHECK-NEXT: entry: 74*07142b30SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 75*07142b30SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 76*07142b30SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]] 77*07142b30SJingu Kang; CHECK: entry.split.us: 78*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 79*07142b30SJingu Kang; CHECK: loop.header.us: 80*07142b30SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 81*07142b30SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 82*07142b30SJingu Kang; CHECK: noclobber.us: 83*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 84*07142b30SJingu Kang; CHECK: loop.latch.us: 85*07142b30SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 86*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 87*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 88*07142b30SJingu Kang; CHECK: exit.split.us: 89*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 90*07142b30SJingu Kang; CHECK: entry.split: 91*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 92*07142b30SJingu Kang; CHECK: loop.header: 93*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 94*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 95*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 96*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 97*07142b30SJingu Kang; CHECK: clobber: 98*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 99*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 100*07142b30SJingu Kang; CHECK: noclobber: 101*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 102*07142b30SJingu Kang; CHECK: loop.latch: 103*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 104*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 105*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 106*07142b30SJingu Kang; CHECK: exit.split: 107*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 108*07142b30SJingu Kang; CHECK: exit: 109*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 110*07142b30SJingu Kang; 111*07142b30SJingu Kangentry: 112*07142b30SJingu Kang br label %loop.header 113*07142b30SJingu Kang 114*07142b30SJingu Kangloop.header: 115*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 116*07142b30SJingu Kang %lv = load i32, i32* %ptr 117*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 118*07142b30SJingu Kang br i1 %sc, label %clobber, label %noclobber 119*07142b30SJingu Kang 120*07142b30SJingu Kangclobber: 121*07142b30SJingu Kang call void @clobber() 122*07142b30SJingu Kang br label %loop.latch 123*07142b30SJingu Kang 124*07142b30SJingu Kangnoclobber: 125*07142b30SJingu Kang br label %loop.latch 126*07142b30SJingu Kang 127*07142b30SJingu Kangloop.latch: 128*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 129*07142b30SJingu Kang %iv.next = add i32 %iv, 1 130*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 131*07142b30SJingu Kang 132*07142b30SJingu Kangexit: 133*07142b30SJingu Kang ret i32 10 134*07142b30SJingu Kang} 135*07142b30SJingu Kang 136*07142b30SJingu Kangdefine i32 @partial_unswtich_gep_load_icmp(i32** %ptr, i32 %N) { 137*07142b30SJingu Kang; CHECK-LABEL: @partial_unswtich_gep_load_icmp( 138*07142b30SJingu Kang; CHECK-NEXT: entry: 139*07142b30SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32*, i32** [[PTR:%.*]], i32 1 140*07142b30SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 8 141*07142b30SJingu Kang; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 142*07142b30SJingu Kang; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 100 143*07142b30SJingu Kang; CHECK-NEXT: br i1 [[TMP3]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 144*07142b30SJingu Kang; CHECK: entry.split.us: 145*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 146*07142b30SJingu Kang; CHECK: loop.header.us: 147*07142b30SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 148*07142b30SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 149*07142b30SJingu Kang; CHECK: noclobber.us: 150*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 151*07142b30SJingu Kang; CHECK: loop.latch.us: 152*07142b30SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 153*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 154*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 155*07142b30SJingu Kang; CHECK: exit.split.us: 156*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 157*07142b30SJingu Kang; CHECK: entry.split: 158*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 159*07142b30SJingu Kang; CHECK: loop.header: 160*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 161*07142b30SJingu Kang; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32*, i32** [[PTR]], i32 1 162*07142b30SJingu Kang; CHECK-NEXT: [[LV_1:%.*]] = load i32*, i32** [[GEP]], align 8 163*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[LV_1]], align 4 164*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 165*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 166*07142b30SJingu Kang; CHECK: noclobber: 167*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 168*07142b30SJingu Kang; CHECK: clobber: 169*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 170*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 171*07142b30SJingu Kang; CHECK: loop.latch: 172*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 173*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 174*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 175*07142b30SJingu Kang; CHECK: exit.split: 176*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 177*07142b30SJingu Kang; CHECK: exit: 178*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 179*07142b30SJingu Kang; 180*07142b30SJingu Kangentry: 181*07142b30SJingu Kang br label %loop.header 182*07142b30SJingu Kang 183*07142b30SJingu Kangloop.header: 184*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 185*07142b30SJingu Kang %gep = getelementptr i32*, i32** %ptr, i32 1 186*07142b30SJingu Kang %lv.1 = load i32*, i32** %gep 187*07142b30SJingu Kang %lv = load i32, i32* %lv.1 188*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 189*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 190*07142b30SJingu Kang 191*07142b30SJingu Kangnoclobber: 192*07142b30SJingu Kang br label %loop.latch 193*07142b30SJingu Kang 194*07142b30SJingu Kangclobber: 195*07142b30SJingu Kang call void @clobber() 196*07142b30SJingu Kang br label %loop.latch 197*07142b30SJingu Kang 198*07142b30SJingu Kangloop.latch: 199*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 200*07142b30SJingu Kang %iv.next = add i32 %iv, 1 201*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 202*07142b30SJingu Kang 203*07142b30SJingu Kangexit: 204*07142b30SJingu Kang ret i32 10 205*07142b30SJingu Kang} 206*07142b30SJingu Kang 207*07142b30SJingu Kangdefine i32 @partial_unswitch_reduction_phi(i32* %ptr, i32 %N) { 208*07142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_reduction_phi( 209*07142b30SJingu Kang; CHECK-NEXT: entry: 210*07142b30SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 211*07142b30SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 212*07142b30SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]] 213*07142b30SJingu Kang; CHECK: entry.split.us: 214*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 215*07142b30SJingu Kang; CHECK: loop.header.us: 216*07142b30SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 217*07142b30SJingu Kang; CHECK-NEXT: [[RED_US:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT_US]] ], [ [[RED_NEXT_US:%.*]], [[LOOP_LATCH_US]] ] 218*07142b30SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 219*07142b30SJingu Kang; CHECK: noclobber.us: 220*07142b30SJingu Kang; CHECK-NEXT: [[ADD_10_US:%.*]] = add i32 [[RED_US]], 10 221*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 222*07142b30SJingu Kang; CHECK: loop.latch.us: 223*07142b30SJingu Kang; CHECK-NEXT: [[RED_NEXT_US]] = phi i32 [ [[ADD_10_US]], [[NOCLOBBER_US]] ] 224*07142b30SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 225*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 226*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 227*07142b30SJingu Kang; CHECK: exit.split.us: 228*07142b30SJingu Kang; CHECK-NEXT: [[RED_NEXT_LCSSA_US:%.*]] = phi i32 [ [[RED_NEXT_US]], [[LOOP_LATCH_US]] ] 229*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 230*07142b30SJingu Kang; CHECK: entry.split: 231*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 232*07142b30SJingu Kang; CHECK: loop.header: 233*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 234*07142b30SJingu Kang; CHECK-NEXT: [[RED:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT]] ], [ [[RED_NEXT:%.*]], [[LOOP_LATCH]] ] 235*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 236*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 237*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 238*07142b30SJingu Kang; CHECK: clobber: 239*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 240*07142b30SJingu Kang; CHECK-NEXT: [[ADD_5:%.*]] = add i32 [[RED]], 5 241*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 242*07142b30SJingu Kang; CHECK: noclobber: 243*07142b30SJingu Kang; CHECK-NEXT: [[ADD_10:%.*]] = add i32 [[RED]], 10 244*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 245*07142b30SJingu Kang; CHECK: loop.latch: 246*07142b30SJingu Kang; CHECK-NEXT: [[RED_NEXT]] = phi i32 [ [[ADD_5]], [[CLOBBER]] ], [ [[ADD_10]], [[NOCLOBBER]] ] 247*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 248*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 249*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 250*07142b30SJingu Kang; CHECK: exit.split: 251*07142b30SJingu Kang; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ] 252*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 253*07142b30SJingu Kang; CHECK: exit: 254*07142b30SJingu Kang; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RED_NEXT_LCSSA]], [[EXIT_SPLIT]] ], [ [[RED_NEXT_LCSSA_US]], [[EXIT_SPLIT_US]] ] 255*07142b30SJingu Kang; CHECK-NEXT: ret i32 [[DOTUS_PHI]] 256*07142b30SJingu Kang; 257*07142b30SJingu Kangentry: 258*07142b30SJingu Kang br label %loop.header 259*07142b30SJingu Kang 260*07142b30SJingu Kangloop.header: 261*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 262*07142b30SJingu Kang %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ] 263*07142b30SJingu Kang %lv = load i32, i32* %ptr 264*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 265*07142b30SJingu Kang br i1 %sc, label %clobber, label %noclobber 266*07142b30SJingu Kang 267*07142b30SJingu Kangclobber: 268*07142b30SJingu Kang call void @clobber() 269*07142b30SJingu Kang %add.5 = add i32 %red, 5 270*07142b30SJingu Kang br label %loop.latch 271*07142b30SJingu Kang 272*07142b30SJingu Kangnoclobber: 273*07142b30SJingu Kang %add.10 = add i32 %red, 10 274*07142b30SJingu Kang br label %loop.latch 275*07142b30SJingu Kang 276*07142b30SJingu Kangloop.latch: 277*07142b30SJingu Kang %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ] 278*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 279*07142b30SJingu Kang %iv.next = add i32 %iv, 1 280*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 281*07142b30SJingu Kang 282*07142b30SJingu Kangexit: 283*07142b30SJingu Kang %red.next.lcssa = phi i32 [ %red.next, %loop.latch ] 284*07142b30SJingu Kang ret i32 %red.next.lcssa 285*07142b30SJingu Kang} 286*07142b30SJingu Kang 287*07142b30SJingu Kang; Partial unswitching is possible, because the store in %noclobber does not 288*07142b30SJingu Kang; alias the load of the condition. 289*07142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_noclobber(i32* noalias %ptr.1, i32* noalias %ptr.2, i32 %N) { 290*07142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_noclobber( 291*07142b30SJingu Kang; CHECK-NEXT: entry: 292*07142b30SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4 293*07142b30SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 294*07142b30SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 295*07142b30SJingu Kang; CHECK: entry.split.us: 296*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 297*07142b30SJingu Kang; CHECK: loop.header.us: 298*07142b30SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 299*07142b30SJingu Kang; CHECK-NEXT: [[LV_US:%.*]] = load i32, i32* [[PTR_1]], align 4 300*07142b30SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 301*07142b30SJingu Kang; CHECK: noclobber.us: 302*07142b30SJingu Kang; CHECK-NEXT: [[GEP_1_US:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV_US]] 303*07142b30SJingu Kang; CHECK-NEXT: store i32 [[LV_US]], i32* [[GEP_1_US]], align 4 304*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 305*07142b30SJingu Kang; CHECK: loop.latch.us: 306*07142b30SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 307*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 308*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 309*07142b30SJingu Kang; CHECK: exit.split.us: 310*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 311*07142b30SJingu Kang; CHECK: entry.split: 312*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 313*07142b30SJingu Kang; CHECK: loop.header: 314*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 315*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR_1]], align 4 316*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 317*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 318*07142b30SJingu Kang; CHECK: noclobber: 319*07142b30SJingu Kang; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2]], i32 [[IV]] 320*07142b30SJingu Kang; CHECK-NEXT: store i32 [[LV]], i32* [[GEP_1]], align 4 321*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 322*07142b30SJingu Kang; CHECK: clobber: 323*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 324*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 325*07142b30SJingu Kang; CHECK: loop.latch: 326*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 327*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 328*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 329*07142b30SJingu Kang; CHECK: exit.split: 330*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 331*07142b30SJingu Kang; CHECK: exit: 332*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 333*07142b30SJingu Kang; 334*07142b30SJingu Kangentry: 335*07142b30SJingu Kang br label %loop.header 336*07142b30SJingu Kang 337*07142b30SJingu Kangloop.header: 338*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 339*07142b30SJingu Kang %lv = load i32, i32* %ptr.1 340*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 341*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 342*07142b30SJingu Kang 343*07142b30SJingu Kangnoclobber: 344*07142b30SJingu Kang %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv 345*07142b30SJingu Kang store i32 %lv, i32* %gep.1 346*07142b30SJingu Kang br label %loop.latch 347*07142b30SJingu Kang 348*07142b30SJingu Kangclobber: 349*07142b30SJingu Kang call void @clobber() 350*07142b30SJingu Kang br label %loop.latch 351*07142b30SJingu Kang 352*07142b30SJingu Kangloop.latch: 353*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 354*07142b30SJingu Kang %iv.next = add i32 %iv, 1 355*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 356*07142b30SJingu Kang 357*07142b30SJingu Kangexit: 358*07142b30SJingu Kang ret i32 10 359*07142b30SJingu Kang} 360*07142b30SJingu Kang 361*07142b30SJingu Kangdefine void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) { 362*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_phi_cond( 363*07142b30SJingu Kang; CHECK-NEXT: entry: 364*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 365*07142b30SJingu Kang; CHECK: loop.header: 366*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 367*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = phi i1 [ [[LC:%.*]], [[ENTRY]] ], [ true, [[LOOP_LATCH]] ] 368*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 369*07142b30SJingu Kang; CHECK: clobber: 370*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 371*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 372*07142b30SJingu Kang; CHECK: noclobber: 373*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 374*07142b30SJingu Kang; CHECK: loop.latch: 375*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 376*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 377*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 378*07142b30SJingu Kang; CHECK: exit: 379*07142b30SJingu Kang; CHECK-NEXT: ret void 380*07142b30SJingu Kang; 381*07142b30SJingu Kangentry: 382*07142b30SJingu Kang br label %loop.header 383*07142b30SJingu Kang 384*07142b30SJingu Kangloop.header: 385*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 386*07142b30SJingu Kang %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ] 387*07142b30SJingu Kang br i1 %sc, label %clobber, label %noclobber 388*07142b30SJingu Kang 389*07142b30SJingu Kangclobber: 390*07142b30SJingu Kang call void @clobber() 391*07142b30SJingu Kang br label %loop.latch 392*07142b30SJingu Kang 393*07142b30SJingu Kangnoclobber: 394*07142b30SJingu Kang br label %loop.latch 395*07142b30SJingu Kang 396*07142b30SJingu Kangloop.latch: 397*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 398*07142b30SJingu Kang %iv.next = add i32 %iv, 1 399*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 400*07142b30SJingu Kang 401*07142b30SJingu Kangexit: 402*07142b30SJingu Kang ret void 403*07142b30SJingu Kang} 404*07142b30SJingu Kang 405*07142b30SJingu Kangdefine void @no_partial_unswitch_clobber_latch(i32* %ptr, i32 %N) { 406*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_latch( 407*07142b30SJingu Kang; CHECK-NEXT: entry: 408*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 409*07142b30SJingu Kang; CHECK: loop.header: 410*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 411*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 412*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 413*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 414*07142b30SJingu Kang; CHECK: noclobber: 415*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 416*07142b30SJingu Kang; CHECK: clobber: 417*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 418*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 419*07142b30SJingu Kang; CHECK: loop.latch: 420*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 421*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 422*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 423*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 424*07142b30SJingu Kang; CHECK: exit: 425*07142b30SJingu Kang; CHECK-NEXT: ret void 426*07142b30SJingu Kang; 427*07142b30SJingu Kangentry: 428*07142b30SJingu Kang br label %loop.header 429*07142b30SJingu Kang 430*07142b30SJingu Kangloop.header: 431*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 432*07142b30SJingu Kang %lv = load i32, i32* %ptr 433*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 434*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 435*07142b30SJingu Kang 436*07142b30SJingu Kangnoclobber: 437*07142b30SJingu Kang br label %loop.latch 438*07142b30SJingu Kang 439*07142b30SJingu Kangclobber: 440*07142b30SJingu Kang call void @clobber() 441*07142b30SJingu Kang br label %loop.latch 442*07142b30SJingu Kang 443*07142b30SJingu Kangloop.latch: 444*07142b30SJingu Kang call void @clobber() 445*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 446*07142b30SJingu Kang %iv.next = add i32 %iv, 1 447*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 448*07142b30SJingu Kang 449*07142b30SJingu Kangexit: 450*07142b30SJingu Kang ret void 451*07142b30SJingu Kang} 452*07142b30SJingu Kang 453*07142b30SJingu Kangdefine void @no_partial_unswitch_clobber_header(i32* %ptr, i32 %N) { 454*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_header( 455*07142b30SJingu Kang; CHECK-NEXT: entry: 456*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 457*07142b30SJingu Kang; CHECK: loop.header: 458*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 459*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 460*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 461*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 462*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 463*07142b30SJingu Kang; CHECK: noclobber: 464*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 465*07142b30SJingu Kang; CHECK: clobber: 466*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 467*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 468*07142b30SJingu Kang; CHECK: loop.latch: 469*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 470*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 471*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 472*07142b30SJingu Kang; CHECK: exit: 473*07142b30SJingu Kang; CHECK-NEXT: ret void 474*07142b30SJingu Kang; 475*07142b30SJingu Kangentry: 476*07142b30SJingu Kang br label %loop.header 477*07142b30SJingu Kang 478*07142b30SJingu Kangloop.header: 479*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 480*07142b30SJingu Kang call void @clobber() 481*07142b30SJingu Kang %lv = load i32, i32* %ptr 482*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 483*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 484*07142b30SJingu Kang 485*07142b30SJingu Kangnoclobber: 486*07142b30SJingu Kang br label %loop.latch 487*07142b30SJingu Kang 488*07142b30SJingu Kangclobber: 489*07142b30SJingu Kang call void @clobber() 490*07142b30SJingu Kang br label %loop.latch 491*07142b30SJingu Kang 492*07142b30SJingu Kangloop.latch: 493*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 494*07142b30SJingu Kang %iv.next = add i32 %iv, 1 495*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 496*07142b30SJingu Kang 497*07142b30SJingu Kangexit: 498*07142b30SJingu Kang ret void 499*07142b30SJingu Kang} 500*07142b30SJingu Kang 501*07142b30SJingu Kangdefine void @no_partial_unswitch_clobber_both(i32* %ptr, i32 %N) { 502*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_both( 503*07142b30SJingu Kang; CHECK-NEXT: entry: 504*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 505*07142b30SJingu Kang; CHECK: loop.header: 506*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 507*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 508*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 509*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 510*07142b30SJingu Kang; CHECK: noclobber: 511*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 512*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 513*07142b30SJingu Kang; CHECK: clobber: 514*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 515*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 516*07142b30SJingu Kang; CHECK: loop.latch: 517*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 518*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 519*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 520*07142b30SJingu Kang; CHECK: exit: 521*07142b30SJingu Kang; CHECK-NEXT: ret void 522*07142b30SJingu Kang; 523*07142b30SJingu Kangentry: 524*07142b30SJingu Kang br label %loop.header 525*07142b30SJingu Kang 526*07142b30SJingu Kangloop.header: 527*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 528*07142b30SJingu Kang %lv = load i32, i32* %ptr 529*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 530*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 531*07142b30SJingu Kang 532*07142b30SJingu Kangnoclobber: 533*07142b30SJingu Kang call void @clobber() 534*07142b30SJingu Kang br label %loop.latch 535*07142b30SJingu Kang 536*07142b30SJingu Kangclobber: 537*07142b30SJingu Kang call void @clobber() 538*07142b30SJingu Kang br label %loop.latch 539*07142b30SJingu Kang 540*07142b30SJingu Kangloop.latch: 541*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 542*07142b30SJingu Kang %iv.next = add i32 %iv, 1 543*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 544*07142b30SJingu Kang 545*07142b30SJingu Kangexit: 546*07142b30SJingu Kang ret void 547*07142b30SJingu Kang} 548*07142b30SJingu Kang 549*07142b30SJingu Kangdefine i32 @no_partial_unswitch_true_successor_storeclobber(i32* %ptr.1, i32* %ptr.2, i32 %N) { 550*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber( 551*07142b30SJingu Kang; CHECK-NEXT: entry: 552*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 553*07142b30SJingu Kang; CHECK: loop.header: 554*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 555*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4 556*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 557*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 558*07142b30SJingu Kang; CHECK: noclobber: 559*07142b30SJingu Kang; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV]] 560*07142b30SJingu Kang; CHECK-NEXT: store i32 [[LV]], i32* [[GEP_1]], align 4 561*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 562*07142b30SJingu Kang; CHECK: clobber: 563*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 564*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 565*07142b30SJingu Kang; CHECK: loop.latch: 566*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 567*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 568*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 569*07142b30SJingu Kang; CHECK: exit: 570*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 571*07142b30SJingu Kang; 572*07142b30SJingu Kangentry: 573*07142b30SJingu Kang br label %loop.header 574*07142b30SJingu Kang 575*07142b30SJingu Kangloop.header: 576*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 577*07142b30SJingu Kang %lv = load i32, i32* %ptr.1 578*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 579*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 580*07142b30SJingu Kang 581*07142b30SJingu Kangnoclobber: 582*07142b30SJingu Kang %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv 583*07142b30SJingu Kang store i32 %lv, i32* %gep.1 584*07142b30SJingu Kang br label %loop.latch 585*07142b30SJingu Kang 586*07142b30SJingu Kangclobber: 587*07142b30SJingu Kang call void @clobber() 588*07142b30SJingu Kang br label %loop.latch 589*07142b30SJingu Kang 590*07142b30SJingu Kangloop.latch: 591*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 592*07142b30SJingu Kang %iv.next = add i32 %iv, 1 593*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 594*07142b30SJingu Kang 595*07142b30SJingu Kangexit: 596*07142b30SJingu Kang ret i32 10 597*07142b30SJingu Kang} 598*07142b30SJingu Kang 599*07142b30SJingu Kang; Make sure the duplicated instructions are moved to a preheader that always 600*07142b30SJingu Kang; executes when the loop body also executes. Do not check the unswitched code, 601*07142b30SJingu Kang; because it is already checked in the @partial_unswitch_true_successor test 602*07142b30SJingu Kang; case. 603*07142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_preheader_insertion(i32* %ptr, i32 %N) { 604*07142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion( 605*07142b30SJingu Kang; CHECK-NEXT: entry: 606*07142b30SJingu Kang; CHECK-NEXT: [[EC:%.*]] = icmp ne i32* [[PTR:%.*]], null 607*07142b30SJingu Kang; CHECK-NEXT: br i1 [[EC]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]] 608*07142b30SJingu Kang; CHECK: loop.ph: 609*07142b30SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR]], align 4 610*07142b30SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 611*07142b30SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PH_SPLIT_US:%.*]], label [[LOOP_PH_SPLIT:%.*]] 612*07142b30SJingu Kang; CHECK: loop.ph.split.us: 613*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 614*07142b30SJingu Kang; CHECK: loop.header.us: 615*07142b30SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 616*07142b30SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 617*07142b30SJingu Kang; CHECK: noclobber.us: 618*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 619*07142b30SJingu Kang; CHECK: loop.latch.us: 620*07142b30SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 621*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 622*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_LOOPEXIT_SPLIT_US:%.*]] 623*07142b30SJingu Kang; CHECK: exit.loopexit.split.us: 624*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT_LOOPEXIT:%.*]] 625*07142b30SJingu Kang; CHECK: loop.ph.split: 626*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 627*07142b30SJingu Kang; CHECK: loop.header: 628*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 629*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 630*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 631*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 632*07142b30SJingu Kang; CHECK: noclobber: 633*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 634*07142b30SJingu Kang; CHECK: clobber: 635*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 636*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 637*07142b30SJingu Kang; CHECK: loop.latch: 638*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 639*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 640*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT_SPLIT:%.*]] 641*07142b30SJingu Kang; CHECK: exit.loopexit.split: 642*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT_LOOPEXIT]] 643*07142b30SJingu Kang; CHECK: exit.loopexit: 644*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 645*07142b30SJingu Kang; CHECK: exit: 646*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 647*07142b30SJingu Kang; 648*07142b30SJingu Kang 649*07142b30SJingu Kangentry: 650*07142b30SJingu Kang %ec = icmp ne i32* %ptr, null 651*07142b30SJingu Kang br i1 %ec, label %loop.ph, label %exit 652*07142b30SJingu Kang 653*07142b30SJingu Kangloop.ph: 654*07142b30SJingu Kang br label %loop.header 655*07142b30SJingu Kang 656*07142b30SJingu Kangloop.header: 657*07142b30SJingu Kang %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ] 658*07142b30SJingu Kang %lv = load i32, i32* %ptr 659*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 660*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 661*07142b30SJingu Kang 662*07142b30SJingu Kangnoclobber: 663*07142b30SJingu Kang br label %loop.latch 664*07142b30SJingu Kang 665*07142b30SJingu Kangclobber: 666*07142b30SJingu Kang call void @clobber() 667*07142b30SJingu Kang br label %loop.latch 668*07142b30SJingu Kang 669*07142b30SJingu Kangloop.latch: 670*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 671*07142b30SJingu Kang %iv.next = add i32 %iv, 1 672*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 673*07142b30SJingu Kang 674*07142b30SJingu Kangexit: 675*07142b30SJingu Kang ret i32 10 676*07142b30SJingu Kang} 677*07142b30SJingu Kang 678*07142b30SJingu Kang; Make sure the duplicated instructions are hoisted just before the branch of 679*07142b30SJingu Kang; the preheader. Do not check the unswitched code, because it is already checked 680*07142b30SJingu Kang; in the @partial_unswitch_true_successor test case 681*07142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_insert_point(i32* %ptr, i32 %N) { 682*07142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_insert_point( 683*07142b30SJingu Kang; CHECK-NEXT: entry: 684*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 685*07142b30SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 686*07142b30SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 687*07142b30SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 688*07142b30SJingu Kang; CHECK: entry.split.us: 689*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 690*07142b30SJingu Kang; CHECK: loop.header.us: 691*07142b30SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 692*07142b30SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 693*07142b30SJingu Kang; CHECK: noclobber.us: 694*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 695*07142b30SJingu Kang; CHECK: loop.latch.us: 696*07142b30SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 697*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 698*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 699*07142b30SJingu Kang; CHECK: exit.split.us: 700*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 701*07142b30SJingu Kang; CHECK: entry.split: 702*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 703*07142b30SJingu Kang; CHECK: loop.header: 704*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 705*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 706*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 707*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 708*07142b30SJingu Kang; CHECK: noclobber: 709*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 710*07142b30SJingu Kang; CHECK: clobber: 711*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 712*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 713*07142b30SJingu Kang; CHECK: loop.latch: 714*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 715*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 716*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 717*07142b30SJingu Kang; CHECK: exit.split: 718*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 719*07142b30SJingu Kang; CHECK: exit: 720*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 721*07142b30SJingu Kang; 722*07142b30SJingu Kangentry: 723*07142b30SJingu Kang call void @clobber() 724*07142b30SJingu Kang br label %loop.header 725*07142b30SJingu Kang 726*07142b30SJingu Kangloop.header: 727*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 728*07142b30SJingu Kang %lv = load i32, i32* %ptr 729*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 730*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 731*07142b30SJingu Kang 732*07142b30SJingu Kangnoclobber: 733*07142b30SJingu Kang br label %loop.latch 734*07142b30SJingu Kang 735*07142b30SJingu Kangclobber: 736*07142b30SJingu Kang call void @clobber() 737*07142b30SJingu Kang br label %loop.latch 738*07142b30SJingu Kang 739*07142b30SJingu Kangloop.latch: 740*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 741*07142b30SJingu Kang %iv.next = add i32 %iv, 1 742*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 743*07142b30SJingu Kang 744*07142b30SJingu Kangexit: 745*07142b30SJingu Kang ret i32 10 746*07142b30SJingu Kang} 747*07142b30SJingu Kang 748*07142b30SJingu Kang; Make sure invariant instructions in the loop are also hoisted to the preheader. 749*07142b30SJingu Kang; Do not check the unswitched code, because it is already checked in the 750*07142b30SJingu Kang; @partial_unswitch_true_successor test case 751*07142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_hoist_invariant(i32* %ptr, i32 %N) { 752*07142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant( 753*07142b30SJingu Kang; CHECK-NEXT: entry: 754*07142b30SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 1 755*07142b30SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 756*07142b30SJingu Kang; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 100 757*07142b30SJingu Kang; CHECK-NEXT: br i1 [[TMP2]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 758*07142b30SJingu Kang; CHECK: entry.split.us: 759*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 760*07142b30SJingu Kang; CHECK: loop.header.us: 761*07142b30SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 762*07142b30SJingu Kang; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] 763*07142b30SJingu Kang; CHECK: noclobber.us: 764*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 765*07142b30SJingu Kang; CHECK: loop.latch.us: 766*07142b30SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 767*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 768*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 769*07142b30SJingu Kang; CHECK: exit.split.us: 770*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 771*07142b30SJingu Kang; CHECK: entry.split: 772*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 773*07142b30SJingu Kang; CHECK: loop.header: 774*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 775*07142b30SJingu Kang; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR]], i64 1 776*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[GEP]], align 4 777*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 778*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 779*07142b30SJingu Kang; CHECK: noclobber: 780*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 781*07142b30SJingu Kang; CHECK: clobber: 782*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 783*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 784*07142b30SJingu Kang; CHECK: loop.latch: 785*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 786*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 787*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 788*07142b30SJingu Kang; CHECK: exit.split: 789*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 790*07142b30SJingu Kang; CHECK: exit: 791*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 792*07142b30SJingu Kang; 793*07142b30SJingu Kangentry: 794*07142b30SJingu Kang br label %loop.header 795*07142b30SJingu Kang 796*07142b30SJingu Kangloop.header: 797*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 798*07142b30SJingu Kang %gep = getelementptr i32, i32* %ptr, i64 1 799*07142b30SJingu Kang %lv = load i32, i32* %gep 800*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 801*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 802*07142b30SJingu Kang 803*07142b30SJingu Kangnoclobber: 804*07142b30SJingu Kang br label %loop.latch 805*07142b30SJingu Kang 806*07142b30SJingu Kangclobber: 807*07142b30SJingu Kang call void @clobber() 808*07142b30SJingu Kang br label %loop.latch 809*07142b30SJingu Kang 810*07142b30SJingu Kangloop.latch: 811*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 812*07142b30SJingu Kang %iv.next = add i32 %iv, 1 813*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 814*07142b30SJingu Kang 815*07142b30SJingu Kangexit: 816*07142b30SJingu Kang ret i32 10 817*07142b30SJingu Kang} 818*07142b30SJingu Kang 819*07142b30SJingu Kang; Do not unswitch if the condition depends on an atomic load. Duplicating such 820*07142b30SJingu Kang; loads is not safe. 821*07142b30SJingu Kangdefine i32 @no_partial_unswitch_atomic_load_unordered(i32* %ptr, i32 %N) { 822*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered( 823*07142b30SJingu Kang; CHECK-NEXT: entry: 824*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 825*07142b30SJingu Kang; CHECK: loop.header: 826*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 827*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] unordered, align 4 828*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 829*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 830*07142b30SJingu Kang; CHECK: noclobber: 831*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 832*07142b30SJingu Kang; CHECK: clobber: 833*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 834*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 835*07142b30SJingu Kang; CHECK: loop.latch: 836*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 837*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 838*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 839*07142b30SJingu Kang; CHECK: exit: 840*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 841*07142b30SJingu Kang; 842*07142b30SJingu Kangentry: 843*07142b30SJingu Kang br label %loop.header 844*07142b30SJingu Kang 845*07142b30SJingu Kangloop.header: 846*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 847*07142b30SJingu Kang %lv = load atomic i32, i32* %ptr unordered, align 4 848*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 849*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 850*07142b30SJingu Kang 851*07142b30SJingu Kangnoclobber: 852*07142b30SJingu Kang br label %loop.latch 853*07142b30SJingu Kang 854*07142b30SJingu Kangclobber: 855*07142b30SJingu Kang call void @clobber() 856*07142b30SJingu Kang br label %loop.latch 857*07142b30SJingu Kang 858*07142b30SJingu Kangloop.latch: 859*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 860*07142b30SJingu Kang %iv.next = add i32 %iv, 1 861*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 862*07142b30SJingu Kang 863*07142b30SJingu Kangexit: 864*07142b30SJingu Kang ret i32 10 865*07142b30SJingu Kang} 866*07142b30SJingu Kang 867*07142b30SJingu Kang; Do not unswitch if the condition depends on an atomic load. Duplicating such 868*07142b30SJingu Kang; loads is not safe. 869*07142b30SJingu Kangdefine i32 @no_partial_unswitch_atomic_load_monotonic(i32* %ptr, i32 %N) { 870*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic( 871*07142b30SJingu Kang; CHECK-NEXT: entry: 872*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 873*07142b30SJingu Kang; CHECK: loop.header: 874*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 875*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] monotonic, align 4 876*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 877*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 878*07142b30SJingu Kang; CHECK: noclobber: 879*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 880*07142b30SJingu Kang; CHECK: clobber: 881*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 882*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 883*07142b30SJingu Kang; CHECK: loop.latch: 884*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 885*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 886*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 887*07142b30SJingu Kang; CHECK: exit: 888*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 889*07142b30SJingu Kang; 890*07142b30SJingu Kangentry: 891*07142b30SJingu Kang br label %loop.header 892*07142b30SJingu Kang 893*07142b30SJingu Kangloop.header: 894*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 895*07142b30SJingu Kang %lv = load atomic i32, i32* %ptr monotonic, align 4 896*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 897*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 898*07142b30SJingu Kang 899*07142b30SJingu Kangnoclobber: 900*07142b30SJingu Kang br label %loop.latch 901*07142b30SJingu Kang 902*07142b30SJingu Kangclobber: 903*07142b30SJingu Kang call void @clobber() 904*07142b30SJingu Kang br label %loop.latch 905*07142b30SJingu Kang 906*07142b30SJingu Kangloop.latch: 907*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 908*07142b30SJingu Kang %iv.next = add i32 %iv, 1 909*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 910*07142b30SJingu Kang 911*07142b30SJingu Kangexit: 912*07142b30SJingu Kang ret i32 10 913*07142b30SJingu Kang} 914*07142b30SJingu Kang 915*07142b30SJingu Kang 916*07142b30SJingu Kangdeclare i32 @get_value() 917*07142b30SJingu Kang 918*07142b30SJingu Kang; Do not unswitch if the condition depends on a call, that may clobber memory. 919*07142b30SJingu Kang; Duplicating such a call is not safe. 920*07142b30SJingu Kangdefine i32 @no_partial_unswitch_cond_call(i32* %ptr, i32 %N) { 921*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_cond_call( 922*07142b30SJingu Kang; CHECK-NEXT: entry: 923*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 924*07142b30SJingu Kang; CHECK: loop.header: 925*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 926*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = call i32 @get_value() 927*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 928*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 929*07142b30SJingu Kang; CHECK: noclobber: 930*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 931*07142b30SJingu Kang; CHECK: clobber: 932*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 933*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 934*07142b30SJingu Kang; CHECK: loop.latch: 935*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 936*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 937*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 938*07142b30SJingu Kang; CHECK: exit: 939*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 940*07142b30SJingu Kang; 941*07142b30SJingu Kangentry: 942*07142b30SJingu Kang br label %loop.header 943*07142b30SJingu Kang 944*07142b30SJingu Kangloop.header: 945*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 946*07142b30SJingu Kang %lv = call i32 @get_value() 947*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 948*07142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 949*07142b30SJingu Kang 950*07142b30SJingu Kangnoclobber: 951*07142b30SJingu Kang br label %loop.latch 952*07142b30SJingu Kang 953*07142b30SJingu Kangclobber: 954*07142b30SJingu Kang call void @clobber() 955*07142b30SJingu Kang br label %loop.latch 956*07142b30SJingu Kang 957*07142b30SJingu Kangloop.latch: 958*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 959*07142b30SJingu Kang %iv.next = add i32 %iv, 1 960*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 961*07142b30SJingu Kang 962*07142b30SJingu Kangexit: 963*07142b30SJingu Kang ret i32 10 964*07142b30SJingu Kang} 965*07142b30SJingu Kang 966*07142b30SJingu Kangdefine i32 @no_partial_unswitch_true_successor_exit(i32* %ptr, i32 %N) { 967*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_successor_exit( 968*07142b30SJingu Kang; CHECK-NEXT: entry: 969*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 970*07142b30SJingu Kang; CHECK: loop.header: 971*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 972*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 973*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 974*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[EXIT:%.*]], label [[CLOBBER:%.*]] 975*07142b30SJingu Kang; CHECK: clobber: 976*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 977*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 978*07142b30SJingu Kang; CHECK: loop.latch: 979*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 980*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 981*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT]] 982*07142b30SJingu Kang; CHECK: exit: 983*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 984*07142b30SJingu Kang; 985*07142b30SJingu Kangentry: 986*07142b30SJingu Kang br label %loop.header 987*07142b30SJingu Kang 988*07142b30SJingu Kangloop.header: 989*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 990*07142b30SJingu Kang %lv = load i32, i32* %ptr 991*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 992*07142b30SJingu Kang br i1 %sc, label %exit, label %clobber 993*07142b30SJingu Kang 994*07142b30SJingu Kangclobber: 995*07142b30SJingu Kang call void @clobber() 996*07142b30SJingu Kang br label %loop.latch 997*07142b30SJingu Kang 998*07142b30SJingu Kangloop.latch: 999*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 1000*07142b30SJingu Kang %iv.next = add i32 %iv, 1 1001*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 1002*07142b30SJingu Kang 1003*07142b30SJingu Kangexit: 1004*07142b30SJingu Kang ret i32 10 1005*07142b30SJingu Kang} 1006*07142b30SJingu Kang 1007*07142b30SJingu Kangdefine i32 @no_partial_unswitch_true_same_successor(i32* %ptr, i32 %N) { 1008*07142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_same_successor( 1009*07142b30SJingu Kang; CHECK-NEXT: entry: 1010*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 1011*07142b30SJingu Kang; CHECK: loop.header: 1012*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 1013*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 1014*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 1015*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[NOCLOBBER]] 1016*07142b30SJingu Kang; CHECK: noclobber: 1017*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 1018*07142b30SJingu Kang; CHECK: loop.latch: 1019*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 1020*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 1021*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 1022*07142b30SJingu Kang; CHECK: exit: 1023*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 1024*07142b30SJingu Kang; 1025*07142b30SJingu Kangentry: 1026*07142b30SJingu Kang br label %loop.header 1027*07142b30SJingu Kang 1028*07142b30SJingu Kangloop.header: 1029*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 1030*07142b30SJingu Kang %lv = load i32, i32* %ptr 1031*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 1032*07142b30SJingu Kang br i1 %sc, label %noclobber, label %noclobber 1033*07142b30SJingu Kang 1034*07142b30SJingu Kangnoclobber: 1035*07142b30SJingu Kang br label %loop.latch 1036*07142b30SJingu Kang 1037*07142b30SJingu Kangloop.latch: 1038*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 1039*07142b30SJingu Kang %iv.next = add i32 %iv, 1 1040*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 1041*07142b30SJingu Kang 1042*07142b30SJingu Kangexit: 1043*07142b30SJingu Kang ret i32 10 1044*07142b30SJingu Kang} 1045*07142b30SJingu Kang 1046*07142b30SJingu Kangdefine i32 @partial_unswitch_true_to_latch(i32* %ptr, i32 %N) { 1047*07142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_to_latch( 1048*07142b30SJingu Kang; CHECK-NEXT: entry: 1049*07142b30SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[PTR:%.*]], align 4 1050*07142b30SJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 1051*07142b30SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 1052*07142b30SJingu Kang; CHECK: entry.split.us: 1053*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 1054*07142b30SJingu Kang; CHECK: loop.header.us: 1055*07142b30SJingu Kang; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] 1056*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH_US]] 1057*07142b30SJingu Kang; CHECK: loop.latch.us: 1058*07142b30SJingu Kang; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] 1059*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 1060*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] 1061*07142b30SJingu Kang; CHECK: exit.split.us: 1062*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT:%.*]] 1063*07142b30SJingu Kang; CHECK: entry.split: 1064*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 1065*07142b30SJingu Kang; CHECK: loop.header: 1066*07142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 1067*07142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR]], align 4 1068*07142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 1069*07142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[LOOP_LATCH]], label [[CLOBBER:%.*]] 1070*07142b30SJingu Kang; CHECK: clobber: 1071*07142b30SJingu Kang; CHECK-NEXT: call void @clobber() 1072*07142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 1073*07142b30SJingu Kang; CHECK: loop.latch: 1074*07142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] 1075*07142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 1076*07142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]] 1077*07142b30SJingu Kang; CHECK: exit.split: 1078*07142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 1079*07142b30SJingu Kang; CHECK: exit: 1080*07142b30SJingu Kang; CHECK-NEXT: ret i32 10 1081*07142b30SJingu Kang; 1082*07142b30SJingu Kangentry: 1083*07142b30SJingu Kang br label %loop.header 1084*07142b30SJingu Kang 1085*07142b30SJingu Kangloop.header: 1086*07142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 1087*07142b30SJingu Kang %lv = load i32, i32* %ptr 1088*07142b30SJingu Kang %sc = icmp eq i32 %lv, 100 1089*07142b30SJingu Kang br i1 %sc, label %loop.latch, label %clobber 1090*07142b30SJingu Kang 1091*07142b30SJingu Kangclobber: 1092*07142b30SJingu Kang call void @clobber() 1093*07142b30SJingu Kang br label %loop.latch 1094*07142b30SJingu Kang 1095*07142b30SJingu Kangloop.latch: 1096*07142b30SJingu Kang %c = icmp ult i32 %iv, %N 1097*07142b30SJingu Kang %iv.next = add i32 %iv, 1 1098*07142b30SJingu Kang br i1 %c, label %loop.header, label %exit 1099*07142b30SJingu Kang 1100*07142b30SJingu Kangexit: 1101*07142b30SJingu Kang ret i32 10 1102*07142b30SJingu Kang} 1103