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