xref: /llvm-project/llvm/test/Transforms/DeadStoreElimination/multiblock-unreachable.ll (revision f497a00da968b0ff90d8c98caa184d14b9a92495)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=dse -S %s | FileCheck %s
3
4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5
6; Make sure we do not crash when we encounter unreachable blocks while checking
7; if all paths to DomAccess go through a killing block.
8define void @test(ptr %ptr, i1 %c.1, i1 %c.2, i1 %c.3) {
9; CHECK-LABEL: @test(
10; CHECK-NEXT:  bb:
11; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB27:%.*]], label [[BB53:%.*]]
12; CHECK:       bb10:
13; CHECK-NEXT:    br label [[BB43:%.*]]
14; CHECK:       bb22:
15; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB22:%.*]], label [[BB53]]
16; CHECK:       bb27:
17; CHECK-NEXT:    br i1 [[C_3:%.*]], label [[BB38:%.*]], label [[BB39:%.*]]
18; CHECK:       bb38:
19; CHECK-NEXT:    store float 0.000000e+00, ptr [[PTR:%.*]], align 4
20; CHECK-NEXT:    br label [[BB38]]
21; CHECK:       bb39:
22; CHECK-NEXT:    br i1 [[C_2]], label [[BB43]], label [[BB38]]
23; CHECK:       bb43:
24; CHECK-NEXT:    store float 0.000000e+00, ptr [[PTR]], align 4
25; CHECK-NEXT:    br label [[BB50:%.*]]
26; CHECK:       bb50:
27; CHECK-NEXT:    br i1 [[C_3]], label [[BB27]], label [[BB53]]
28; CHECK:       bb53:
29; CHECK-NEXT:    br label [[BB53]]
30;
31bb:
32  br i1 %c.1, label %bb27, label %bb53
33
34bb10:                                             ; No predecessors!
35  br label %bb43
36
37bb22:                                             ; preds = %bb22
38  br i1 %c.2, label %bb22, label %bb53
39
40bb27:                                             ; preds = %bb50, %bb
41  br i1 %c.3, label %bb38, label %bb39
42
43bb38:                                             ; preds = %bb39, %bb38, %bb27
44  store float 0.000000e+00, ptr %ptr, align 4
45  br label %bb38
46
47bb39:                                             ; preds = %bb27
48  br i1 %c.2, label %bb43, label %bb38
49
50bb43:                                             ; preds = %bb39, %bb10
51  store float 0.000000e+00, ptr %ptr, align 4
52  br label %bb50
53
54bb50:                                             ; preds = %bb43
55  br i1 %c.3, label %bb27, label %bb53
56
57bb53:                                             ; preds = %bb53, %bb50, %bb22, %bb
58  br label %bb53
59}
60
61declare void @exit()
62
63define void @unreachable_exit_with_no_call(ptr noalias %ptr, i1 %c.1) {
64; CHECK-LABEL: @unreachable_exit_with_no_call(
65; CHECK-NEXT:  entry:
66; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
67; CHECK:       if.then:
68; CHECK-NEXT:    unreachable
69; CHECK:       if.end:
70; CHECK-NEXT:    store i64 0, ptr [[PTR:%.*]], align 8
71; CHECK-NEXT:    ret void
72;
73entry:
74  store i64 1, ptr %ptr, align 8
75  br i1 %c.1, label %if.then, label %if.end
76
77if.then:
78  unreachable
79
80if.end:
81  store i64 0, ptr %ptr, align 8
82  ret void
83}
84
85; Test for PR53800.
86define void @unreachable_exit_with_nounwind_call_pr53800(ptr noalias %ptr, i1 %c.1) {
87; CHECK-LABEL: @unreachable_exit_with_nounwind_call_pr53800(
88; CHECK-NEXT:  entry:
89; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
90; CHECK:       if.then:
91; CHECK-NEXT:    tail call void @exit() #[[ATTR0:[0-9]+]]
92; CHECK-NEXT:    unreachable
93; CHECK:       if.end:
94; CHECK-NEXT:    store i64 0, ptr [[PTR:%.*]], align 8
95; CHECK-NEXT:    ret void
96;
97entry:
98  store i64 1, ptr %ptr, align 8
99  br i1 %c.1, label %if.then, label %if.end
100
101if.then:
102  tail call void @exit() nounwind
103  unreachable
104
105if.end:
106  store i64 0, ptr %ptr, align 8
107  ret void
108}
109
110; The call @exit may read %ptr as it is not marked as noalias
111define void @unreachable_exit_and_call_may_read(ptr %ptr, i1 %c.1) {
112; CHECK-LABEL: @unreachable_exit_and_call_may_read(
113; CHECK-NEXT:  entry:
114; CHECK-NEXT:    store i64 1, ptr [[PTR:%.*]], align 8
115; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
116; CHECK:       if.then:
117; CHECK-NEXT:    tail call void @exit() #[[ATTR0]]
118; CHECK-NEXT:    unreachable
119; CHECK:       if.end:
120; CHECK-NEXT:    store i64 0, ptr [[PTR]], align 8
121; CHECK-NEXT:    ret void
122;
123entry:
124  store i64 1, ptr %ptr, align 8
125  br i1 %c.1, label %if.then, label %if.end
126
127if.then:
128  tail call void @exit() nounwind
129  unreachable
130
131if.end:
132  store i64 0, ptr %ptr, align 8
133  ret void
134}
135
136define void @unreachable_exit_with_may_unwind_call(ptr noalias %ptr, i1 %c.1) {
137; CHECK-LABEL: @unreachable_exit_with_may_unwind_call(
138; CHECK-NEXT:  entry:
139; CHECK-NEXT:    store i64 1, ptr [[PTR:%.*]], align 8
140; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
141; CHECK:       if.then:
142; CHECK-NEXT:    tail call void @exit()
143; CHECK-NEXT:    unreachable
144; CHECK:       if.end:
145; CHECK-NEXT:    store i64 0, ptr [[PTR]], align 8
146; CHECK-NEXT:    ret void
147;
148entry:
149  store i64 1, ptr %ptr, align 8
150  br i1 %c.1, label %if.then, label %if.end
151
152if.then:
153  tail call void @exit()
154  unreachable
155
156if.end:
157  store i64 0, ptr %ptr, align 8
158  ret void
159}
160
161; Cannot remove the store in entry, because it is not dead on the path to e.1
162define void @unreachable_exit_but_another_exit(ptr noalias %ptr, i1 %c.1, i32 %s, i1 %c.2) {
163; CHECK-LABEL: @unreachable_exit_but_another_exit(
164; CHECK-NEXT:  entry:
165; CHECK-NEXT:    store i64 1, ptr [[PTR:%.*]], align 8
166; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
167; CHECK:       if.then:
168; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[E_0:%.*]], label [[E_1:%.*]]
169; CHECK:       e.0:
170; CHECK-NEXT:    tail call void @exit() #[[ATTR0]]
171; CHECK-NEXT:    unreachable
172; CHECK:       e.1:
173; CHECK-NEXT:    ret void
174; CHECK:       if.end:
175; CHECK-NEXT:    store i64 0, ptr [[PTR]], align 8
176; CHECK-NEXT:    ret void
177;
178entry:
179  store i64 1, ptr %ptr, align 8
180  br i1 %c.1, label %if.then, label %if.end
181
182if.then:
183  br i1 %c.2, label %e.0, label %e.1
184
185e.0:
186  tail call void @exit() nounwind
187  unreachable
188
189e.1:
190  ret void
191
192if.end:
193  store i64 0, ptr %ptr, align 8
194  ret void
195}
196