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: 907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 1007142b30SJingu Kang; CHECK: loop.header: 11*107d19ebSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 12*107d19ebSJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 1307142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 1407142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 1507142b30SJingu Kang; CHECK: noclobber: 1607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 1707142b30SJingu Kang; CHECK: clobber: 1807142b30SJingu Kang; CHECK-NEXT: call void @clobber() 1907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 2007142b30SJingu Kang; CHECK: loop.latch: 21*107d19ebSJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 2207142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 23*107d19ebSJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 2407142b30SJingu Kang; CHECK: exit: 2507142b30SJingu Kang; CHECK-NEXT: ret i32 10 2607142b30SJingu Kang; 2707142b30SJingu Kangentry: 2807142b30SJingu Kang br label %loop.header 2907142b30SJingu Kang 3007142b30SJingu Kangloop.header: 3107142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 3207142b30SJingu Kang %lv = load i32, i32* %ptr 3307142b30SJingu Kang %sc = icmp eq i32 %lv, 100 3407142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 3507142b30SJingu Kang 3607142b30SJingu Kangnoclobber: 3707142b30SJingu Kang br label %loop.latch 3807142b30SJingu Kang 3907142b30SJingu Kangclobber: 4007142b30SJingu Kang call void @clobber() 4107142b30SJingu Kang br label %loop.latch 4207142b30SJingu Kang 4307142b30SJingu Kangloop.latch: 4407142b30SJingu Kang %c = icmp ult i32 %iv, %N 4507142b30SJingu Kang %iv.next = add i32 %iv, 1 4607142b30SJingu Kang br i1 %c, label %loop.header, label %exit 4707142b30SJingu Kang 4807142b30SJingu Kangexit: 4907142b30SJingu Kang ret i32 10 5007142b30SJingu Kang} 5107142b30SJingu Kang 5207142b30SJingu Kangdefine i32 @partial_unswitch_false_successor(i32* %ptr, i32 %N) { 5307142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_false_successor( 5407142b30SJingu Kang; CHECK-NEXT: entry: 5507142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 5607142b30SJingu Kang; CHECK: loop.header: 57*107d19ebSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 58*107d19ebSJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 5907142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 6007142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 6107142b30SJingu Kang; CHECK: clobber: 6207142b30SJingu Kang; CHECK-NEXT: call void @clobber() 6307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 6407142b30SJingu Kang; CHECK: noclobber: 6507142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 6607142b30SJingu Kang; CHECK: loop.latch: 67*107d19ebSJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 6807142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 69*107d19ebSJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 7007142b30SJingu Kang; CHECK: exit: 7107142b30SJingu Kang; CHECK-NEXT: ret i32 10 7207142b30SJingu Kang; 7307142b30SJingu Kangentry: 7407142b30SJingu Kang br label %loop.header 7507142b30SJingu Kang 7607142b30SJingu Kangloop.header: 7707142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 7807142b30SJingu Kang %lv = load i32, i32* %ptr 7907142b30SJingu Kang %sc = icmp eq i32 %lv, 100 8007142b30SJingu Kang br i1 %sc, label %clobber, label %noclobber 8107142b30SJingu Kang 8207142b30SJingu Kangclobber: 8307142b30SJingu Kang call void @clobber() 8407142b30SJingu Kang br label %loop.latch 8507142b30SJingu Kang 8607142b30SJingu Kangnoclobber: 8707142b30SJingu Kang br label %loop.latch 8807142b30SJingu Kang 8907142b30SJingu Kangloop.latch: 9007142b30SJingu Kang %c = icmp ult i32 %iv, %N 9107142b30SJingu Kang %iv.next = add i32 %iv, 1 9207142b30SJingu Kang br i1 %c, label %loop.header, label %exit 9307142b30SJingu Kang 9407142b30SJingu Kangexit: 9507142b30SJingu Kang ret i32 10 9607142b30SJingu Kang} 9707142b30SJingu Kang 9807142b30SJingu Kangdefine i32 @partial_unswtich_gep_load_icmp(i32** %ptr, i32 %N) { 9907142b30SJingu Kang; CHECK-LABEL: @partial_unswtich_gep_load_icmp( 10007142b30SJingu Kang; CHECK-NEXT: entry: 10107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 10207142b30SJingu Kang; CHECK: loop.header: 103*107d19ebSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 104*107d19ebSJingu Kang; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32*, i32** [[PTR:%.*]], i32 1 10507142b30SJingu Kang; CHECK-NEXT: [[LV_1:%.*]] = load i32*, i32** [[GEP]], align 8 10607142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[LV_1]], align 4 10707142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 10807142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 10907142b30SJingu Kang; CHECK: noclobber: 11007142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 11107142b30SJingu Kang; CHECK: clobber: 11207142b30SJingu Kang; CHECK-NEXT: call void @clobber() 11307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 11407142b30SJingu Kang; CHECK: loop.latch: 115*107d19ebSJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 11607142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 117*107d19ebSJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 11807142b30SJingu Kang; CHECK: exit: 11907142b30SJingu Kang; CHECK-NEXT: ret i32 10 12007142b30SJingu Kang; 12107142b30SJingu Kangentry: 12207142b30SJingu Kang br label %loop.header 12307142b30SJingu Kang 12407142b30SJingu Kangloop.header: 12507142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 12607142b30SJingu Kang %gep = getelementptr i32*, i32** %ptr, i32 1 12707142b30SJingu Kang %lv.1 = load i32*, i32** %gep 12807142b30SJingu Kang %lv = load i32, i32* %lv.1 12907142b30SJingu Kang %sc = icmp eq i32 %lv, 100 13007142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 13107142b30SJingu Kang 13207142b30SJingu Kangnoclobber: 13307142b30SJingu Kang br label %loop.latch 13407142b30SJingu Kang 13507142b30SJingu Kangclobber: 13607142b30SJingu Kang call void @clobber() 13707142b30SJingu Kang br label %loop.latch 13807142b30SJingu Kang 13907142b30SJingu Kangloop.latch: 14007142b30SJingu Kang %c = icmp ult i32 %iv, %N 14107142b30SJingu Kang %iv.next = add i32 %iv, 1 14207142b30SJingu Kang br i1 %c, label %loop.header, label %exit 14307142b30SJingu Kang 14407142b30SJingu Kangexit: 14507142b30SJingu Kang ret i32 10 14607142b30SJingu Kang} 14707142b30SJingu Kang 14807142b30SJingu Kangdefine i32 @partial_unswitch_reduction_phi(i32* %ptr, i32 %N) { 14907142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_reduction_phi( 15007142b30SJingu Kang; CHECK-NEXT: entry: 15107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 15207142b30SJingu Kang; CHECK: loop.header: 153*107d19ebSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 154*107d19ebSJingu Kang; CHECK-NEXT: [[RED:%.*]] = phi i32 [ 20, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP_LATCH]] ] 155*107d19ebSJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 15607142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 15707142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 15807142b30SJingu Kang; CHECK: clobber: 15907142b30SJingu Kang; CHECK-NEXT: call void @clobber() 16007142b30SJingu Kang; CHECK-NEXT: [[ADD_5:%.*]] = add i32 [[RED]], 5 16107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 16207142b30SJingu Kang; CHECK: noclobber: 16307142b30SJingu Kang; CHECK-NEXT: [[ADD_10:%.*]] = add i32 [[RED]], 10 16407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 16507142b30SJingu Kang; CHECK: loop.latch: 16607142b30SJingu Kang; CHECK-NEXT: [[RED_NEXT]] = phi i32 [ [[ADD_5]], [[CLOBBER]] ], [ [[ADD_10]], [[NOCLOBBER]] ] 167*107d19ebSJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 16807142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 169*107d19ebSJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 17088b259c0SJingu Kang; CHECK: exit: 171*107d19ebSJingu Kang; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ] 172*107d19ebSJingu Kang; CHECK-NEXT: ret i32 [[RED_NEXT_LCSSA]] 17307142b30SJingu Kang; 17407142b30SJingu Kangentry: 17507142b30SJingu Kang br label %loop.header 17607142b30SJingu Kang 17707142b30SJingu Kangloop.header: 17807142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 17907142b30SJingu Kang %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ] 18007142b30SJingu Kang %lv = load i32, i32* %ptr 18107142b30SJingu Kang %sc = icmp eq i32 %lv, 100 18207142b30SJingu Kang br i1 %sc, label %clobber, label %noclobber 18307142b30SJingu Kang 18407142b30SJingu Kangclobber: 18507142b30SJingu Kang call void @clobber() 18607142b30SJingu Kang %add.5 = add i32 %red, 5 18707142b30SJingu Kang br label %loop.latch 18807142b30SJingu Kang 18907142b30SJingu Kangnoclobber: 19007142b30SJingu Kang %add.10 = add i32 %red, 10 19107142b30SJingu Kang br label %loop.latch 19207142b30SJingu Kang 19307142b30SJingu Kangloop.latch: 19407142b30SJingu Kang %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ] 19507142b30SJingu Kang %c = icmp ult i32 %iv, %N 19607142b30SJingu Kang %iv.next = add i32 %iv, 1 19707142b30SJingu Kang br i1 %c, label %loop.header, label %exit 19807142b30SJingu Kang 19907142b30SJingu Kangexit: 20007142b30SJingu Kang %red.next.lcssa = phi i32 [ %red.next, %loop.latch ] 20107142b30SJingu Kang ret i32 %red.next.lcssa 20207142b30SJingu Kang} 20307142b30SJingu Kang 20407142b30SJingu Kang; Partial unswitching is possible, because the store in %noclobber does not 20507142b30SJingu Kang; alias the load of the condition. 20607142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_noclobber(i32* noalias %ptr.1, i32* noalias %ptr.2, i32 %N) { 20707142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_noclobber( 20807142b30SJingu Kang; CHECK-NEXT: entry: 20907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 21007142b30SJingu Kang; CHECK: loop.header: 211*107d19ebSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 212*107d19ebSJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4 21307142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 21407142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 21507142b30SJingu Kang; CHECK: noclobber: 216*107d19ebSJingu Kang; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV]] 21707142b30SJingu Kang; CHECK-NEXT: store i32 [[LV]], i32* [[GEP_1]], align 4 21807142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 21907142b30SJingu Kang; CHECK: clobber: 22007142b30SJingu Kang; CHECK-NEXT: call void @clobber() 22107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 22207142b30SJingu Kang; CHECK: loop.latch: 223*107d19ebSJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 22407142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 225*107d19ebSJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 22607142b30SJingu Kang; CHECK: exit: 22707142b30SJingu Kang; CHECK-NEXT: ret i32 10 22807142b30SJingu Kang; 22907142b30SJingu Kangentry: 23007142b30SJingu Kang br label %loop.header 23107142b30SJingu Kang 23207142b30SJingu Kangloop.header: 23307142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 23407142b30SJingu Kang %lv = load i32, i32* %ptr.1 23507142b30SJingu Kang %sc = icmp eq i32 %lv, 100 23607142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 23707142b30SJingu Kang 23807142b30SJingu Kangnoclobber: 23907142b30SJingu Kang %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv 24007142b30SJingu Kang store i32 %lv, i32* %gep.1 24107142b30SJingu Kang br label %loop.latch 24207142b30SJingu Kang 24307142b30SJingu Kangclobber: 24407142b30SJingu Kang call void @clobber() 24507142b30SJingu Kang br label %loop.latch 24607142b30SJingu Kang 24707142b30SJingu Kangloop.latch: 24807142b30SJingu Kang %c = icmp ult i32 %iv, %N 24907142b30SJingu Kang %iv.next = add i32 %iv, 1 25007142b30SJingu Kang br i1 %c, label %loop.header, label %exit 25107142b30SJingu Kang 25207142b30SJingu Kangexit: 25307142b30SJingu Kang ret i32 10 25407142b30SJingu Kang} 25507142b30SJingu Kang 25607142b30SJingu Kangdefine void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) { 25707142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_phi_cond( 25807142b30SJingu Kang; CHECK-NEXT: entry: 25907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 26007142b30SJingu Kang; CHECK: loop.header: 26107142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 26207142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = phi i1 [ [[LC:%.*]], [[ENTRY]] ], [ true, [[LOOP_LATCH]] ] 26307142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]] 26407142b30SJingu Kang; CHECK: clobber: 26507142b30SJingu Kang; CHECK-NEXT: call void @clobber() 26607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 26707142b30SJingu Kang; CHECK: noclobber: 26807142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 26907142b30SJingu Kang; CHECK: loop.latch: 27007142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 27107142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 27207142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 27307142b30SJingu Kang; CHECK: exit: 27407142b30SJingu Kang; CHECK-NEXT: ret void 27507142b30SJingu Kang; 27607142b30SJingu Kangentry: 27707142b30SJingu Kang br label %loop.header 27807142b30SJingu Kang 27907142b30SJingu Kangloop.header: 28007142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 28107142b30SJingu Kang %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ] 28207142b30SJingu Kang br i1 %sc, label %clobber, label %noclobber 28307142b30SJingu Kang 28407142b30SJingu Kangclobber: 28507142b30SJingu Kang call void @clobber() 28607142b30SJingu Kang br label %loop.latch 28707142b30SJingu Kang 28807142b30SJingu Kangnoclobber: 28907142b30SJingu Kang br label %loop.latch 29007142b30SJingu Kang 29107142b30SJingu Kangloop.latch: 29207142b30SJingu Kang %c = icmp ult i32 %iv, %N 29307142b30SJingu Kang %iv.next = add i32 %iv, 1 29407142b30SJingu Kang br i1 %c, label %loop.header, label %exit 29507142b30SJingu Kang 29607142b30SJingu Kangexit: 29707142b30SJingu Kang ret void 29807142b30SJingu Kang} 29907142b30SJingu Kang 30007142b30SJingu Kangdefine void @no_partial_unswitch_clobber_latch(i32* %ptr, i32 %N) { 30107142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_latch( 30207142b30SJingu Kang; CHECK-NEXT: entry: 30307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 30407142b30SJingu Kang; CHECK: loop.header: 30507142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 30607142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 30707142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 30807142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 30907142b30SJingu Kang; CHECK: noclobber: 31007142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 31107142b30SJingu Kang; CHECK: clobber: 31207142b30SJingu Kang; CHECK-NEXT: call void @clobber() 31307142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 31407142b30SJingu Kang; CHECK: loop.latch: 31507142b30SJingu Kang; CHECK-NEXT: call void @clobber() 31607142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 31707142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 31807142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 31907142b30SJingu Kang; CHECK: exit: 32007142b30SJingu Kang; CHECK-NEXT: ret void 32107142b30SJingu Kang; 32207142b30SJingu Kangentry: 32307142b30SJingu Kang br label %loop.header 32407142b30SJingu Kang 32507142b30SJingu Kangloop.header: 32607142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 32707142b30SJingu Kang %lv = load i32, i32* %ptr 32807142b30SJingu Kang %sc = icmp eq i32 %lv, 100 32907142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 33007142b30SJingu Kang 33107142b30SJingu Kangnoclobber: 33207142b30SJingu Kang br label %loop.latch 33307142b30SJingu Kang 33407142b30SJingu Kangclobber: 33507142b30SJingu Kang call void @clobber() 33607142b30SJingu Kang br label %loop.latch 33707142b30SJingu Kang 33807142b30SJingu Kangloop.latch: 33907142b30SJingu Kang call void @clobber() 34007142b30SJingu Kang %c = icmp ult i32 %iv, %N 34107142b30SJingu Kang %iv.next = add i32 %iv, 1 34207142b30SJingu Kang br i1 %c, label %loop.header, label %exit 34307142b30SJingu Kang 34407142b30SJingu Kangexit: 34507142b30SJingu Kang ret void 34607142b30SJingu Kang} 34707142b30SJingu Kang 34807142b30SJingu Kangdefine void @no_partial_unswitch_clobber_header(i32* %ptr, i32 %N) { 34907142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_header( 35007142b30SJingu Kang; CHECK-NEXT: entry: 35107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 35207142b30SJingu Kang; CHECK: loop.header: 35307142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 35407142b30SJingu Kang; CHECK-NEXT: call void @clobber() 35507142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 35607142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 35707142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 35807142b30SJingu Kang; CHECK: noclobber: 35907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 36007142b30SJingu Kang; CHECK: clobber: 36107142b30SJingu Kang; CHECK-NEXT: call void @clobber() 36207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 36307142b30SJingu Kang; CHECK: loop.latch: 36407142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 36507142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 36607142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 36707142b30SJingu Kang; CHECK: exit: 36807142b30SJingu Kang; CHECK-NEXT: ret void 36907142b30SJingu Kang; 37007142b30SJingu Kangentry: 37107142b30SJingu Kang br label %loop.header 37207142b30SJingu Kang 37307142b30SJingu Kangloop.header: 37407142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 37507142b30SJingu Kang call void @clobber() 37607142b30SJingu Kang %lv = load i32, i32* %ptr 37707142b30SJingu Kang %sc = icmp eq i32 %lv, 100 37807142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 37907142b30SJingu Kang 38007142b30SJingu Kangnoclobber: 38107142b30SJingu Kang br label %loop.latch 38207142b30SJingu Kang 38307142b30SJingu Kangclobber: 38407142b30SJingu Kang call void @clobber() 38507142b30SJingu Kang br label %loop.latch 38607142b30SJingu Kang 38707142b30SJingu Kangloop.latch: 38807142b30SJingu Kang %c = icmp ult i32 %iv, %N 38907142b30SJingu Kang %iv.next = add i32 %iv, 1 39007142b30SJingu Kang br i1 %c, label %loop.header, label %exit 39107142b30SJingu Kang 39207142b30SJingu Kangexit: 39307142b30SJingu Kang ret void 39407142b30SJingu Kang} 39507142b30SJingu Kang 39607142b30SJingu Kangdefine void @no_partial_unswitch_clobber_both(i32* %ptr, i32 %N) { 39707142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_clobber_both( 39807142b30SJingu Kang; CHECK-NEXT: entry: 39907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 40007142b30SJingu Kang; CHECK: loop.header: 40107142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 40207142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 40307142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 40407142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 40507142b30SJingu Kang; CHECK: noclobber: 40607142b30SJingu Kang; CHECK-NEXT: call void @clobber() 40707142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 40807142b30SJingu Kang; CHECK: clobber: 40907142b30SJingu Kang; CHECK-NEXT: call void @clobber() 41007142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 41107142b30SJingu Kang; CHECK: loop.latch: 41207142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 41307142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 41407142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 41507142b30SJingu Kang; CHECK: exit: 41607142b30SJingu Kang; CHECK-NEXT: ret void 41707142b30SJingu Kang; 41807142b30SJingu Kangentry: 41907142b30SJingu Kang br label %loop.header 42007142b30SJingu Kang 42107142b30SJingu Kangloop.header: 42207142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 42307142b30SJingu Kang %lv = load i32, i32* %ptr 42407142b30SJingu Kang %sc = icmp eq i32 %lv, 100 42507142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 42607142b30SJingu Kang 42707142b30SJingu Kangnoclobber: 42807142b30SJingu Kang call void @clobber() 42907142b30SJingu Kang br label %loop.latch 43007142b30SJingu Kang 43107142b30SJingu Kangclobber: 43207142b30SJingu Kang call void @clobber() 43307142b30SJingu Kang br label %loop.latch 43407142b30SJingu Kang 43507142b30SJingu Kangloop.latch: 43607142b30SJingu Kang %c = icmp ult i32 %iv, %N 43707142b30SJingu Kang %iv.next = add i32 %iv, 1 43807142b30SJingu Kang br i1 %c, label %loop.header, label %exit 43907142b30SJingu Kang 44007142b30SJingu Kangexit: 44107142b30SJingu Kang ret void 44207142b30SJingu Kang} 44307142b30SJingu Kang 44407142b30SJingu Kangdefine i32 @no_partial_unswitch_true_successor_storeclobber(i32* %ptr.1, i32* %ptr.2, i32 %N) { 44507142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber( 44607142b30SJingu Kang; CHECK-NEXT: entry: 44707142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 44807142b30SJingu Kang; CHECK: loop.header: 44907142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 45007142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR_1:%.*]], align 4 45107142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 45207142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 45307142b30SJingu Kang; CHECK: noclobber: 45407142b30SJingu Kang; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, i32* [[PTR_2:%.*]], i32 [[IV]] 45507142b30SJingu Kang; CHECK-NEXT: store i32 [[LV]], i32* [[GEP_1]], align 4 45607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 45707142b30SJingu Kang; CHECK: clobber: 45807142b30SJingu Kang; CHECK-NEXT: call void @clobber() 45907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 46007142b30SJingu Kang; CHECK: loop.latch: 46107142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 46207142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 46307142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 46407142b30SJingu Kang; CHECK: exit: 46507142b30SJingu Kang; CHECK-NEXT: ret i32 10 46607142b30SJingu Kang; 46707142b30SJingu Kangentry: 46807142b30SJingu Kang br label %loop.header 46907142b30SJingu Kang 47007142b30SJingu Kangloop.header: 47107142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 47207142b30SJingu Kang %lv = load i32, i32* %ptr.1 47307142b30SJingu Kang %sc = icmp eq i32 %lv, 100 47407142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 47507142b30SJingu Kang 47607142b30SJingu Kangnoclobber: 47707142b30SJingu Kang %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv 47807142b30SJingu Kang store i32 %lv, i32* %gep.1 47907142b30SJingu Kang br label %loop.latch 48007142b30SJingu Kang 48107142b30SJingu Kangclobber: 48207142b30SJingu Kang call void @clobber() 48307142b30SJingu Kang br label %loop.latch 48407142b30SJingu Kang 48507142b30SJingu Kangloop.latch: 48607142b30SJingu Kang %c = icmp ult i32 %iv, %N 48707142b30SJingu Kang %iv.next = add i32 %iv, 1 48807142b30SJingu Kang br i1 %c, label %loop.header, label %exit 48907142b30SJingu Kang 49007142b30SJingu Kangexit: 49107142b30SJingu Kang ret i32 10 49207142b30SJingu Kang} 49307142b30SJingu Kang 49407142b30SJingu Kang; Make sure the duplicated instructions are moved to a preheader that always 49507142b30SJingu Kang; executes when the loop body also executes. Do not check the unswitched code, 49607142b30SJingu Kang; because it is already checked in the @partial_unswitch_true_successor test 49707142b30SJingu Kang; case. 49807142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_preheader_insertion(i32* %ptr, i32 %N) { 49907142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion( 50007142b30SJingu Kang; CHECK-NEXT: entry: 50107142b30SJingu Kang; CHECK-NEXT: [[EC:%.*]] = icmp ne i32* [[PTR:%.*]], null 50207142b30SJingu Kang; CHECK-NEXT: br i1 [[EC]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]] 50307142b30SJingu Kang; CHECK: loop.ph: 50407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 50507142b30SJingu Kang; CHECK: loop.header: 506*107d19ebSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[LOOP_PH]] ], [ [[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: br label [[LOOP_LATCH]] 51207142b30SJingu Kang; CHECK: clobber: 51307142b30SJingu Kang; CHECK-NEXT: call void @clobber() 51407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 51507142b30SJingu Kang; CHECK: loop.latch: 516*107d19ebSJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 51707142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 518*107d19ebSJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT:%.*]] 51907142b30SJingu Kang; CHECK: exit.loopexit: 52007142b30SJingu Kang; CHECK-NEXT: br label [[EXIT]] 52107142b30SJingu Kang; CHECK: exit: 52207142b30SJingu Kang; CHECK-NEXT: ret i32 10 52307142b30SJingu Kang; 52407142b30SJingu Kang 52507142b30SJingu Kangentry: 52607142b30SJingu Kang %ec = icmp ne i32* %ptr, null 52707142b30SJingu Kang br i1 %ec, label %loop.ph, label %exit 52807142b30SJingu Kang 52907142b30SJingu Kangloop.ph: 53007142b30SJingu Kang br label %loop.header 53107142b30SJingu Kang 53207142b30SJingu Kangloop.header: 53307142b30SJingu Kang %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ] 53407142b30SJingu Kang %lv = load i32, i32* %ptr 53507142b30SJingu Kang %sc = icmp eq i32 %lv, 100 53607142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 53707142b30SJingu Kang 53807142b30SJingu Kangnoclobber: 53907142b30SJingu Kang br label %loop.latch 54007142b30SJingu Kang 54107142b30SJingu Kangclobber: 54207142b30SJingu Kang call void @clobber() 54307142b30SJingu Kang br label %loop.latch 54407142b30SJingu Kang 54507142b30SJingu Kangloop.latch: 54607142b30SJingu Kang %c = icmp ult i32 %iv, %N 54707142b30SJingu Kang %iv.next = add i32 %iv, 1 54807142b30SJingu Kang br i1 %c, label %loop.header, label %exit 54907142b30SJingu Kang 55007142b30SJingu Kangexit: 55107142b30SJingu Kang ret i32 10 55207142b30SJingu Kang} 55307142b30SJingu Kang 55407142b30SJingu Kang; Make sure the duplicated instructions are hoisted just before the branch of 55507142b30SJingu Kang; the preheader. Do not check the unswitched code, because it is already checked 55607142b30SJingu Kang; in the @partial_unswitch_true_successor test case 55707142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_insert_point(i32* %ptr, i32 %N) { 55807142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_insert_point( 55907142b30SJingu Kang; CHECK-NEXT: entry: 56007142b30SJingu Kang; CHECK-NEXT: call void @clobber() 56107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 56207142b30SJingu Kang; CHECK: loop.header: 563*107d19ebSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 564*107d19ebSJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 56507142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 56607142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 56707142b30SJingu Kang; CHECK: noclobber: 56807142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 56907142b30SJingu Kang; CHECK: clobber: 57007142b30SJingu Kang; CHECK-NEXT: call void @clobber() 57107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 57207142b30SJingu Kang; CHECK: loop.latch: 573*107d19ebSJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 57407142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 575*107d19ebSJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 57607142b30SJingu Kang; CHECK: exit: 57707142b30SJingu Kang; CHECK-NEXT: ret i32 10 57807142b30SJingu Kang; 57907142b30SJingu Kangentry: 58007142b30SJingu Kang call void @clobber() 58107142b30SJingu Kang br label %loop.header 58207142b30SJingu Kang 58307142b30SJingu Kangloop.header: 58407142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 58507142b30SJingu Kang %lv = load i32, i32* %ptr 58607142b30SJingu Kang %sc = icmp eq i32 %lv, 100 58707142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 58807142b30SJingu Kang 58907142b30SJingu Kangnoclobber: 59007142b30SJingu Kang br label %loop.latch 59107142b30SJingu Kang 59207142b30SJingu Kangclobber: 59307142b30SJingu Kang call void @clobber() 59407142b30SJingu Kang br label %loop.latch 59507142b30SJingu Kang 59607142b30SJingu Kangloop.latch: 59707142b30SJingu Kang %c = icmp ult i32 %iv, %N 59807142b30SJingu Kang %iv.next = add i32 %iv, 1 59907142b30SJingu Kang br i1 %c, label %loop.header, label %exit 60007142b30SJingu Kang 60107142b30SJingu Kangexit: 60207142b30SJingu Kang ret i32 10 60307142b30SJingu Kang} 60407142b30SJingu Kang 60507142b30SJingu Kang; Make sure invariant instructions in the loop are also hoisted to the preheader. 60607142b30SJingu Kang; Do not check the unswitched code, because it is already checked in the 60707142b30SJingu Kang; @partial_unswitch_true_successor test case 60807142b30SJingu Kangdefine i32 @partial_unswitch_true_successor_hoist_invariant(i32* %ptr, i32 %N) { 60907142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant( 61007142b30SJingu Kang; CHECK-NEXT: entry: 61107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 61207142b30SJingu Kang; CHECK: loop.header: 613*107d19ebSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 614*107d19ebSJingu Kang; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 1 61507142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[GEP]], align 4 61607142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 61707142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 61807142b30SJingu Kang; CHECK: noclobber: 61907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 62007142b30SJingu Kang; CHECK: clobber: 62107142b30SJingu Kang; CHECK-NEXT: call void @clobber() 62207142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 62307142b30SJingu Kang; CHECK: loop.latch: 624*107d19ebSJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 62507142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 626*107d19ebSJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 62707142b30SJingu Kang; CHECK: exit: 62807142b30SJingu Kang; CHECK-NEXT: ret i32 10 62907142b30SJingu Kang; 63007142b30SJingu Kangentry: 63107142b30SJingu Kang br label %loop.header 63207142b30SJingu Kang 63307142b30SJingu Kangloop.header: 63407142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 63507142b30SJingu Kang %gep = getelementptr i32, i32* %ptr, i64 1 63607142b30SJingu Kang %lv = load i32, i32* %gep 63707142b30SJingu Kang %sc = icmp eq i32 %lv, 100 63807142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 63907142b30SJingu Kang 64007142b30SJingu Kangnoclobber: 64107142b30SJingu Kang br label %loop.latch 64207142b30SJingu Kang 64307142b30SJingu Kangclobber: 64407142b30SJingu Kang call void @clobber() 64507142b30SJingu Kang br label %loop.latch 64607142b30SJingu Kang 64707142b30SJingu Kangloop.latch: 64807142b30SJingu Kang %c = icmp ult i32 %iv, %N 64907142b30SJingu Kang %iv.next = add i32 %iv, 1 65007142b30SJingu Kang br i1 %c, label %loop.header, label %exit 65107142b30SJingu Kang 65207142b30SJingu Kangexit: 65307142b30SJingu Kang ret i32 10 65407142b30SJingu Kang} 65507142b30SJingu Kang 65607142b30SJingu Kang; Do not unswitch if the condition depends on an atomic load. Duplicating such 65707142b30SJingu Kang; loads is not safe. 65807142b30SJingu Kangdefine i32 @no_partial_unswitch_atomic_load_unordered(i32* %ptr, i32 %N) { 65907142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered( 66007142b30SJingu Kang; CHECK-NEXT: entry: 66107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 66207142b30SJingu Kang; CHECK: loop.header: 66307142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 66407142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] unordered, align 4 66507142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 66607142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 66707142b30SJingu Kang; CHECK: noclobber: 66807142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 66907142b30SJingu Kang; CHECK: clobber: 67007142b30SJingu Kang; CHECK-NEXT: call void @clobber() 67107142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 67207142b30SJingu Kang; CHECK: loop.latch: 67307142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 67407142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 67507142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 67607142b30SJingu Kang; CHECK: exit: 67707142b30SJingu Kang; CHECK-NEXT: ret i32 10 67807142b30SJingu Kang; 67907142b30SJingu Kangentry: 68007142b30SJingu Kang br label %loop.header 68107142b30SJingu Kang 68207142b30SJingu Kangloop.header: 68307142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 68407142b30SJingu Kang %lv = load atomic i32, i32* %ptr unordered, align 4 68507142b30SJingu Kang %sc = icmp eq i32 %lv, 100 68607142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 68707142b30SJingu Kang 68807142b30SJingu Kangnoclobber: 68907142b30SJingu Kang br label %loop.latch 69007142b30SJingu Kang 69107142b30SJingu Kangclobber: 69207142b30SJingu Kang call void @clobber() 69307142b30SJingu Kang br label %loop.latch 69407142b30SJingu Kang 69507142b30SJingu Kangloop.latch: 69607142b30SJingu Kang %c = icmp ult i32 %iv, %N 69707142b30SJingu Kang %iv.next = add i32 %iv, 1 69807142b30SJingu Kang br i1 %c, label %loop.header, label %exit 69907142b30SJingu Kang 70007142b30SJingu Kangexit: 70107142b30SJingu Kang ret i32 10 70207142b30SJingu Kang} 70307142b30SJingu Kang 70407142b30SJingu Kang; Do not unswitch if the condition depends on an atomic load. Duplicating such 70507142b30SJingu Kang; loads is not safe. 70607142b30SJingu Kangdefine i32 @no_partial_unswitch_atomic_load_monotonic(i32* %ptr, i32 %N) { 70707142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic( 70807142b30SJingu Kang; CHECK-NEXT: entry: 70907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 71007142b30SJingu Kang; CHECK: loop.header: 71107142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 71207142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load atomic i32, i32* [[PTR:%.*]] monotonic, align 4 71307142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 71407142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 71507142b30SJingu Kang; CHECK: noclobber: 71607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 71707142b30SJingu Kang; CHECK: clobber: 71807142b30SJingu Kang; CHECK-NEXT: call void @clobber() 71907142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 72007142b30SJingu Kang; CHECK: loop.latch: 72107142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 72207142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 72307142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 72407142b30SJingu Kang; CHECK: exit: 72507142b30SJingu Kang; CHECK-NEXT: ret i32 10 72607142b30SJingu Kang; 72707142b30SJingu Kangentry: 72807142b30SJingu Kang br label %loop.header 72907142b30SJingu Kang 73007142b30SJingu Kangloop.header: 73107142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 73207142b30SJingu Kang %lv = load atomic i32, i32* %ptr monotonic, align 4 73307142b30SJingu Kang %sc = icmp eq i32 %lv, 100 73407142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 73507142b30SJingu Kang 73607142b30SJingu Kangnoclobber: 73707142b30SJingu Kang br label %loop.latch 73807142b30SJingu Kang 73907142b30SJingu Kangclobber: 74007142b30SJingu Kang call void @clobber() 74107142b30SJingu Kang br label %loop.latch 74207142b30SJingu Kang 74307142b30SJingu Kangloop.latch: 74407142b30SJingu Kang %c = icmp ult i32 %iv, %N 74507142b30SJingu Kang %iv.next = add i32 %iv, 1 74607142b30SJingu Kang br i1 %c, label %loop.header, label %exit 74707142b30SJingu Kang 74807142b30SJingu Kangexit: 74907142b30SJingu Kang ret i32 10 75007142b30SJingu Kang} 75107142b30SJingu Kang 75207142b30SJingu Kang 75307142b30SJingu Kangdeclare i32 @get_value() 75407142b30SJingu Kang 75507142b30SJingu Kang; Do not unswitch if the condition depends on a call, that may clobber memory. 75607142b30SJingu Kang; Duplicating such a call is not safe. 75707142b30SJingu Kangdefine i32 @no_partial_unswitch_cond_call(i32* %ptr, i32 %N) { 75807142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_cond_call( 75907142b30SJingu Kang; CHECK-NEXT: entry: 76007142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 76107142b30SJingu Kang; CHECK: loop.header: 76207142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 76307142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = call i32 @get_value() 76407142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 76507142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] 76607142b30SJingu Kang; CHECK: noclobber: 76707142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 76807142b30SJingu Kang; CHECK: clobber: 76907142b30SJingu Kang; CHECK-NEXT: call void @clobber() 77007142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 77107142b30SJingu Kang; CHECK: loop.latch: 77207142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 77307142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 77407142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 77507142b30SJingu Kang; CHECK: exit: 77607142b30SJingu Kang; CHECK-NEXT: ret i32 10 77707142b30SJingu Kang; 77807142b30SJingu Kangentry: 77907142b30SJingu Kang br label %loop.header 78007142b30SJingu Kang 78107142b30SJingu Kangloop.header: 78207142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 78307142b30SJingu Kang %lv = call i32 @get_value() 78407142b30SJingu Kang %sc = icmp eq i32 %lv, 100 78507142b30SJingu Kang br i1 %sc, label %noclobber, label %clobber 78607142b30SJingu Kang 78707142b30SJingu Kangnoclobber: 78807142b30SJingu Kang br label %loop.latch 78907142b30SJingu Kang 79007142b30SJingu Kangclobber: 79107142b30SJingu Kang call void @clobber() 79207142b30SJingu Kang br label %loop.latch 79307142b30SJingu Kang 79407142b30SJingu Kangloop.latch: 79507142b30SJingu Kang %c = icmp ult i32 %iv, %N 79607142b30SJingu Kang %iv.next = add i32 %iv, 1 79707142b30SJingu Kang br i1 %c, label %loop.header, label %exit 79807142b30SJingu Kang 79907142b30SJingu Kangexit: 80007142b30SJingu Kang ret i32 10 80107142b30SJingu Kang} 80207142b30SJingu Kang 80307142b30SJingu Kangdefine i32 @no_partial_unswitch_true_successor_exit(i32* %ptr, i32 %N) { 80407142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_successor_exit( 80507142b30SJingu Kang; CHECK-NEXT: entry: 80607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 80707142b30SJingu Kang; CHECK: loop.header: 80807142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 80907142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 81007142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 81107142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[EXIT:%.*]], label [[CLOBBER:%.*]] 81207142b30SJingu Kang; CHECK: clobber: 81307142b30SJingu Kang; CHECK-NEXT: call void @clobber() 81407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 81507142b30SJingu Kang; CHECK: loop.latch: 81607142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 81707142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 81807142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT]] 81907142b30SJingu Kang; CHECK: exit: 82007142b30SJingu Kang; CHECK-NEXT: ret i32 10 82107142b30SJingu Kang; 82207142b30SJingu Kangentry: 82307142b30SJingu Kang br label %loop.header 82407142b30SJingu Kang 82507142b30SJingu Kangloop.header: 82607142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 82707142b30SJingu Kang %lv = load i32, i32* %ptr 82807142b30SJingu Kang %sc = icmp eq i32 %lv, 100 82907142b30SJingu Kang br i1 %sc, label %exit, label %clobber 83007142b30SJingu Kang 83107142b30SJingu Kangclobber: 83207142b30SJingu Kang call void @clobber() 83307142b30SJingu Kang br label %loop.latch 83407142b30SJingu Kang 83507142b30SJingu Kangloop.latch: 83607142b30SJingu Kang %c = icmp ult i32 %iv, %N 83707142b30SJingu Kang %iv.next = add i32 %iv, 1 83807142b30SJingu Kang br i1 %c, label %loop.header, label %exit 83907142b30SJingu Kang 84007142b30SJingu Kangexit: 84107142b30SJingu Kang ret i32 10 84207142b30SJingu Kang} 84307142b30SJingu Kang 84407142b30SJingu Kangdefine i32 @no_partial_unswitch_true_same_successor(i32* %ptr, i32 %N) { 84507142b30SJingu Kang; CHECK-LABEL: @no_partial_unswitch_true_same_successor( 84607142b30SJingu Kang; CHECK-NEXT: entry: 84707142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 84807142b30SJingu Kang; CHECK: loop.header: 84907142b30SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 85007142b30SJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 85107142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 85207142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[NOCLOBBER]] 85307142b30SJingu Kang; CHECK: noclobber: 85407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 85507142b30SJingu Kang; CHECK: loop.latch: 85607142b30SJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 85707142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 85807142b30SJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 85907142b30SJingu Kang; CHECK: exit: 86007142b30SJingu Kang; CHECK-NEXT: ret i32 10 86107142b30SJingu Kang; 86207142b30SJingu Kangentry: 86307142b30SJingu Kang br label %loop.header 86407142b30SJingu Kang 86507142b30SJingu Kangloop.header: 86607142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 86707142b30SJingu Kang %lv = load i32, i32* %ptr 86807142b30SJingu Kang %sc = icmp eq i32 %lv, 100 86907142b30SJingu Kang br i1 %sc, label %noclobber, label %noclobber 87007142b30SJingu Kang 87107142b30SJingu Kangnoclobber: 87207142b30SJingu Kang br label %loop.latch 87307142b30SJingu Kang 87407142b30SJingu Kangloop.latch: 87507142b30SJingu Kang %c = icmp ult i32 %iv, %N 87607142b30SJingu Kang %iv.next = add i32 %iv, 1 87707142b30SJingu Kang br i1 %c, label %loop.header, label %exit 87807142b30SJingu Kang 87907142b30SJingu Kangexit: 88007142b30SJingu Kang ret i32 10 88107142b30SJingu Kang} 88207142b30SJingu Kang 88307142b30SJingu Kangdefine i32 @partial_unswitch_true_to_latch(i32* %ptr, i32 %N) { 88407142b30SJingu Kang; CHECK-LABEL: @partial_unswitch_true_to_latch( 88507142b30SJingu Kang; CHECK-NEXT: entry: 88607142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 88707142b30SJingu Kang; CHECK: loop.header: 888*107d19ebSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 889*107d19ebSJingu Kang; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR:%.*]], align 4 89007142b30SJingu Kang; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 89107142b30SJingu Kang; CHECK-NEXT: br i1 [[SC]], label [[LOOP_LATCH]], label [[CLOBBER:%.*]] 89207142b30SJingu Kang; CHECK: clobber: 89307142b30SJingu Kang; CHECK-NEXT: call void @clobber() 89407142b30SJingu Kang; CHECK-NEXT: br label [[LOOP_LATCH]] 89507142b30SJingu Kang; CHECK: loop.latch: 896*107d19ebSJingu Kang; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 89707142b30SJingu Kang; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 898*107d19ebSJingu Kang; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 89907142b30SJingu Kang; CHECK: exit: 90007142b30SJingu Kang; CHECK-NEXT: ret i32 10 90107142b30SJingu Kang; 90207142b30SJingu Kangentry: 90307142b30SJingu Kang br label %loop.header 90407142b30SJingu Kang 90507142b30SJingu Kangloop.header: 90607142b30SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 90707142b30SJingu Kang %lv = load i32, i32* %ptr 90807142b30SJingu Kang %sc = icmp eq i32 %lv, 100 90907142b30SJingu Kang br i1 %sc, label %loop.latch, label %clobber 91007142b30SJingu Kang 91107142b30SJingu Kangclobber: 91207142b30SJingu Kang call void @clobber() 91307142b30SJingu Kang br label %loop.latch 91407142b30SJingu Kang 91507142b30SJingu Kangloop.latch: 91607142b30SJingu Kang %c = icmp ult i32 %iv, %N 91707142b30SJingu Kang %iv.next = add i32 %iv, 1 91807142b30SJingu Kang br i1 %c, label %loop.header, label %exit 91907142b30SJingu Kang 92007142b30SJingu Kangexit: 92107142b30SJingu Kang ret i32 10 92207142b30SJingu Kang} 923