xref: /llvm-project/llvm/test/Transforms/LoopFusion/guarded_unsafeblock_peel.ll (revision 055fb7795aa219a3d274d280ec9129784f169f56)
1; RUN: opt -S -passes=loop-fusion -loop-fusion-peel-max-count=3 < %s | FileCheck %s
2
3; Tests that we do not fuse two guarded loops together.
4; These loops do not have the same trip count, and the first loop meets the
5; requirements for peeling. However, the exit block of the first loop makes the
6; loops unsafe to fuse together.
7; The expected output of this test is the function as below.
8
9; CHECK-LABEL: void @unsafe_exitblock(ptr noalias %A, ptr noalias %B)
10; CHECK:       for.first.guard
11; CHECK:         br i1 %cmp3, label %for.first.preheader, label %for.second.guard
12; CHECK:       for.first.preheader:
13; CHECK-NEXT:    br label %for.first
14; CHECK:       for.first:
15; CHECK:         br i1 %cmp, label %for.first, label %for.first.exit
16; CHECK:       for.first.exit:
17; CHECK-NEXT:    call void @bar()
18; CHECK-NEXT:    br label %for.second.guard
19; CHECK:       for.second.guard:
20; CHECK:         br i1 %cmp21, label %for.second.preheader, label %for.end
21; CHECK:       for.second.preheader:
22; CHECK-NEXT:    br label %for.second
23; CHECK:       for.second:
24; CHECK:         br i1 %cmp2, label %for.second, label %for.second.exit
25; CHECK:       for.second.exit:
26; CHECK-NEXT:    br label %for.end
27; CHECK:       for.end:
28; CHECK-NEXT:    ret void
29
30define void @unsafe_exitblock(ptr noalias %A, ptr noalias %B) {
31for.first.guard:
32  %cmp3 = icmp slt i64 0, 45
33  br i1 %cmp3, label %for.first.preheader, label %for.second.guard
34
35for.first.preheader:                             ; preds = %for.first.guard
36  br label %for.first
37
38for.first:                                       ; preds = %for.first.preheader, %for.first
39  %i.04 = phi i64 [ %inc, %for.first ], [ 0, %for.first.preheader ]
40  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %i.04
41  store i32 0, ptr %arrayidx, align 4
42  %inc = add nsw i64 %i.04, 1
43  %cmp = icmp slt i64 %inc, 45
44  br i1 %cmp, label %for.first, label %for.first.exit
45
46for.first.exit:                                  ; preds = %for.first
47  call void @bar()
48  br label %for.second.guard
49
50for.second.guard:                                ; preds = %for.first.exit, %for.first.guard
51  %cmp21 = icmp slt i64 2,45
52  br i1 %cmp21, label %for.second.preheader, label %for.end
53
54for.second.preheader:                            ; preds = %for.second.guard
55  br label %for.second
56
57for.second:                                      ; preds = %for.second.preheader, %for.second
58  %j.02 = phi i64 [ %inc6, %for.second ], [ 2, %for.second.preheader ]
59  %arrayidx4 = getelementptr inbounds i32, ptr %B, i64 %j.02
60  store i32 0, ptr %arrayidx4, align 4
61  %inc6 = add nsw i64 %j.02, 1
62  %cmp2 = icmp slt i64 %inc6, 45
63  br i1 %cmp2, label %for.second, label %for.second.exit
64
65for.second.exit:                                 ; preds = %for.second
66  br label %for.end
67
68for.end:                                         ; preds = %for.second.exit, %for.second.guard
69  ret void
70}
71
72declare void @bar()
73