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