blob: e5c2ef65b3181eb39d7744515f26667d18183651 [file] [log] [blame]
Eric Christophercee313d2019-04-17 04:52:47 +00001; 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)