1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -S -passes='simplify-cfg<switch-to-lookup>' | FileCheck %s
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6 define void @test(i1 %a) {
8 ; CHECK-NEXT: [[A_OFF:%.*]] = add i1 [[A:%.*]], true
9 ; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i1 [[A_OFF]], true
10 ; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
12 ; CHECK-NEXT: call void @foo(i32 1)
13 ; CHECK-NEXT: ret void
15 ; CHECK-NEXT: call void @foo(i32 3)
16 ; CHECK-NEXT: ret void
18 switch i1 %a, label %default [i1 1, label %true
31 define void @test2(i2 %a) {
32 ; CHECK-LABEL: @test2(
33 ; CHECK-NEXT: switch i2 [[A:%.*]], label [[DEFAULT1:%.*]] [
34 ; CHECK-NEXT: i2 0, label [[CASE0:%.*]]
35 ; CHECK-NEXT: i2 1, label [[CASE1:%.*]]
36 ; CHECK-NEXT: i2 -2, label [[CASE2:%.*]]
37 ; CHECK-NEXT: i2 -1, label [[CASE3:%.*]]
40 ; CHECK-NEXT: call void @foo(i32 0)
41 ; CHECK-NEXT: ret void
43 ; CHECK-NEXT: call void @foo(i32 1)
44 ; CHECK-NEXT: ret void
46 ; CHECK-NEXT: call void @foo(i32 2)
47 ; CHECK-NEXT: ret void
49 ; CHECK-NEXT: call void @foo(i32 3)
50 ; CHECK-NEXT: ret void
52 ; CHECK-NEXT: unreachable
54 switch i2 %a, label %default [i2 0, label %case0
75 ; This one is a negative test - we know the value of the default,
77 define void @test3(i2 %a) {
78 ; CHECK-LABEL: @test3(
79 ; CHECK-NEXT: switch i2 [[A:%.*]], label [[DEFAULT:%.*]] [
80 ; CHECK-NEXT: i2 0, label [[CASE0:%.*]]
81 ; CHECK-NEXT: i2 1, label [[CASE1:%.*]]
82 ; CHECK-NEXT: i2 -2, label [[CASE2:%.*]]
85 ; CHECK-NEXT: call void @foo(i32 0)
86 ; CHECK-NEXT: ret void
88 ; CHECK-NEXT: call void @foo(i32 1)
89 ; CHECK-NEXT: ret void
91 ; CHECK-NEXT: call void @foo(i32 2)
92 ; CHECK-NEXT: ret void
94 ; CHECK-NEXT: call void @foo(i32 0)
95 ; CHECK-NEXT: ret void
97 switch i2 %a, label %default [i2 0, label %case0
102 call void @foo(i32 0)
105 call void @foo(i32 1)
108 call void @foo(i32 2)
111 call void @foo(i32 0)
115 ; Negative test - check for possible overflow when computing
116 ; number of possible cases.
117 define void @test4(i128 %a) {
118 ; CHECK-LABEL: @test4(
119 ; CHECK-NEXT: switch i128 [[A:%.*]], label [[DEFAULT:%.*]] [
120 ; CHECK-NEXT: i128 0, label [[CASE0:%.*]]
121 ; CHECK-NEXT: i128 1, label [[CASE1:%.*]]
124 ; CHECK-NEXT: call void @foo(i32 0)
125 ; CHECK-NEXT: ret void
127 ; CHECK-NEXT: call void @foo(i32 1)
128 ; CHECK-NEXT: ret void
130 ; CHECK-NEXT: call void @foo(i32 0)
131 ; CHECK-NEXT: ret void
133 switch i128 %a, label %default [i128 0, label %case0
134 i128 1, label %case1]
137 call void @foo(i32 0)
140 call void @foo(i32 1)
143 call void @foo(i32 0)
147 ; All but one bit known zero
148 define void @test5(i8 %a) {
149 ; CHECK-LABEL: @test5(
150 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A:%.*]], 2
151 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
152 ; CHECK-NEXT: [[A_OFF:%.*]] = add i8 [[A]], -1
153 ; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[A_OFF]], 1
154 ; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
156 ; CHECK-NEXT: call void @foo(i32 1)
157 ; CHECK-NEXT: ret void
159 ; CHECK-NEXT: call void @foo(i32 3)
160 ; CHECK-NEXT: ret void
162 %cmp = icmp ult i8 %a, 2
163 call void @llvm.assume(i1 %cmp)
164 switch i8 %a, label %default [i8 1, label %true
167 call void @foo(i32 1)
170 call void @foo(i32 3)
173 call void @foo(i32 2)
177 ;; All but one bit known one
178 define void @test6(i8 %a) {
179 ; CHECK-LABEL: @test6(
180 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[A:%.*]], -2
181 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], -2
182 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
183 ; CHECK-NEXT: [[A_OFF:%.*]] = add i8 [[A]], 1
184 ; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[A_OFF]], 1
185 ; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
187 ; CHECK-NEXT: call void @foo(i32 1)
188 ; CHECK-NEXT: ret void
190 ; CHECK-NEXT: call void @foo(i32 3)
191 ; CHECK-NEXT: ret void
193 %and = and i8 %a, 254
194 %cmp = icmp eq i8 %and, 254
195 call void @llvm.assume(i1 %cmp)
196 switch i8 %a, label %default [i8 255, label %true
197 i8 254, label %false]
199 call void @foo(i32 1)
202 call void @foo(i32 3)
205 call void @foo(i32 2)
209 ; Check that we can eliminate both dead cases and dead defaults
210 ; within a single run of simplify-cfg
211 define void @test7(i8 %a) {
212 ; CHECK-LABEL: @test7(
213 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[A:%.*]], -2
214 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], -2
215 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
216 ; CHECK-NEXT: [[A_OFF:%.*]] = add i8 [[A]], 1
217 ; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[A_OFF]], 1
218 ; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
220 ; CHECK-NEXT: call void @foo(i32 1)
221 ; CHECK-NEXT: ret void
223 ; CHECK-NEXT: call void @foo(i32 3)
224 ; CHECK-NEXT: ret void
226 %and = and i8 %a, 254
227 %cmp = icmp eq i8 %and, 254
228 call void @llvm.assume(i1 %cmp)
229 switch i8 %a, label %default [i8 255, label %true
231 i8 0, label %also_dead]
233 call void @foo(i32 1)
236 call void @foo(i32 3)
239 call void @foo(i32 5)
242 call void @foo(i32 2)
246 declare void @llvm.assume(i1)