xref: /llvm-project/llvm/test/Transforms/LoopSimplify/pr28272.ll (revision abb9f9fa06ef22be2b0287b9047d5cfed71d91d4)
1; RUN: opt < %s -passes=lcssa,loop-simplify,indvars -S | FileCheck %s
2target triple = "x86_64-unknown-linux-gnu"
3
4; PR28272, PR28825
5; When LoopSimplify separates nested loops, it might break LCSSA form: values
6; from the original loop might be used in the outer loop. This test invokes
7; loop-unroll, which calls loop-simplify before itself. If LCSSA is broken
8; after loop-simplify, we crash on assertion.
9
10; CHECK-LABEL: @foo
11define void @foo(i1 %arg) {
12entry:
13  br label %header
14
15header:
16  br label %loop1
17
18loop1:
19  br i1 true, label %loop1, label %bb43
20
21bb43:
22  %a = phi i32 [ undef, %loop1 ], [ 0, %bb45 ], [ %a, %bb54 ]
23  %b = phi i32 [ 0, %loop1 ], [ 1, %bb54 ], [ %c, %bb45 ]
24  br i1 true, label %bb114, label %header
25
26bb114:
27  %c = add i32 0, 1
28  %d = add i32 0, 1
29  br i1 true, label %bb45, label %bb54
30
31bb45:
32  %x = add i32 %d, 0
33  br label %bb43
34
35bb54:
36  br label %bb43
37}
38
39; CHECK-LABEL: @foo2
40define void @foo2(i1 %arg) {
41entry:
42  br label %outer
43
44outer.loopexit:
45  br label %outer
46
47outer:
48  br label %loop1
49
50loop1:
51  br i1 true, label %loop1, label %loop2.preheader
52
53loop2.preheader:
54  %a.ph = phi i32 [ undef, %loop1 ]
55  %b.ph = phi i32 [ 0, %loop1 ]
56  br label %loop2
57
58loop2:
59  %a = phi i32 [ 0, %loop2.if.true ], [ %a, %loop2.if.false ], [ %a.ph, %loop2.preheader ], [0, %bb]
60  %b = phi i32 [ 1, %loop2.if.false ], [ %c, %loop2.if.true ], [ %b.ph, %loop2.preheader ], [%c, %bb]
61  br i1 true, label %loop2.if, label %outer.loopexit
62
63loop2.if:
64  %c = add i32 0, 1
65  switch i32 undef, label %loop2.if.false [i32 0, label %loop2.if.true
66                                       i32 1, label %bb]
67
68loop2.if.true:
69  br i1 %arg, label %loop2, label %bb
70
71loop2.if.false:
72  br label %loop2
73
74bb:
75  br label %loop2
76}
77
78; When LoopSimplify separates nested loops, it might break LCSSA form: values
79; from the original loop might be used in exit blocks of the outer loop.
80; CHECK-LABEL: @foo3
81define void @foo3(i1 %arg) {
82entry:
83  br label %bb1
84
85bb1:
86  br i1 %arg, label %bb2, label %bb1
87
88bb2:
89  %a = phi i32 [ undef, %bb1 ], [ %a, %bb3 ], [ undef, %bb5 ]
90  br i1 %arg, label %bb3, label %bb1
91
92bb3:
93  %b = load ptr, ptr undef
94  br i1 %arg, label %bb2, label %bb4
95
96bb4:
97  br i1 %arg, label %bb5, label %bb6
98
99bb5:
100  br i1 %arg, label %bb2, label %bb4
101
102bb6:
103  br i1 %arg, label %bb_end, label %bb1
104
105bb_end:
106  %x = getelementptr i32, ptr %b
107  br label %bb_end
108}
109
110; When LoopSimplify separates nested loops, it might break LCSSA form: values
111; from the original loop might occur in a loop, which is now a sibling of the
112; original loop (before separating it was a subloop of the original loop, and
113; thus didn't require an lcssa phi nodes).
114; CHECK-LABEL: @foo4
115define void @foo4(i1 %arg) {
116bb1:
117  br label %bb2
118
119; CHECK: bb2.loopexit:
120bb2.loopexit:                                     ; preds = %bb3
121  %i.ph = phi i32 [ 0, %bb3 ]
122  br label %bb2
123
124; CHECK: bb2.outer:
125; CHECK: bb2:
126bb2:                                              ; preds = %bb2.loopexit, %bb2, %bb1
127  %i = phi i32 [ 0, %bb1 ], [ %i, %bb2 ], [ %i.ph, %bb2.loopexit ]
128  %x = load i32, ptr undef, align 8
129  br i1 %arg, label %bb2, label %bb3.preheader
130
131; CHECK: bb3.preheader:
132bb3.preheader:                                    ; preds = %bb2
133; CHECK: %x.lcssa = phi i32 [ %x, %bb2 ]
134  br label %bb3
135
136bb3:                                              ; preds = %bb3.preheader, %bb3
137  %y = add i32 2, %x
138  br i1 true, label %bb2.loopexit, label %bb3
139}
140