1; RUN: opt %s -S -simplifycfg | FileCheck %s
2declare void @foo(i32)
3
4define void @test(i1 %a) {
5; CHECK-LABEL: @test
6; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
7  switch i1 %a, label %default [i1 1, label %true
8                                i1 0, label %false]
9true:
10  call void @foo(i32 1)
11  ret void
12false:
13  call void @foo(i32 3)
14  ret void
15default:
16  call void @foo(i32 2)
17  ret void
18}
19
20define void @test2(i2 %a) {
21; CHECK-LABEL: @test2
22  switch i2 %a, label %default [i2 0, label %case0
23                                i2 1, label %case1
24                                i2 2, label %case2
25                                i2 3, label %case3]
26case0:
27  call void @foo(i32 0)
28  ret void
29case1:
30  call void @foo(i32 1)
31  ret void
32case2:
33  call void @foo(i32 2)
34  ret void
35case3:
36  call void @foo(i32 3)
37  ret void
38default:
39; CHECK-LABEL: default1:
40; CHECK-NEXT: unreachable
41  call void @foo(i32 4)
42  ret void
43}
44
45; This one is a negative test - we know the value of the default,
46; but that's about it
47define void @test3(i2 %a) {
48; CHECK-LABEL: @test3
49  switch i2 %a, label %default [i2 0, label %case0
50                                i2 1, label %case1
51                                i2 2, label %case2]
52
53case0:
54  call void @foo(i32 0)
55  ret void
56case1:
57  call void @foo(i32 1)
58  ret void
59case2:
60  call void @foo(i32 2)
61  ret void
62default:
63; CHECK-LABEL: default:
64; CHECK-NEXT: call void @foo
65  call void @foo(i32 0)
66  ret void
67}
68
69; Negative test - check for possible overflow when computing
70; number of possible cases.
71define void @test4(i128 %a) {
72; CHECK-LABEL: @test4
73  switch i128 %a, label %default [i128 0, label %case0
74                                  i128 1, label %case1]
75
76case0:
77  call void @foo(i32 0)
78  ret void
79case1:
80  call void @foo(i32 1)
81  ret void
82default:
83; CHECK-LABEL: default:
84; CHECK-NEXT: call void @foo
85  call void @foo(i32 0)
86  ret void
87}
88
89; All but one bit known zero
90define void @test5(i8 %a) {
91; CHECK-LABEL: @test5
92; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
93  %cmp = icmp ult i8 %a, 2
94  call void @llvm.assume(i1 %cmp)
95  switch i8 %a, label %default [i8 1, label %true
96                                i8 0, label %false]
97true:
98  call void @foo(i32 1)
99  ret void
100false:
101  call void @foo(i32 3)
102  ret void
103default:
104  call void @foo(i32 2)
105  ret void
106}
107
108;; All but one bit known one
109define void @test6(i8 %a) {
110; CHECK-LABEL: @test6
111; CHECK: @llvm.assume
112; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
113  %and = and i8 %a, 254
114  %cmp = icmp eq i8 %and, 254
115  call void @llvm.assume(i1 %cmp)
116  switch i8 %a, label %default [i8 255, label %true
117                                i8 254, label %false]
118true:
119  call void @foo(i32 1)
120  ret void
121false:
122  call void @foo(i32 3)
123  ret void
124default:
125  call void @foo(i32 2)
126  ret void
127}
128
129; Check that we can eliminate both dead cases and dead defaults
130; within a single run of simplify-cfg
131define void @test7(i8 %a) {
132; CHECK-LABEL: @test7
133; CHECK: @llvm.assume
134; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
135  %and = and i8 %a, 254
136  %cmp = icmp eq i8 %and, 254
137  call void @llvm.assume(i1 %cmp)
138  switch i8 %a, label %default [i8 255, label %true
139                                i8 254, label %false
140                                i8 0, label %also_dead]
141true:
142  call void @foo(i32 1)
143  ret void
144false:
145  call void @foo(i32 3)
146  ret void
147also_dead:
148  call void @foo(i32 5)
149  ret void
150default:
151  call void @foo(i32 2)
152  ret void
153}
154
155;; All but one bit known undef
156;; Note: This is currently testing an optimization which doesn't trigger. The
157;; case this is protecting against is that a bit could be assumed both zero
158;; *or* one given we know it's undef.  ValueTracking doesn't do this today,
159;; but it doesn't hurt to confirm.
160define void @test8(i8 %a) {
161; CHECK-LABEL: @test8(
162; CHECK: switch i8
163  %and = and i8 %a, 254
164  %cmp = icmp eq i8 %and, undef
165  call void @llvm.assume(i1 %cmp)
166  switch i8 %a, label %default [i8 255, label %true
167                                i8 254, label %false]
168true:
169  call void @foo(i32 1)
170  ret void
171false:
172  call void @foo(i32 3)
173  ret void
174default:
175  call void @foo(i32 2)
176  ret void
177}
178
179declare void @llvm.assume(i1)
180