• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -loop-unroll -indvars -disable-output
2
3@b = external global i32, align 4
4
5; Test that LoopUnroll does not break LCSSA form.
6;
7; In this function we have a following CFG:
8;            ( entry )
9;                |
10;                v
11;         ( outer.header ) <--
12;                |             \
13;                v              |
14;     --> ( inner.header )      |
15;   /       /          \        |
16;   \      /            \       |
17;    \    v              v     /
18;  ( inner.latch )   ( outer.latch )
19;         |
20;         v
21;     ( exit )
22;
23; When the inner loop is unrolled, we inner.latch block has only one
24; predecessor and one successor, so it can be merged with exit block.
25; During the merge, however, we remove an LCSSA definition for
26; %storemerge1.lcssa, breaking LCSSA form for the outer loop.
27
28; Function Attrs: nounwind uwtable
29define void @fn1() #0 {
30entry:
31  br label %outer.header
32
33outer.header:                                     ; preds = %outer.latch, %entry
34  %storemerge1 = phi i32 [ 0, %entry ], [ %inc9, %outer.latch ]
35  br label %inner.header
36
37inner.header:                                     ; preds = %inner.latch, %outer.header
38  %storemerge = phi i32 [ %add, %inner.latch ], [ 0, %outer.header ]
39  %cmp = icmp slt i32 %storemerge, 1
40  br i1 %cmp, label %inner.latch, label %outer.latch
41
42inner.latch:                                      ; preds = %inner.header
43  %tobool4 = icmp eq i32 %storemerge, 0
44  %add = add nsw i32 %storemerge, 1
45  br i1 %tobool4, label %inner.header, label %exit
46
47exit:                                             ; preds = %inner.latch
48  %storemerge1.lcssa = phi i32 [ %storemerge1, %inner.latch ]
49  store i32 %storemerge1.lcssa, i32* @b, align 4
50  ret void
51
52outer.latch:                                      ; preds = %inner.header
53  %inc9 = add nsw i32 %storemerge1, 1
54  br label %outer.header
55}
56
57; This case is similar to the previous one, and has the same CFG.
58; The difference is that loop unrolling doesn't remove any LCSSA definition,
59; yet breaks LCSSA form for the outer loop. It happens because before unrolling
60; block inner.latch was inside outer loop (and consequently, didn't require
61; LCSSA definition for %x), but after unrolling it occurs out of the outer
62; loop, so we need to insert an LCSSA definition to keep LCSSA.
63
64; Function Attrs: nounwind uwtable
65define void @fn2() {
66entry:
67  br label %outer.header
68
69outer.header:
70  br label %inner.header
71
72inner.header:
73  %x = load i32, i32* undef, align 4
74  br i1 true, label %outer.latch, label %inner.latch
75
76inner.latch:
77  %inc6 = add nsw i32 %x, 1
78  store i32 %inc6, i32* undef, align 4
79  br i1 false, label %inner.header, label %exit
80
81exit:
82  ret void
83
84outer.latch:
85  br label %outer.header
86}
87