1
+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2
+ ; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC
3
+ ; RUN: opt < %s -passes=instcombine -S -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=CHECK,CONSTSPLAT
4
+
5
+ define i32 @add_select_cmp_and1 (i32 %in ) {
6
+ ; CHECK-LABEL: @add_select_cmp_and1(
7
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
8
+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
9
+ ; CHECK-NEXT: ret i32 [[OUT]]
10
+ ;
11
+ %bitop0 = and i32 %in , 1
12
+ %cmp0 = icmp eq i32 %bitop0 , 0
13
+ %bitop1 = and i32 %in , 2
14
+ %cmp1 = icmp eq i32 %bitop1 , 0
15
+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
16
+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
17
+ %out = or disjoint i32 %sel0 , %sel1
18
+ ret i32 %out
19
+ }
20
+
21
+ define i32 @add_select_cmp_and2 (i32 %in ) {
22
+ ; CHECK-LABEL: @add_select_cmp_and2(
23
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 5
24
+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
25
+ ; CHECK-NEXT: ret i32 [[OUT]]
26
+ ;
27
+ %bitop0 = and i32 %in , 1
28
+ %cmp0 = icmp eq i32 %bitop0 , 0
29
+ %bitop1 = and i32 %in , 4
30
+ %cmp1 = icmp eq i32 %bitop1 , 0
31
+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
32
+ %sel1 = select i1 %cmp1 , i32 0 , i32 288
33
+ %out = or disjoint i32 %sel0 , %sel1
34
+ ret i32 %out
35
+ }
36
+
37
+ define i32 @add_select_cmp_and3 (i32 %in ) {
38
+ ; CHECK-LABEL: @add_select_cmp_and3(
39
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
40
+ ; CHECK-NEXT: [[TEMP:%.*]] = mul nuw nsw i32 [[TMP1]], 72
41
+ ; CHECK-NEXT: [[BITOP2:%.*]] = and i32 [[IN]], 4
42
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[BITOP2]], 0
43
+ ; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 0, i32 288
44
+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[TEMP]], [[SEL2]]
45
+ ; CHECK-NEXT: ret i32 [[OUT]]
46
+ ;
47
+ %bitop0 = and i32 %in , 1
48
+ %cmp0 = icmp eq i32 %bitop0 , 0
49
+ %bitop1 = and i32 %in , 2
50
+ %cmp1 = icmp eq i32 %bitop1 , 0
51
+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
52
+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
53
+ %temp = or disjoint i32 %sel0 , %sel1
54
+ %bitop2 = and i32 %in , 4
55
+ %cmp2 = icmp eq i32 %bitop2 , 0
56
+ %sel2 = select i1 %cmp2 , i32 0 , i32 288
57
+ %out = or disjoint i32 %temp , %sel2
58
+ ret i32 %out
59
+ }
60
+
61
+ define i32 @add_select_cmp_and4 (i32 %in ) {
62
+ ; CHECK-LABEL: @add_select_cmp_and4(
63
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
64
+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
65
+ ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[IN]], 12
66
+ ; CHECK-NEXT: [[TEMP3:%.*]] = mul nuw nsw i32 [[TMP2]], 72
67
+ ; CHECK-NEXT: [[OUT1:%.*]] = or disjoint i32 [[OUT]], [[TEMP3]]
68
+ ; CHECK-NEXT: ret i32 [[OUT1]]
69
+ ;
70
+ %bitop0 = and i32 %in , 1
71
+ %cmp0 = icmp eq i32 %bitop0 , 0
72
+ %bitop1 = and i32 %in , 2
73
+ %cmp1 = icmp eq i32 %bitop1 , 0
74
+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
75
+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
76
+ %temp = or disjoint i32 %sel0 , %sel1
77
+ %bitop2 = and i32 %in , 4
78
+ %cmp2 = icmp eq i32 %bitop2 , 0
79
+ %bitop3 = and i32 %in , 8
80
+ %cmp3 = icmp eq i32 %bitop3 , 0
81
+ %sel2 = select i1 %cmp2 , i32 0 , i32 288
82
+ %sel3 = select i1 %cmp3 , i32 0 , i32 576
83
+ %temp2 = or disjoint i32 %sel2 , %sel3
84
+ %out = or disjoint i32 %temp , %temp2
85
+ ret i32 %out
86
+ }
87
+
88
+ define i32 @add_select_cmp_and_pred1 (i32 %in ) {
89
+ ; CHECK-LABEL: @add_select_cmp_and_pred1(
90
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
91
+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
92
+ ; CHECK-NEXT: ret i32 [[OUT]]
93
+ ;
94
+ %bitop0 = and i32 %in , 1
95
+ %cmp0 = icmp ne i32 %bitop0 , 0
96
+ %bitop1 = and i32 %in , 2
97
+ %cmp1 = icmp eq i32 %bitop1 , 0
98
+ %sel0 = select i1 %cmp0 , i32 72 , i32 0
99
+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
100
+ %out = or disjoint i32 %sel0 , %sel1
101
+ ret i32 %out
102
+ }
103
+
104
+ define i32 @add_select_cmp_and_pred2 (i32 %in ) {
105
+ ; CHECK-LABEL: @add_select_cmp_and_pred2(
106
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
107
+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
108
+ ; CHECK-NEXT: ret i32 [[OUT]]
109
+ ;
110
+ %bitop0 = and i32 %in , 1
111
+ %cmp0 = icmp eq i32 %bitop0 , 0
112
+ %bitop1 = and i32 %in , 2
113
+ %cmp1 = icmp ne i32 %bitop1 , 0
114
+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
115
+ %sel1 = select i1 %cmp1 , i32 144 , i32 0
116
+ %out = or disjoint i32 %sel0 , %sel1
117
+ ret i32 %out
118
+ }
119
+
120
+ define i32 @add_select_cmp_and_pred3 (i32 %in ) {
121
+ ; CHECK-LABEL: @add_select_cmp_and_pred3(
122
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
123
+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
124
+ ; CHECK-NEXT: ret i32 [[OUT]]
125
+ ;
126
+ %bitop0 = and i32 %in , 1
127
+ %cmp0 = icmp ne i32 %bitop0 , 0
128
+ %bitop1 = and i32 %in , 2
129
+ %cmp1 = icmp ne i32 %bitop1 , 0
130
+ %sel0 = select i1 %cmp0 , i32 72 , i32 0
131
+ %sel1 = select i1 %cmp1 , i32 144 , i32 0
132
+ %out = or disjoint i32 %sel0 , %sel1
133
+ ret i32 %out
134
+ }
135
+
136
+ define i32 @add_select_cmp_trunc (i32 %in ) {
137
+ ; CHECK-LABEL: @add_select_cmp_trunc(
138
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
139
+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
140
+ ; CHECK-NEXT: ret i32 [[OUT]]
141
+ ;
142
+ %cmp0 = trunc i32 %in to i1
143
+ %bitop1 = and i32 %in , 2
144
+ %cmp1 = icmp eq i32 %bitop1 , 0
145
+ %sel0 = select i1 %cmp0 , i32 72 , i32 0
146
+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
147
+ %out = or disjoint i32 %sel0 , %sel1
148
+ ret i32 %out
149
+ }
150
+
151
+ define i32 @add_select_cmp_trunc1 (i32 %in ) {
152
+ ; CHECK-LABEL: @add_select_cmp_trunc1(
153
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
154
+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
155
+ ; CHECK-NEXT: ret i32 [[OUT]]
156
+ ;
157
+ %cmp0 = trunc i32 %in to i1
158
+ %bitop1 = and i32 %in , 2
159
+ %cmp1 = icmp ne i32 %bitop1 , 0
160
+ %sel0 = select i1 %cmp0 , i32 72 , i32 0
161
+ %sel1 = select i1 %cmp1 , i32 144 , i32 0
162
+ %out = or disjoint i32 %sel0 , %sel1
163
+ ret i32 %out
164
+ }
165
+
166
+
167
+ define i32 @add_select_cmp_and_const_mismatch (i32 %in ) {
168
+ ; CHECK-LABEL: @add_select_cmp_and_const_mismatch(
169
+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
170
+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
171
+ ; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 2
172
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
173
+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
174
+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 288
175
+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
176
+ ; CHECK-NEXT: ret i32 [[OUT]]
177
+ ;
178
+ %bitop0 = and i32 %in , 1
179
+ %cmp0 = icmp eq i32 %bitop0 , 0
180
+ %bitop1 = and i32 %in , 2
181
+ %cmp1 = icmp eq i32 %bitop1 , 0
182
+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
183
+ %sel1 = select i1 %cmp1 , i32 0 , i32 288
184
+ %out = or disjoint i32 %sel0 , %sel1
185
+ ret i32 %out
186
+ }
187
+
188
+ define i32 @add_select_cmp_and_value_mismatch (i32 %in , i32 %in1 ) {
189
+ ; CHECK-LABEL: @add_select_cmp_and_value_mismatch(
190
+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
191
+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
192
+ ; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN1:%.*]], 2
193
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
194
+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
195
+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 144
196
+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
197
+ ; CHECK-NEXT: ret i32 [[OUT]]
198
+ ;
199
+ %bitop0 = and i32 %in , 1
200
+ %cmp0 = icmp eq i32 %bitop0 , 0
201
+ %bitop1 = and i32 %in1 , 2
202
+ %cmp1 = icmp eq i32 %bitop1 , 0
203
+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
204
+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
205
+ %out = or disjoint i32 %sel0 , %sel1
206
+ ret i32 %out
207
+ }
208
+
209
+ define i32 @add_select_cmp_and_negative (i32 %in ) {
210
+ ; CHECK-LABEL: @add_select_cmp_and_negative(
211
+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
212
+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
213
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[IN]], 2
214
+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
215
+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 -144
216
+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
217
+ ; CHECK-NEXT: ret i32 [[OUT]]
218
+ ;
219
+ %bitop0 = and i32 %in , 1
220
+ %cmp0 = icmp eq i32 %bitop0 , 0
221
+ %bitop1 = and i32 %in , -2
222
+ %cmp1 = icmp eq i32 %bitop1 , 0
223
+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
224
+ %sel1 = select i1 %cmp1 , i32 0 , i32 -144
225
+ %out = or disjoint i32 %sel0 , %sel1
226
+ ret i32 %out
227
+ }
228
+
229
+ define i32 @add_select_cmp_and_bitsel_overlap (i32 %in ) {
230
+ ; CHECK-LABEL: @add_select_cmp_and_bitsel_overlap(
231
+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 2
232
+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
233
+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 144
234
+ ; CHECK-NEXT: ret i32 [[SEL0]]
235
+ ;
236
+ %bitop0 = and i32 %in , 2
237
+ %cmp0 = icmp eq i32 %bitop0 , 0
238
+ %bitop1 = and i32 %in , 2
239
+ %cmp1 = icmp eq i32 %bitop1 , 0
240
+ %sel0 = select i1 %cmp0 , i32 0 , i32 144
241
+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
242
+ %out = or disjoint i32 %sel0 , %sel1
243
+ ret i32 %out
244
+ }
245
+
246
+ ; We cannot combine into and-mul, as %bitop1 may not be exactly 6
247
+
248
+ define i32 @add_select_cmp_and_multbit_mask (i32 %in ) {
249
+ ; CHECK-LABEL: @add_select_cmp_and_multbit_mask(
250
+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
251
+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
252
+ ; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 6
253
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
254
+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
255
+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 432
256
+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
257
+ ; CHECK-NEXT: ret i32 [[OUT]]
258
+ ;
259
+ %bitop0 = and i32 %in , 1
260
+ %cmp0 = icmp eq i32 %bitop0 , 0
261
+ %bitop1 = and i32 %in , 6
262
+ %cmp1 = icmp eq i32 %bitop1 , 0
263
+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
264
+ %sel1 = select i1 %cmp1 , i32 0 , i32 432
265
+ %out = or disjoint i32 %sel0 , %sel1
266
+ ret i32 %out
267
+ }
268
+
269
+
270
+ define <2 x i32 > @add_select_cmp_vec (<2 x i32 > %in ) {
271
+ ; CHECK-LABEL: @add_select_cmp_vec(
272
+ ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[IN:%.*]], splat (i32 3)
273
+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw <2 x i32> [[TMP1]], splat (i32 72)
274
+ ; CHECK-NEXT: ret <2 x i32> [[OUT]]
275
+ ;
276
+ %bitop0 = and <2 x i32 > %in , <i32 1 , i32 1 >
277
+ %cmp0 = icmp eq <2 x i32 > %bitop0 , <i32 0 , i32 0 >
278
+ %bitop1 = and <2 x i32 > %in , <i32 2 , i32 2 >
279
+ %cmp1 = icmp eq <2 x i32 > %bitop1 , <i32 0 , i32 0 >
280
+ %sel0 = select <2 x i1 > %cmp0 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 72 , i32 72 >
281
+ %sel1 = select <2 x i1 > %cmp1 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 144 , i32 144 >
282
+ %out = or disjoint <2 x i32 > %sel0 , %sel1
283
+ ret <2 x i32 > %out
284
+ }
285
+
286
+ define <2 x i32 > @add_select_cmp_vec_poison (<2 x i32 > %in ) {
287
+ ; CHECK-LABEL: @add_select_cmp_vec_poison(
288
+ ; CHECK-NEXT: [[BITOP0:%.*]] = and <2 x i32> [[IN:%.*]], splat (i32 1)
289
+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i32> [[BITOP0]], zeroinitializer
290
+ ; CHECK-NEXT: [[BITOP1:%.*]] = and <2 x i32> [[IN]], splat (i32 2)
291
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[BITOP1]], zeroinitializer
292
+ ; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> <i32 poison, i32 144>
293
+ ; CHECK-NEXT: [[OUT:%.*]] = select <2 x i1> [[CMP0]], <2 x i32> [[SEL1]], <2 x i32> <i32 72, i32 poison>
294
+ ; CHECK-NEXT: ret <2 x i32> [[OUT]]
295
+ ;
296
+ %bitop0 = and <2 x i32 > %in , <i32 1 , i32 1 >
297
+ %cmp0 = icmp eq <2 x i32 > %bitop0 , <i32 0 , i32 0 >
298
+ %bitop1 = and <2 x i32 > %in , <i32 2 , i32 2 >
299
+ %cmp1 = icmp eq <2 x i32 > %bitop1 , <i32 0 , i32 0 >
300
+ %sel0 = select <2 x i1 > %cmp0 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 72 , i32 poison>
301
+ %sel1 = select <2 x i1 > %cmp1 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 poison, i32 144 >
302
+ %out = or disjoint <2 x i32 > %sel0 , %sel1
303
+ ret <2 x i32 > %out
304
+ }
305
+
306
+ define <2 x i32 > @add_select_cmp_vec_nonunique (<2 x i32 > %in ) {
307
+ ; CHECK-LABEL: @add_select_cmp_vec_nonunique(
308
+ ; CHECK-NEXT: [[BITOP0:%.*]] = and <2 x i32> [[IN:%.*]], <i32 1, i32 2>
309
+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i32> [[BITOP0]], zeroinitializer
310
+ ; CHECK-NEXT: [[BITOP1:%.*]] = and <2 x i32> [[IN]], <i32 4, i32 8>
311
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[BITOP1]], zeroinitializer
312
+ ; CHECK-NEXT: [[SEL0:%.*]] = select <2 x i1> [[CMP0]], <2 x i32> zeroinitializer, <2 x i32> <i32 72, i32 144>
313
+ ; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> <i32 288, i32 576>
314
+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint <2 x i32> [[SEL0]], [[SEL1]]
315
+ ; CHECK-NEXT: ret <2 x i32> [[OUT]]
316
+ ;
317
+ %bitop0 = and <2 x i32 > %in , <i32 1 , i32 2 >
318
+ %cmp0 = icmp eq <2 x i32 > %bitop0 , <i32 0 , i32 0 >
319
+ %bitop1 = and <2 x i32 > %in , <i32 4 , i32 8 >
320
+ %cmp1 = icmp eq <2 x i32 > %bitop1 , <i32 0 , i32 0 >
321
+ %sel0 = select <2 x i1 > %cmp0 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 72 , i32 144 >
322
+ %sel1 = select <2 x i1 > %cmp1 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 288 , i32 576 >
323
+ %out = or disjoint <2 x i32 > %sel0 , %sel1
324
+ ret <2 x i32 > %out
325
+ }
326
+ ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
327
+ ; CONSTSPLAT: {{.*}}
328
+ ; CONSTVEC: {{.*}}
0 commit comments