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*ab728717SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
12*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
2207142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
23*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
58*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
6807142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
69*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
104*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
11607142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
117*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
154*ab728717SJingu Kang; CHECK-NEXT:    [[RED:%.*]] = phi i32 [ 20, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP_LATCH]] ]
155*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
16807142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
169*ab728717SJingu Kang; CHECK-NEXT:    br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
17007142b30SJingu Kang; CHECK:       exit:
171*ab728717SJingu Kang; CHECK-NEXT:    [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ]
172*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
212*ab728717SJingu 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*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
22407142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
225*ab728717SJingu 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*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
51707142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
518*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
564*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
57407142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
575*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
614*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
62507142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
626*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
889*ab728717SJingu 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*ab728717SJingu Kang; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
89707142b30SJingu Kang; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
898*ab728717SJingu 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