xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/phi-undef-loadstore.ll (revision e7da06a0551ff4520aeeb1b71d109fff15d97eae)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
3
4declare void @bar() nounwind
5
6define i32 @test1(ptr %a, i32 %b, ptr %c, i32 %d) nounwind {
7; CHECK-LABEL: define i32 @test1
8; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0:[0-9]+]] {
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
11; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
12; CHECK:       if.then:
13; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
14; CHECK-NEXT:    br label [[IF_END7:%.*]]
15; CHECK:       if.else:
16; CHECK-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
17; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[TOBOOL3]], true
18; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
19; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
20; CHECK-NEXT:    br label [[IF_END7]]
21; CHECK:       if.end7:
22; CHECK-NEXT:    [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ [[C]], [[IF_ELSE]] ]
23; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
24; CHECK-NEXT:    ret i32 [[TMP9]]
25;
26entry:
27  %tobool = icmp eq i32 %b, 0
28  br i1 %tobool, label %if.else, label %if.then
29
30if.then:                                          ; preds = %entry
31  tail call void @bar() nounwind
32  br label %if.end7
33
34if.else:                                          ; preds = %entry
35  %tobool3 = icmp eq i32 %d, 0
36  br i1 %tobool3, label %if.end7, label %if.then4
37
38if.then4:                                         ; preds = %if.else
39  tail call void @bar() nounwind
40  br label %if.end7
41
42if.end7:                                          ; preds = %if.else, %if.then4, %if.then
43  %x.0 = phi ptr [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ]
44  %tmp9 = load i32, ptr %x.0
45  ret i32 %tmp9
46}
47
48define i32 @test1_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 {
49; CHECK-LABEL: define i32 @test1_no_null_opt
50; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1:[0-9]+]] {
51; CHECK-NEXT:  entry:
52; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
53; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
54; CHECK:       if.then:
55; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
56; CHECK-NEXT:    br label [[IF_END7:%.*]]
57; CHECK:       if.else:
58; CHECK-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
59; CHECK-NEXT:    br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
60; CHECK:       if.then4:
61; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
62; CHECK-NEXT:    br label [[IF_END7]]
63; CHECK:       if.end7:
64; CHECK-NEXT:    [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ [[C]], [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
65; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
66; CHECK-NEXT:    ret i32 [[TMP9]]
67;
68entry:
69  %tobool = icmp eq i32 %b, 0
70  br i1 %tobool, label %if.else, label %if.then
71
72if.then:                                          ; preds = %entry
73  tail call void @bar() nounwind
74  br label %if.end7
75
76if.else:                                          ; preds = %entry
77  %tobool3 = icmp eq i32 %d, 0
78  br i1 %tobool3, label %if.end7, label %if.then4
79
80if.then4:                                         ; preds = %if.else
81  tail call void @bar() nounwind
82  br label %if.end7
83
84if.end7:                                          ; preds = %if.else, %if.then4, %if.then
85  %x.0 = phi ptr [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ]
86  %tmp9 = load i32, ptr %x.0
87  ret i32 %tmp9
88}
89
90define i32 @test2(ptr %a, i32 %b, ptr %c, i32 %d) nounwind {
91; CHECK-LABEL: define i32 @test2
92; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0]] {
93; CHECK-NEXT:  entry:
94; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
95; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
96; CHECK:       if.then:
97; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
98; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[A]], align 4
99; CHECK-NEXT:    ret i32 [[TMP9]]
100; CHECK:       if.else:
101; CHECK-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
102; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[TOBOOL3]], true
103; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
104; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
105; CHECK-NEXT:    unreachable
106;
107entry:
108  %tobool = icmp eq i32 %b, 0
109  br i1 %tobool, label %if.else, label %if.then
110
111if.then:                                          ; preds = %entry
112  tail call void @bar() nounwind
113  br label %if.end7
114
115if.else:                                          ; preds = %entry
116  %tobool3 = icmp eq i32 %d, 0
117  br i1 %tobool3, label %if.end7, label %if.then4
118
119if.then4:                                         ; preds = %if.else
120  tail call void @bar() nounwind
121  br label %if.end7
122
123if.end7:                                          ; preds = %if.else, %if.then4, %if.then
124  %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
125  %tmp9 = load i32, ptr %x.0
126  ret i32 %tmp9
127}
128
129define i32 @test2_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 {
130; CHECK-LABEL: define i32 @test2_no_null_opt
131; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1]] {
132; CHECK-NEXT:  entry:
133; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
134; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
135; CHECK:       if.then:
136; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
137; CHECK-NEXT:    br label [[IF_END7:%.*]]
138; CHECK:       if.else:
139; CHECK-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
140; CHECK-NEXT:    br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
141; CHECK:       if.then4:
142; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
143; CHECK-NEXT:    br label [[IF_END7]]
144; CHECK:       if.end7:
145; CHECK-NEXT:    [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
146; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
147; CHECK-NEXT:    ret i32 [[TMP9]]
148;
149entry:
150  %tobool = icmp eq i32 %b, 0
151  br i1 %tobool, label %if.else, label %if.then
152
153if.then:                                          ; preds = %entry
154  tail call void @bar() nounwind
155  br label %if.end7
156
157if.else:                                          ; preds = %entry
158  %tobool3 = icmp eq i32 %d, 0
159  br i1 %tobool3, label %if.end7, label %if.then4
160
161if.then4:                                         ; preds = %if.else
162  tail call void @bar() nounwind
163  br label %if.end7
164
165if.end7:                                          ; preds = %if.else, %if.then4, %if.then
166  %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
167  %tmp9 = load i32, ptr %x.0
168  ret i32 %tmp9
169}
170
171define i32 @test3(ptr %a, i32 %b, ptr %c, i32 %d) nounwind {
172; CHECK-LABEL: define i32 @test3
173; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0]] {
174; CHECK-NEXT:  entry:
175; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
176; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
177; CHECK:       if.then:
178; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
179; CHECK-NEXT:    br label [[IF_END7:%.*]]
180; CHECK:       if.else:
181; CHECK-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
182; CHECK-NEXT:    br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
183; CHECK:       if.then4:
184; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
185; CHECK-NEXT:    br label [[IF_END7]]
186; CHECK:       if.end7:
187; CHECK-NEXT:    [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
188; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
189; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
190; CHECK-NEXT:    ret i32 [[TMP9]]
191;
192entry:
193  %tobool = icmp eq i32 %b, 0
194  br i1 %tobool, label %if.else, label %if.then
195
196if.then:                                          ; preds = %entry
197  tail call void @bar() nounwind
198  br label %if.end7
199
200if.else:                                          ; preds = %entry
201  %tobool3 = icmp eq i32 %d, 0
202  br i1 %tobool3, label %if.end7, label %if.then4
203
204if.then4:                                         ; preds = %if.else
205  tail call void @bar() nounwind
206  br label %if.end7
207
208if.end7:                                          ; preds = %if.else, %if.then4, %if.then
209  %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
210  tail call void @bar() nounwind
211  %tmp9 = load i32, ptr %x.0
212  ret i32 %tmp9
213}
214
215define i32 @test3_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 {
216; CHECK-LABEL: define i32 @test3_no_null_opt
217; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1]] {
218; CHECK-NEXT:  entry:
219; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
220; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
221; CHECK:       if.then:
222; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
223; CHECK-NEXT:    br label [[IF_END7:%.*]]
224; CHECK:       if.else:
225; CHECK-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
226; CHECK-NEXT:    br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
227; CHECK:       if.then4:
228; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
229; CHECK-NEXT:    br label [[IF_END7]]
230; CHECK:       if.end7:
231; CHECK-NEXT:    [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
232; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
233; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
234; CHECK-NEXT:    ret i32 [[TMP9]]
235;
236entry:
237  %tobool = icmp eq i32 %b, 0
238  br i1 %tobool, label %if.else, label %if.then
239
240if.then:                                          ; preds = %entry
241  tail call void @bar() nounwind
242  br label %if.end7
243
244if.else:                                          ; preds = %entry
245  %tobool3 = icmp eq i32 %d, 0
246  br i1 %tobool3, label %if.end7, label %if.then4
247
248if.then4:                                         ; preds = %if.else
249  tail call void @bar() nounwind
250  br label %if.end7
251
252if.end7:                                          ; preds = %if.else, %if.then4, %if.then
253  %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
254  tail call void @bar() nounwind
255  %tmp9 = load i32, ptr %x.0
256  ret i32 %tmp9
257}
258
259define i32 @test4(ptr %a, i32 %b, ptr %c, i32 %d) nounwind {
260; CHECK-LABEL: define i32 @test4
261; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0]] {
262; CHECK-NEXT:  entry:
263; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
264; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
265; CHECK:       if.then:
266; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
267; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[A]], i32 10
268; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[GEP]], align 4
269; CHECK-NEXT:    [[TMP10:%.*]] = or i32 [[TMP9]], 1
270; CHECK-NEXT:    store i32 [[TMP10]], ptr [[GEP]], align 4
271; CHECK-NEXT:    ret i32 [[TMP9]]
272; CHECK:       if.else:
273; CHECK-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
274; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[TOBOOL3]], true
275; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
276; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
277; CHECK-NEXT:    unreachable
278;
279entry:
280  %tobool = icmp eq i32 %b, 0
281  br i1 %tobool, label %if.else, label %if.then
282
283if.then:                                          ; preds = %entry
284  tail call void @bar() nounwind
285  br label %if.end7
286
287if.else:                                          ; preds = %entry
288  %tobool3 = icmp eq i32 %d, 0
289  br i1 %tobool3, label %if.end7, label %if.then4
290
291if.then4:                                         ; preds = %if.else
292  tail call void @bar() nounwind
293  br label %if.end7
294
295if.end7:                                          ; preds = %if.else, %if.then4, %if.then
296  %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
297  %gep = getelementptr i32, ptr %x.0, i32 10
298  %tmp9 = load i32, ptr %gep
299  %tmp10 = or i32 %tmp9, 1
300  store i32 %tmp10, ptr %gep
301  ret i32 %tmp9
302}
303
304define i32 @test4_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 {
305; CHECK-LABEL: define i32 @test4_no_null_opt
306; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1]] {
307; CHECK-NEXT:  entry:
308; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
309; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
310; CHECK:       if.then:
311; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
312; CHECK-NEXT:    br label [[IF_END7:%.*]]
313; CHECK:       if.else:
314; CHECK-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
315; CHECK-NEXT:    br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
316; CHECK:       if.then4:
317; CHECK-NEXT:    tail call void @bar() #[[ATTR0]]
318; CHECK-NEXT:    br label [[IF_END7]]
319; CHECK:       if.end7:
320; CHECK-NEXT:    [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
321; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[X_0]], i32 10
322; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[GEP]], align 4
323; CHECK-NEXT:    [[TMP10:%.*]] = or i32 [[TMP9]], 1
324; CHECK-NEXT:    store i32 [[TMP10]], ptr [[GEP]], align 4
325; CHECK-NEXT:    ret i32 [[TMP9]]
326;
327entry:
328  %tobool = icmp eq i32 %b, 0
329  br i1 %tobool, label %if.else, label %if.then
330
331if.then:                                          ; preds = %entry
332  tail call void @bar() nounwind
333  br label %if.end7
334
335if.else:                                          ; preds = %entry
336  %tobool3 = icmp eq i32 %d, 0
337  br i1 %tobool3, label %if.end7, label %if.then4
338
339if.then4:                                         ; preds = %if.else
340  tail call void @bar() nounwind
341  br label %if.end7
342
343if.end7:                                          ; preds = %if.else, %if.then4, %if.then
344  %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
345  %gep = getelementptr i32, ptr %x.0, i32 10
346  %tmp9 = load i32, ptr %gep
347  %tmp10 = or i32 %tmp9, 1
348  store i32 %tmp10, ptr %gep
349  ret i32 %tmp9
350}
351
352attributes #0 = { null_pointer_is_valid }
353