1; RUN: opt -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
2
3declare void @bar() nounwind
4
5define i32 @test1(i32* %a, i32 %b, i32* %c, i32 %d) nounwind {
6entry:
7  %tobool = icmp eq i32 %b, 0
8  br i1 %tobool, label %if.else, label %if.then
9
10if.then:                                          ; preds = %entry
11  tail call void @bar() nounwind
12  br label %if.end7
13
14if.else:                                          ; preds = %entry
15  %tobool3 = icmp eq i32 %d, 0
16  br i1 %tobool3, label %if.end7, label %if.then4
17
18if.then4:                                         ; preds = %if.else
19  tail call void @bar() nounwind
20  br label %if.end7
21
22if.end7:                                          ; preds = %if.else, %if.then4, %if.then
23  %x.0 = phi i32* [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ]
24  %tmp9 = load i32, i32* %x.0
25  ret i32 %tmp9
26
27; CHECK-LABEL: @test1(
28; CHECK: if.else:
29; CHECK: br label %if.end7
30
31; CHECK: phi i32* [ %a, %if.then ], [ %c, %if.else ]
32}
33
34define i32 @test1_no_null_opt(i32* %a, i32 %b, i32* %c, i32 %d) nounwind #0 {
35entry:
36  %tobool = icmp eq i32 %b, 0
37  br i1 %tobool, label %if.else, label %if.then
38
39if.then:                                          ; preds = %entry
40  tail call void @bar() nounwind
41  br label %if.end7
42
43if.else:                                          ; preds = %entry
44  %tobool3 = icmp eq i32 %d, 0
45  br i1 %tobool3, label %if.end7, label %if.then4
46
47if.then4:                                         ; preds = %if.else
48  tail call void @bar() nounwind
49  br label %if.end7
50
51if.end7:                                          ; preds = %if.else, %if.then4, %if.then
52  %x.0 = phi i32* [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ]
53  %tmp9 = load i32, i32* %x.0
54  ret i32 %tmp9
55
56; CHECK-LABEL: @test1_no_null_opt(
57; CHECK: if.then:
58; CHECK: if.else:
59; CHECK: if.then4:
60; CHECK: br label %if.end7
61; CHECK: if.end7:
62; CHECK-NEXT: phi i32* [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ]
63}
64
65define i32 @test2(i32* %a, i32 %b, i32* %c, i32 %d) nounwind {
66entry:
67  %tobool = icmp eq i32 %b, 0
68  br i1 %tobool, label %if.else, label %if.then
69
70if.then:                                          ; preds = %entry
71  tail call void @bar() nounwind
72  br label %if.end7
73
74if.else:                                          ; preds = %entry
75  %tobool3 = icmp eq i32 %d, 0
76  br i1 %tobool3, label %if.end7, label %if.then4
77
78if.then4:                                         ; preds = %if.else
79  tail call void @bar() nounwind
80  br label %if.end7
81
82if.end7:                                          ; preds = %if.else, %if.then4, %if.then
83  %x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
84  %tmp9 = load i32, i32* %x.0
85  ret i32 %tmp9
86; CHECK-LABEL: @test2(
87; CHECK: if.else:
88; CHECK: unreachable
89
90; CHECK-NOT: phi
91}
92
93define i32 @test2_no_null_opt(i32* %a, i32 %b, i32* %c, i32 %d) nounwind #0 {
94entry:
95  %tobool = icmp eq i32 %b, 0
96  br i1 %tobool, label %if.else, label %if.then
97
98if.then:                                          ; preds = %entry
99  tail call void @bar() nounwind
100  br label %if.end7
101
102if.else:                                          ; preds = %entry
103  %tobool3 = icmp eq i32 %d, 0
104  br i1 %tobool3, label %if.end7, label %if.then4
105
106if.then4:                                         ; preds = %if.else
107  tail call void @bar() nounwind
108  br label %if.end7
109
110if.end7:                                          ; preds = %if.else, %if.then4, %if.then
111  %x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
112  %tmp9 = load i32, i32* %x.0
113  ret i32 %tmp9
114; CHECK-LABEL: @test2_no_null_opt(
115; CHECK: if.then:
116; CHECK: if.else:
117; CHECK: if.then4:
118; CHECK: if.end7:
119; CHECK-NEXT: phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
120}
121
122define i32 @test3(i32* %a, i32 %b, i32* %c, i32 %d) nounwind {
123entry:
124  %tobool = icmp eq i32 %b, 0
125  br i1 %tobool, label %if.else, label %if.then
126
127if.then:                                          ; preds = %entry
128  tail call void @bar() nounwind
129  br label %if.end7
130
131if.else:                                          ; preds = %entry
132  %tobool3 = icmp eq i32 %d, 0
133  br i1 %tobool3, label %if.end7, label %if.then4
134
135if.then4:                                         ; preds = %if.else
136  tail call void @bar() nounwind
137  br label %if.end7
138
139if.end7:                                          ; preds = %if.else, %if.then4, %if.then
140  %x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
141  tail call void @bar() nounwind
142  %tmp9 = load i32, i32* %x.0
143  ret i32 %tmp9
144; CHECK-LABEL: @test3(
145; CHECK: if.end7:
146; CHECK: phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
147}
148
149define i32 @test3_no_null_opt(i32* %a, i32 %b, i32* %c, i32 %d) nounwind #0 {
150entry:
151  %tobool = icmp eq i32 %b, 0
152  br i1 %tobool, label %if.else, label %if.then
153
154if.then:                                          ; preds = %entry
155  tail call void @bar() nounwind
156  br label %if.end7
157
158if.else:                                          ; preds = %entry
159  %tobool3 = icmp eq i32 %d, 0
160  br i1 %tobool3, label %if.end7, label %if.then4
161
162if.then4:                                         ; preds = %if.else
163  tail call void @bar() nounwind
164  br label %if.end7
165
166if.end7:                                          ; preds = %if.else, %if.then4, %if.then
167  %x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
168  tail call void @bar() nounwind
169  %tmp9 = load i32, i32* %x.0
170  ret i32 %tmp9
171; CHECK-LABEL: @test3_no_null_opt(
172; CHECK: if.then:
173; CHECK: if.else:
174; CHECK: if.then4:
175; CHECK: if.end7:
176; CHECK-NEXT: phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
177}
178
179define i32 @test4(i32* %a, i32 %b, i32* %c, i32 %d) nounwind {
180entry:
181  %tobool = icmp eq i32 %b, 0
182  br i1 %tobool, label %if.else, label %if.then
183
184if.then:                                          ; preds = %entry
185  tail call void @bar() nounwind
186  br label %if.end7
187
188if.else:                                          ; preds = %entry
189  %tobool3 = icmp eq i32 %d, 0
190  br i1 %tobool3, label %if.end7, label %if.then4
191
192if.then4:                                         ; preds = %if.else
193  tail call void @bar() nounwind
194  br label %if.end7
195
196if.end7:                                          ; preds = %if.else, %if.then4, %if.then
197  %x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
198  %gep = getelementptr i32, i32* %x.0, i32 10
199  %tmp9 = load i32, i32* %gep
200  %tmp10 = or i32 %tmp9, 1
201  store i32 %tmp10, i32* %gep
202  ret i32 %tmp9
203; CHECK-LABEL: @test4(
204; CHECK-NOT: phi
205}
206
207define i32 @test4_no_null_opt(i32* %a, i32 %b, i32* %c, i32 %d) nounwind #0 {
208entry:
209  %tobool = icmp eq i32 %b, 0
210  br i1 %tobool, label %if.else, label %if.then
211
212if.then:                                          ; preds = %entry
213  tail call void @bar() nounwind
214  br label %if.end7
215
216if.else:                                          ; preds = %entry
217  %tobool3 = icmp eq i32 %d, 0
218  br i1 %tobool3, label %if.end7, label %if.then4
219
220if.then4:                                         ; preds = %if.else
221  tail call void @bar() nounwind
222  br label %if.end7
223
224if.end7:                                          ; preds = %if.else, %if.then4, %if.then
225  %x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
226  %gep = getelementptr i32, i32* %x.0, i32 10
227  %tmp9 = load i32, i32* %gep
228  %tmp10 = or i32 %tmp9, 1
229  store i32 %tmp10, i32* %gep
230  ret i32 %tmp9
231; CHECK-LABEL: @test4_no_null_opt(
232; CHECK: if.then:
233; CHECK: if.else:
234; CHECK: if.then4:
235; CHECK: if.end7:
236; CHECK-NEXT: phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
237}
238
239attributes #0 = { null_pointer_is_valid }
240