1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
4
5declare void @foo_01()
6declare void @foo_02()
7declare void @foo_03()
8
9define i32 @test_01(i32* %p, i32 %x, i1 %cond) {
10; CHECK-LABEL: @test_01(
11; CHECK-NEXT:  entry:
12; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB:%.*]], label [[COMMON_RET:%.*]]
13; CHECK:       common.ret:
14; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[ENTRY:%.*]] ]
15; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
16; CHECK:       bb:
17; CHECK-NEXT:    [[R]] = load i32, i32* [[P:%.*]], align 4
18; CHECK-NEXT:    br label [[COMMON_RET]]
19;
20entry:
21  br i1 %cond, label %bb, label %pred
22
23pred:
24  switch i32 %x, label %other_succ [i32 42, label %bb
25  i32 123456, label %bb
26  i32 -654321, label %bb]
27
28bb:
29  %phi = phi i32* [null, %pred], [null, %pred], [null, %pred], [%p, %entry]
30  %r = load i32, i32* %phi
31  ret i32 %r
32
33other_succ:
34  ret i32 0
35}
36
37define i32 @test_02(i32* %p, i32 %x, i1 %cond) {
38; CHECK-LABEL: @test_02(
39; CHECK-NEXT:  entry:
40; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB:%.*]], label [[COMMON_RET:%.*]]
41; CHECK:       common.ret:
42; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[ENTRY:%.*]] ]
43; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
44; CHECK:       bb:
45; CHECK-NEXT:    [[R]] = load i32, i32* [[P:%.*]], align 4
46; CHECK-NEXT:    br label [[COMMON_RET]]
47;
48entry:
49  br i1 %cond, label %bb, label %pred
50
51pred:
52  switch i32 %x, label %bb [i32 42, label %other_succ
53  i32 123456, label %other_succ
54  i32 -654321, label %other_succ]
55
56bb:
57  %phi = phi i32* [null, %pred], [%p, %entry]
58  %r = load i32, i32* %phi
59  ret i32 %r
60
61other_succ:
62  ret i32 0
63}
64
65define i32 @test_03(i32* %p, i32 %x, i1 %cond) {
66; CHECK-LABEL: @test_03(
67; CHECK-NEXT:  entry:
68; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]]
69; CHECK:       pred:
70; CHECK-NEXT:    switch i32 [[X:%.*]], label [[UNREACHABLE:%.*]] [
71; CHECK-NEXT:    i32 42, label [[COMMON_RET:%.*]]
72; CHECK-NEXT:    i32 123456, label [[COMMON_RET]]
73; CHECK-NEXT:    i32 -654321, label [[COMMON_RET]]
74; CHECK-NEXT:    i32 1, label [[DO_1:%.*]]
75; CHECK-NEXT:    i32 2, label [[DO_2:%.*]]
76; CHECK-NEXT:    i32 3, label [[DO_3:%.*]]
77; CHECK-NEXT:    ]
78; CHECK:       common.ret:
79; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 1, [[DO_1]] ], [ 1, [[DO_2]] ], [ 1, [[DO_3]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ]
80; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
81; CHECK:       unreachable:
82; CHECK-NEXT:    unreachable
83; CHECK:       bb:
84; CHECK-NEXT:    [[R]] = load i32, i32* [[P:%.*]], align 4
85; CHECK-NEXT:    br label [[COMMON_RET]]
86; CHECK:       do_1:
87; CHECK-NEXT:    call void @foo_01()
88; CHECK-NEXT:    br label [[COMMON_RET]]
89; CHECK:       do_2:
90; CHECK-NEXT:    call void @foo_02()
91; CHECK-NEXT:    br label [[COMMON_RET]]
92; CHECK:       do_3:
93; CHECK-NEXT:    call void @foo_03()
94; CHECK-NEXT:    br label [[COMMON_RET]]
95;
96entry:
97  br i1 %cond, label %bb, label %pred
98
99pred:
100  switch i32 %x, label %bb [i32 42, label %other_succ
101  i32 123456, label %other_succ
102  i32 -654321, label %other_succ
103  i32 1, label %do_1
104  i32 2, label %do_2
105  i32 3, label %do_3]
106
107bb:
108  %phi = phi i32* [null, %pred], [%p, %entry]
109  %r = load i32, i32* %phi
110  ret i32 %r
111
112do_1:
113  call void @foo_01()
114  ret i32 1
115
116do_2:
117  call void @foo_02()
118  ret i32 1
119
120do_3:
121  call void @foo_03()
122  ret i32 1
123
124other_succ:
125  ret i32 0
126}
127
128define i32 @test_04(i32* %p, i32 %x, i1 %cond) {
129; CHECK-LABEL: @test_04(
130; CHECK-NEXT:  entry:
131; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]]
132; CHECK:       pred:
133; CHECK-NEXT:    switch i32 [[X:%.*]], label [[COMMON_RET:%.*]] [
134; CHECK-NEXT:    i32 3, label [[DO_3:%.*]]
135; CHECK-NEXT:    i32 2, label [[DO_2:%.*]]
136; CHECK-NEXT:    i32 1, label [[DO_1:%.*]]
137; CHECK-NEXT:    ]
138; CHECK:       common.ret:
139; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 1, [[DO_1]] ], [ 1, [[DO_2]] ], [ 1, [[DO_3]] ], [ 0, [[PRED]] ]
140; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
141; CHECK:       bb:
142; CHECK-NEXT:    [[R]] = load i32, i32* [[P:%.*]], align 4
143; CHECK-NEXT:    br label [[COMMON_RET]]
144; CHECK:       do_1:
145; CHECK-NEXT:    call void @foo_01()
146; CHECK-NEXT:    br label [[COMMON_RET]]
147; CHECK:       do_2:
148; CHECK-NEXT:    call void @foo_02()
149; CHECK-NEXT:    br label [[COMMON_RET]]
150; CHECK:       do_3:
151; CHECK-NEXT:    call void @foo_03()
152; CHECK-NEXT:    br label [[COMMON_RET]]
153;
154entry:
155  br i1 %cond, label %bb, label %pred
156
157pred:
158  switch i32 %x, label %other_succ [i32 42, label %bb
159  i32 123456, label %bb
160  i32 -654321, label %bb
161  i32 1, label %do_1
162  i32 2, label %do_2
163  i32 3, label %do_3]
164
165bb:
166  %phi = phi i32* [null, %pred], [null, %pred], [null, %pred], [%p, %entry]
167  %r = load i32, i32* %phi
168  ret i32 %r
169
170do_1:
171  call void @foo_01()
172  ret i32 1
173
174do_2:
175  call void @foo_02()
176  ret i32 1
177
178do_3:
179  call void @foo_03()
180  ret i32 1
181
182other_succ:
183  ret i32 0
184}
185