xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll (revision d1d129356909af2f6fefd6f1b9335a39fe172e9a)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3
4; ModuleID = '<stdin>'
5declare i1 @foo()
6
7declare i1 @bar(i32)
8
9; This function can't be merged
10define void @a() {
11; CHECK-LABEL: @a(
12; CHECK-NEXT:  entry:
13; CHECK-NEXT:    br label [[BB_NOMERGE:%.*]]
14; CHECK:       BB.nomerge:
15; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 0, [[COMMON:%.*]] ]
16; CHECK-NEXT:    br label [[SUCC:%.*]]
17; CHECK:       Succ:
18; CHECK-NEXT:    [[B:%.*]] = phi i32 [ [[A]], [[BB_NOMERGE]] ], [ 2, [[COMMON]] ]
19; CHECK-NEXT:    [[CONDE:%.*]] = call i1 @foo()
20; CHECK-NEXT:    br i1 [[CONDE]], label [[COMMON]], label [[EXIT:%.*]]
21; CHECK:       Common:
22; CHECK-NEXT:    [[COND:%.*]] = call i1 @foo()
23; CHECK-NEXT:    br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
24; CHECK:       Exit:
25; CHECK-NEXT:    ret void
26;
27entry:
28  br label %BB.nomerge
29
30BB.nomerge:		; preds = %Common, %entry
31  ; This phi has a conflicting value (0) with below phi (2), so blocks
32  ; can't be merged.
33  %a = phi i32 [ 1, %entry ], [ 0, %Common ]		; <i32> [#uses=1]
34  br label %Succ
35
36Succ:		; preds = %Common, %BB.nomerge
37  %b = phi i32 [ %a, %BB.nomerge ], [ 2, %Common ]		; <i32> [#uses=0]
38  %conde = call i1 @foo( )		; <i1> [#uses=1]
39  br i1 %conde, label %Common, label %Exit
40
41Common:		; preds = %Succ
42  %cond = call i1 @foo( )		; <i1> [#uses=1]
43  br i1 %cond, label %BB.nomerge, label %Succ
44
45Exit:		; preds = %Succ
46  ret void
47}
48
49; This function can't be merged
50define void @b() {
51; CHECK-LABEL: @b(
52; CHECK-NEXT:  entry:
53; CHECK-NEXT:    br label [[BB_NOMERGE:%.*]]
54; CHECK:       BB.nomerge:
55; CHECK-NEXT:    br label [[SUCC:%.*]]
56; CHECK:       Succ:
57; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 1, [[BB_NOMERGE]] ], [ 2, [[COMMON:%.*]] ]
58; CHECK-NEXT:    [[CONDE:%.*]] = call i1 @foo()
59; CHECK-NEXT:    br i1 [[CONDE]], label [[COMMON]], label [[EXIT:%.*]]
60; CHECK:       Common:
61; CHECK-NEXT:    [[COND:%.*]] = call i1 @foo()
62; CHECK-NEXT:    br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
63; CHECK:       Exit:
64; CHECK-NEXT:    ret void
65;
66entry:
67  br label %BB.nomerge
68
69BB.nomerge:		; preds = %Common, %entry
70  br label %Succ
71
72Succ:		; preds = %Common, %BB.nomerge
73  ; This phi has confliction values for Common and (through BB) Common,
74  ; blocks can't be merged
75  %b = phi i32 [ 1, %BB.nomerge ], [ 2, %Common ]		; <i32> [#uses=0]
76  %conde = call i1 @foo( )		; <i1> [#uses=1]
77  br i1 %conde, label %Common, label %Exit
78
79Common:		; preds = %Succ
80  %cond = call i1 @foo( )		; <i1> [#uses=1]
81  br i1 %cond, label %BB.nomerge, label %Succ
82
83Exit:		; preds = %Succ
84  ret void
85}
86
87; This function can't be merged (for keeping canonical loop structures)
88define void @c() {
89; CHECK-LABEL: @c(
90; CHECK-NEXT:  entry:
91; CHECK-NEXT:    br label [[BB_NOMERGE:%.*]]
92; CHECK:       BB.nomerge:
93; CHECK-NEXT:    br label [[SUCC:%.*]]
94; CHECK:       Succ:
95; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 1, [[BB_NOMERGE]] ], [ 1, [[COMMON:%.*]] ], [ 2, [[PRE_EXIT:%.*]] ]
96; CHECK-NEXT:    [[CONDE:%.*]] = call i1 @foo()
97; CHECK-NEXT:    br i1 [[CONDE]], label [[COMMON]], label [[PRE_EXIT]]
98; CHECK:       Common:
99; CHECK-NEXT:    [[COND:%.*]] = call i1 @foo()
100; CHECK-NEXT:    br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
101; CHECK:       Pre-Exit:
102; CHECK-NEXT:    [[COND2:%.*]] = call i1 @foo()
103; CHECK-NEXT:    br i1 [[COND2]], label [[SUCC]], label [[EXIT:%.*]]
104; CHECK:       Exit:
105; CHECK-NEXT:    ret void
106;
107entry:
108  br label %BB.nomerge
109
110BB.nomerge:		; preds = %Common, %entry
111  br label %Succ
112
113Succ:		; preds = %Common, %BB.tomerge, %Pre-Exit
114  ; This phi has identical values for Common and (through BB) Common,
115  ; blocks can't be merged
116  %b = phi i32 [ 1, %BB.nomerge ], [ 1, %Common ], [ 2, %Pre-Exit ]
117  %conde = call i1 @foo( )		; <i1> [#uses=1]
118  br i1 %conde, label %Common, label %Pre-Exit
119
120Common:		; preds = %Succ
121  %cond = call i1 @foo( )		; <i1> [#uses=1]
122  br i1 %cond, label %BB.nomerge, label %Succ
123
124Pre-Exit:       ; preds = %Succ
125  ; This adds a backedge, so the %b phi node gets a third branch and is
126  ; not completely trivial
127  %cond2 = call i1 @foo( )		; <i1> [#uses=1]
128  br i1 %cond2, label %Succ, label %Exit
129
130Exit:		; preds = %Pre-Exit
131  ret void
132}
133
134; This function can't be merged (for keeping canonical loop structures)
135define void @d() {
136; CHECK-LABEL: @d(
137; CHECK-NEXT:  entry:
138; CHECK-NEXT:    br label [[BB_NOMERGE:%.*]]
139; CHECK:       BB.nomerge:
140; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 0, [[COMMON:%.*]] ]
141; CHECK-NEXT:    br label [[SUCC:%.*]]
142; CHECK:       Succ:
143; CHECK-NEXT:    [[B:%.*]] = phi i32 [ [[A]], [[BB_NOMERGE]] ], [ 0, [[COMMON]] ]
144; CHECK-NEXT:    [[CONDE:%.*]] = call i1 @foo()
145; CHECK-NEXT:    br i1 [[CONDE]], label [[COMMON]], label [[EXIT:%.*]]
146; CHECK:       Common:
147; CHECK-NEXT:    [[COND:%.*]] = call i1 @foo()
148; CHECK-NEXT:    br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
149; CHECK:       Exit:
150; CHECK-NEXT:    ret void
151;
152entry:
153  br label %BB.nomerge
154
155BB.nomerge:		; preds = %Common, %entry
156  ; This phi has a matching value (0) with below phi (0), so blocks
157  ; can be merged.
158  %a = phi i32 [ 1, %entry ], [ 0, %Common ]		; <i32> [#uses=1]
159  br label %Succ
160
161Succ:		; preds = %Common, %BB.tomerge
162  %b = phi i32 [ %a, %BB.nomerge ], [ 0, %Common ]		; <i32> [#uses=0]
163  %conde = call i1 @foo( )		; <i1> [#uses=1]
164  br i1 %conde, label %Common, label %Exit
165
166Common:		; preds = %Succ
167  %cond = call i1 @foo( )		; <i1> [#uses=1]
168  br i1 %cond, label %BB.nomerge, label %Succ
169
170Exit:		; preds = %Succ
171  ret void
172}
173
174; This function can be merged
175define void @e() {
176; CHECK-LABEL: @e(
177; CHECK-NEXT:  entry:
178; CHECK-NEXT:    br label [[SUCC:%.*]]
179; CHECK:       Succ:
180; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 0, [[USE:%.*]] ]
181; CHECK-NEXT:    [[CONDE:%.*]] = call i1 @foo()
182; CHECK-NEXT:    br i1 [[CONDE]], label [[USE]], label [[EXIT:%.*]]
183; CHECK:       Use:
184; CHECK-NEXT:    [[COND:%.*]] = call i1 @bar(i32 [[A]])
185; CHECK-NEXT:    br i1 [[COND]], label [[SUCC]], label [[EXIT]]
186; CHECK:       Exit:
187; CHECK-NEXT:    ret void
188;
189entry:
190  br label %Succ
191
192Succ:		; preds = %Use, %entry
193  ; This phi is used somewhere else than Succ, but this should not prevent
194  ; merging this block
195  %a = phi i32 [ 1, %entry ], [ 0, %Use ]		; <i32> [#uses=1]
196  br label %BB.tomerge
197
198BB.tomerge:		; preds = %BB.tomerge
199  %conde = call i1 @foo( )		; <i1> [#uses=1]
200  br i1 %conde, label %Use, label %Exit
201
202Use:		; preds = %Succ
203  %cond = call i1 @bar( i32 %a )		; <i1> [#uses=1]
204  br i1 %cond, label %Succ, label %Exit
205
206Exit:		; preds = %Use, %Succ
207  ret void
208}
209