[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / switch-dead-default.ll
blob1662bb99f27bcc696b3eb3214ef20bf5cf5bfcb0
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -S -passes='simplifycfg<switch-to-lookup>' -simplifycfg-require-and-preserve-domtree=1 -switch-range-to-icmp | FileCheck %s
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 declare void @foo(i32)
7 define void @test(i1 %a) {
8 ; CHECK-LABEL: @test(
9 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i1 [[A:%.*]], true
10 ; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i1 [[A_OFF]], true
11 ; CHECK-NEXT:    br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
12 ; CHECK:       common.ret:
13 ; CHECK-NEXT:    ret void
14 ; CHECK:       true:
15 ; CHECK-NEXT:    call void @foo(i32 1)
16 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
17 ; CHECK:       false:
18 ; CHECK-NEXT:    call void @foo(i32 3)
19 ; CHECK-NEXT:    br label [[COMMON_RET]]
21   switch i1 %a, label %default [i1 1, label %true
22   i1 0, label %false]
23 true:
24   call void @foo(i32 1)
25   ret void
26 false:
27   call void @foo(i32 3)
28   ret void
29 default:
30   call void @foo(i32 2)
31   ret void
34 define void @test2(i2 %a) {
35 ; CHECK-LABEL: @test2(
36 ; CHECK-NEXT:    switch i2 [[A:%.*]], label [[DOTUNREACHABLEDEFAULT:%.*]] [
37 ; CHECK-NEXT:    i2 0, label [[CASE0:%.*]]
38 ; CHECK-NEXT:    i2 1, label [[CASE1:%.*]]
39 ; CHECK-NEXT:    i2 -2, label [[CASE2:%.*]]
40 ; CHECK-NEXT:    i2 -1, label [[CASE3:%.*]]
41 ; CHECK-NEXT:    ]
42 ; CHECK:       common.ret:
43 ; CHECK-NEXT:    ret void
44 ; CHECK:       case0:
45 ; CHECK-NEXT:    call void @foo(i32 0)
46 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
47 ; CHECK:       case1:
48 ; CHECK-NEXT:    call void @foo(i32 1)
49 ; CHECK-NEXT:    br label [[COMMON_RET]]
50 ; CHECK:       case2:
51 ; CHECK-NEXT:    call void @foo(i32 2)
52 ; CHECK-NEXT:    br label [[COMMON_RET]]
53 ; CHECK:       case3:
54 ; CHECK-NEXT:    call void @foo(i32 3)
55 ; CHECK-NEXT:    br label [[COMMON_RET]]
56 ; CHECK:       .unreachabledefault:
57 ; CHECK-NEXT:    unreachable
59   switch i2 %a, label %default [i2 0, label %case0
60   i2 1, label %case1
61   i2 2, label %case2
62   i2 3, label %case3]
63 case0:
64   call void @foo(i32 0)
65   ret void
66 case1:
67   call void @foo(i32 1)
68   ret void
69 case2:
70   call void @foo(i32 2)
71   ret void
72 case3:
73   call void @foo(i32 3)
74   ret void
75 default:
76   call void @foo(i32 4)
77   ret void
80 ; This one is a negative test - we know the value of the default,
81 ; but that's about it
82 define void @test3(i2 %a) {
83 ; CHECK-LABEL: @test3(
84 ; CHECK-NEXT:    switch i2 [[A:%.*]], label [[DEFAULT:%.*]] [
85 ; CHECK-NEXT:    i2 0, label [[CASE0:%.*]]
86 ; CHECK-NEXT:    i2 1, label [[CASE1:%.*]]
87 ; CHECK-NEXT:    i2 -2, label [[CASE2:%.*]]
88 ; CHECK-NEXT:    ]
89 ; CHECK:       common.ret:
90 ; CHECK-NEXT:    ret void
91 ; CHECK:       case0:
92 ; CHECK-NEXT:    call void @foo(i32 0)
93 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
94 ; CHECK:       case1:
95 ; CHECK-NEXT:    call void @foo(i32 1)
96 ; CHECK-NEXT:    br label [[COMMON_RET]]
97 ; CHECK:       case2:
98 ; CHECK-NEXT:    call void @foo(i32 2)
99 ; CHECK-NEXT:    br label [[COMMON_RET]]
100 ; CHECK:       default:
101 ; CHECK-NEXT:    call void @foo(i32 3)
102 ; CHECK-NEXT:    br label [[COMMON_RET]]
104   switch i2 %a, label %default [i2 0, label %case0
105   i2 1, label %case1
106   i2 2, label %case2]
108 case0:
109   call void @foo(i32 0)
110   ret void
111 case1:
112   call void @foo(i32 1)
113   ret void
114 case2:
115   call void @foo(i32 2)
116   ret void
117 default:
118   call void @foo(i32 3)
119   ret void
122 ; Negative test - check for possible overflow when computing
123 ; number of possible cases.
124 define void @test4(i128 %a) {
125 ; CHECK-LABEL: @test4(
126 ; CHECK-NEXT:    switch i128 [[A:%.*]], label [[DEFAULT:%.*]] [
127 ; CHECK-NEXT:    i128 0, label [[CASE0:%.*]]
128 ; CHECK-NEXT:    i128 1, label [[CASE1:%.*]]
129 ; CHECK-NEXT:    ]
130 ; CHECK:       common.ret:
131 ; CHECK-NEXT:    ret void
132 ; CHECK:       case0:
133 ; CHECK-NEXT:    call void @foo(i32 0)
134 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
135 ; CHECK:       case1:
136 ; CHECK-NEXT:    call void @foo(i32 1)
137 ; CHECK-NEXT:    br label [[COMMON_RET]]
138 ; CHECK:       default:
139 ; CHECK-NEXT:    call void @foo(i32 2)
140 ; CHECK-NEXT:    br label [[COMMON_RET]]
142   switch i128 %a, label %default [i128 0, label %case0
143   i128 1, label %case1]
145 case0:
146   call void @foo(i32 0)
147   ret void
148 case1:
149   call void @foo(i32 1)
150   ret void
151 default:
152   call void @foo(i32 2)
153   ret void
156 ; All but one bit known zero
157 define void @test5(i8 %a) {
158 ; CHECK-LABEL: @test5(
159 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[A:%.*]], 2
160 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
161 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i8 [[A]], -1
162 ; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i8 [[A_OFF]], 1
163 ; CHECK-NEXT:    br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
164 ; CHECK:       common.ret:
165 ; CHECK-NEXT:    ret void
166 ; CHECK:       true:
167 ; CHECK-NEXT:    call void @foo(i32 1)
168 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
169 ; CHECK:       false:
170 ; CHECK-NEXT:    call void @foo(i32 3)
171 ; CHECK-NEXT:    br label [[COMMON_RET]]
173   %cmp = icmp ult i8 %a, 2
174   call void @llvm.assume(i1 %cmp)
175   switch i8 %a, label %default [i8 1, label %true
176   i8 0, label %false]
177 true:
178   call void @foo(i32 1)
179   ret void
180 false:
181   call void @foo(i32 3)
182   ret void
183 default:
184   call void @foo(i32 2)
185   ret void
188 ;; All but one bit known one
189 define void @test6(i8 %a) {
190 ; CHECK-LABEL: @test6(
191 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[A:%.*]], -2
192 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[AND]], -2
193 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
194 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i8 [[A]], 1
195 ; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i8 [[A_OFF]], 1
196 ; CHECK-NEXT:    br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
197 ; CHECK:       common.ret:
198 ; CHECK-NEXT:    ret void
199 ; CHECK:       true:
200 ; CHECK-NEXT:    call void @foo(i32 1)
201 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
202 ; CHECK:       false:
203 ; CHECK-NEXT:    call void @foo(i32 3)
204 ; CHECK-NEXT:    br label [[COMMON_RET]]
206   %and = and i8 %a, 254
207   %cmp = icmp eq i8 %and, 254
208   call void @llvm.assume(i1 %cmp)
209   switch i8 %a, label %default [i8 255, label %true
210   i8 254, label %false]
211 true:
212   call void @foo(i32 1)
213   ret void
214 false:
215   call void @foo(i32 3)
216   ret void
217 default:
218   call void @foo(i32 2)
219   ret void
222 ; Check that we can eliminate both dead cases and dead defaults
223 ; within a single run of simplifycfg
224 define void @test7(i8 %a) {
225 ; CHECK-LABEL: @test7(
226 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[A:%.*]], -2
227 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[AND]], -2
228 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
229 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i8 [[A]], 1
230 ; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i8 [[A_OFF]], 1
231 ; CHECK-NEXT:    br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
232 ; CHECK:       common.ret:
233 ; CHECK-NEXT:    ret void
234 ; CHECK:       true:
235 ; CHECK-NEXT:    call void @foo(i32 1)
236 ; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
237 ; CHECK:       false:
238 ; CHECK-NEXT:    call void @foo(i32 3)
239 ; CHECK-NEXT:    br label [[COMMON_RET]]
241   %and = and i8 %a, 254
242   %cmp = icmp eq i8 %and, 254
243   call void @llvm.assume(i1 %cmp)
244   switch i8 %a, label %default [i8 255, label %true
245   i8 254, label %false
246   i8 0, label %also_dead]
247 true:
248   call void @foo(i32 1)
249   ret void
250 false:
251   call void @foo(i32 3)
252   ret void
253 also_dead:
254   call void @foo(i32 5)
255   ret void
256 default:
257   call void @foo(i32 2)
258   ret void
261 declare void @llvm.assume(i1)