xref: /llvm-project/llvm/test/Transforms/InstCombine/switch-shl.ll (revision 1259c0512292a6559fb073b16056bff2e934822b)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i1 @test_switch_with_shl_mask(i32 %a) {
5; CHECK-LABEL: define i1 @test_switch_with_shl_mask(
6; CHECK-SAME: i32 [[A:%.*]]) {
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[A]] to i8
9; CHECK-NEXT:    switch i8 [[TRUNC]], label [[SW_DEFAULT:%.*]] [
10; CHECK-NEXT:      i8 0, label [[SW_BB:%.*]]
11; CHECK-NEXT:      i8 1, label [[SW_BB]]
12; CHECK-NEXT:      i8 -128, label [[SW_BB]]
13; CHECK-NEXT:    ]
14; CHECK:       sw.bb:
15; CHECK-NEXT:    ret i1 true
16; CHECK:       sw.default:
17; CHECK-NEXT:    ret i1 false
18;
19entry:
20  %b = shl i32 %a, 24
21  switch i32 %b, label %sw.default [
22  i32 0, label %sw.bb
23  i32 16777216, label %sw.bb
24  i32 2147483648, label %sw.bb
25  ]
26
27sw.bb:
28  ret i1 true
29sw.default:
30  ret i1 false
31}
32
33define i1 @test_switch_with_shl_nuw_multiuse(i32 %a) {
34; CHECK-LABEL: define i1 @test_switch_with_shl_nuw_multiuse(
35; CHECK-SAME: i32 [[A:%.*]]) {
36; CHECK-NEXT:  entry:
37; CHECK-NEXT:    [[B:%.*]] = shl nuw i32 [[A]], 24
38; CHECK-NEXT:    call void @use(i32 [[B]])
39; CHECK-NEXT:    switch i32 [[A]], label [[SW_DEFAULT:%.*]] [
40; CHECK-NEXT:      i32 0, label [[SW_BB:%.*]]
41; CHECK-NEXT:      i32 1, label [[SW_BB]]
42; CHECK-NEXT:      i32 128, label [[SW_BB]]
43; CHECK-NEXT:    ]
44; CHECK:       sw.bb:
45; CHECK-NEXT:    ret i1 true
46; CHECK:       sw.default:
47; CHECK-NEXT:    ret i1 false
48;
49entry:
50  %b = shl nuw i32 %a, 24
51  call void @use(i32 %b)
52  switch i32 %b, label %sw.default [
53  i32 0, label %sw.bb
54  i32 16777216, label %sw.bb
55  i32 2147483648, label %sw.bb
56  ]
57
58sw.bb:
59  ret i1 true
60sw.default:
61  ret i1 false
62}
63
64define i1 @test_switch_with_shl_nsw_multiuse(i32 %a) {
65; CHECK-LABEL: define i1 @test_switch_with_shl_nsw_multiuse(
66; CHECK-SAME: i32 [[A:%.*]]) {
67; CHECK-NEXT:  entry:
68; CHECK-NEXT:    [[B:%.*]] = shl nsw i32 [[A]], 24
69; CHECK-NEXT:    call void @use(i32 [[B]])
70; CHECK-NEXT:    switch i32 [[A]], label [[SW_DEFAULT:%.*]] [
71; CHECK-NEXT:      i32 0, label [[SW_BB:%.*]]
72; CHECK-NEXT:      i32 1, label [[SW_BB]]
73; CHECK-NEXT:      i32 -128, label [[SW_BB]]
74; CHECK-NEXT:    ]
75; CHECK:       sw.bb:
76; CHECK-NEXT:    ret i1 true
77; CHECK:       sw.default:
78; CHECK-NEXT:    ret i1 false
79;
80entry:
81  %b = shl nsw i32 %a, 24
82  call void @use(i32 %b)
83  switch i32 %b, label %sw.default [
84  i32 0, label %sw.bb
85  i32 16777216, label %sw.bb
86  i32 2147483648, label %sw.bb
87  ]
88
89sw.bb:
90  ret i1 true
91sw.default:
92  ret i1 false
93}
94
95; Negative tests
96
97define i1 @test_switch_with_shl_mask_multiuse(i32 %a) {
98; CHECK-LABEL: define i1 @test_switch_with_shl_mask_multiuse(
99; CHECK-SAME: i32 [[A:%.*]]) {
100; CHECK-NEXT:  entry:
101; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A]], 24
102; CHECK-NEXT:    call void @use(i32 [[B]])
103; CHECK-NEXT:    switch i32 [[B]], label [[SW_DEFAULT:%.*]] [
104; CHECK-NEXT:      i32 0, label [[SW_BB:%.*]]
105; CHECK-NEXT:      i32 16777216, label [[SW_BB]]
106; CHECK-NEXT:      i32 -2147483648, label [[SW_BB]]
107; CHECK-NEXT:    ]
108; CHECK:       sw.bb:
109; CHECK-NEXT:    ret i1 true
110; CHECK:       sw.default:
111; CHECK-NEXT:    ret i1 false
112;
113entry:
114  %b = shl i32 %a, 24
115  call void @use(i32 %b)
116  switch i32 %b, label %sw.default [
117  i32 0, label %sw.bb
118  i32 16777216, label %sw.bb
119  i32 2147483648, label %sw.bb
120  ]
121
122sw.bb:
123  ret i1 true
124sw.default:
125  ret i1 false
126}
127
128define i1 @test_switch_with_shl_mask_unknown_shamt(i32 %a, i32 %shamt) {
129; CHECK-LABEL: define i1 @test_switch_with_shl_mask_unknown_shamt(
130; CHECK-SAME: i32 [[A:%.*]], i32 [[SHAMT:%.*]]) {
131; CHECK-NEXT:  entry:
132; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A]], [[SHAMT]]
133; CHECK-NEXT:    switch i32 [[B]], label [[SW_DEFAULT:%.*]] [
134; CHECK-NEXT:      i32 0, label [[SW_BB:%.*]]
135; CHECK-NEXT:      i32 16777216, label [[SW_BB]]
136; CHECK-NEXT:      i32 -2147483648, label [[SW_BB]]
137; CHECK-NEXT:    ]
138; CHECK:       sw.bb:
139; CHECK-NEXT:    ret i1 true
140; CHECK:       sw.default:
141; CHECK-NEXT:    ret i1 false
142;
143entry:
144  %b = shl i32 %a, %shamt
145  switch i32 %b, label %sw.default [
146  i32 0, label %sw.bb
147  i32 16777216, label %sw.bb
148  i32 2147483648, label %sw.bb
149  ]
150
151sw.bb:
152  ret i1 true
153sw.default:
154  ret i1 false
155}
156
157define i1 @test_switch_with_shl_mask_poison(i32 %a) {
158; CHECK-LABEL: define i1 @test_switch_with_shl_mask_poison(
159; CHECK-SAME: i32 [[A:%.*]]) {
160; CHECK-NEXT:  entry:
161; CHECK-NEXT:    switch i32 poison, label [[SW_DEFAULT:%.*]] [
162; CHECK-NEXT:      i32 0, label [[SW_BB:%.*]]
163; CHECK-NEXT:      i32 16777216, label [[SW_BB]]
164; CHECK-NEXT:      i32 -2147483648, label [[SW_BB]]
165; CHECK-NEXT:    ]
166; CHECK:       sw.bb:
167; CHECK-NEXT:    ret i1 true
168; CHECK:       sw.default:
169; CHECK-NEXT:    ret i1 false
170;
171entry:
172  %b = shl i32 %a, 32
173  switch i32 %b, label %sw.default [
174  i32 0, label %sw.bb
175  i32 16777216, label %sw.bb
176  i32 2147483648, label %sw.bb
177  ]
178
179sw.bb:
180  ret i1 true
181sw.default:
182  ret i1 false
183}
184
185declare void @use(i32)
186