[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / fsh.ll
blob49a8ef07d7f43faa539cff14a323920e3e860b78
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare i32 @llvm.fshl.i32(i32, i32, i32)
5 declare i33 @llvm.fshr.i33(i33, i33, i33)
6 declare <2 x i32> @llvm.fshr.v2i32(<2 x i32>, <2 x i32>, <2 x i32>)
7 declare <2 x i31> @llvm.fshl.v2i31(<2 x i31>, <2 x i31>, <2 x i31>)
9 ; If the shift mask doesn't include any demanded bits, the funnel shift can be eliminated.
11 define i32 @fshl_mask_simplify1(i32 %x, i32 %y, i32 %sh) {
12 ; CHECK-LABEL: @fshl_mask_simplify1(
13 ; CHECK-NEXT:    ret i32 [[X:%.*]]
15   %maskedsh = and i32 %sh, 32
16   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
17   ret i32 %r
20 define <2 x i32> @fshr_mask_simplify2(<2 x i32> %x, <2 x i32> %y, <2 x i32> %sh) {
21 ; CHECK-LABEL: @fshr_mask_simplify2(
22 ; CHECK-NEXT:    ret <2 x i32> [[Y:%.*]]
24   %maskedsh = and <2 x i32> %sh, <i32 64, i32 64>
25   %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %maskedsh)
26   ret <2 x i32> %r
29 ; Negative test.
31 define i32 @fshl_mask_simplify3(i32 %x, i32 %y, i32 %sh) {
32 ; CHECK-LABEL: @fshl_mask_simplify3(
33 ; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 16
34 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])
35 ; CHECK-NEXT:    ret i32 [[R]]
37   %maskedsh = and i32 %sh, 16
38   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
39   ret i32 %r
42 ; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.
44 define i33 @fshr_mask_simplify1(i33 %x, i33 %y, i33 %sh) {
45 ; CHECK-LABEL: @fshr_mask_simplify1(
46 ; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i33 [[SH:%.*]], 64
47 ; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshr.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 [[MASKEDSH]])
48 ; CHECK-NEXT:    ret i33 [[R]]
50   %maskedsh = and i33 %sh, 64
51   %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %maskedsh)
52   ret i33 %r
55 ; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.
57 define <2 x i31> @fshl_mask_simplify2(<2 x i31> %x, <2 x i31> %y, <2 x i31> %sh) {
58 ; CHECK-LABEL: @fshl_mask_simplify2(
59 ; CHECK-NEXT:    [[MASKEDSH:%.*]] = and <2 x i31> [[SH:%.*]], <i31 32, i31 32>
60 ; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> [[MASKEDSH]])
61 ; CHECK-NEXT:    ret <2 x i31> [[R]]
63   %maskedsh = and <2 x i31> %sh, <i31 32, i31 32>
64   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> %maskedsh)
65   ret <2 x i31> %r
68 ; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.
70 define i33 @fshr_mask_simplify3(i33 %x, i33 %y, i33 %sh) {
71 ; CHECK-LABEL: @fshr_mask_simplify3(
72 ; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i33 [[SH:%.*]], 32
73 ; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshr.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 [[MASKEDSH]])
74 ; CHECK-NEXT:    ret i33 [[R]]
76   %maskedsh = and i33 %sh, 32
77   %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %maskedsh)
78   ret i33 %r
81 ; This mask op is unnecessary.
83 define i32 @fshl_mask_not_required(i32 %x, i32 %y, i32 %sh) {
84 ; CHECK-LABEL: @fshl_mask_not_required(
85 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[SH:%.*]])
86 ; CHECK-NEXT:    ret i32 [[R]]
88   %maskedsh = and i32 %sh, 31
89   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
90   ret i32 %r
93 ; This mask op can be reduced.
95 define i32 @fshl_mask_reduce_constant(i32 %x, i32 %y, i32 %sh) {
96 ; CHECK-LABEL: @fshl_mask_reduce_constant(
97 ; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 1
98 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])
99 ; CHECK-NEXT:    ret i32 [[R]]
101   %maskedsh = and i32 %sh, 33
102   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
103   ret i32 %r
106 ; But this mask op is required.
108 define i32 @fshl_mask_negative(i32 %x, i32 %y, i32 %sh) {
109 ; CHECK-LABEL: @fshl_mask_negative(
110 ; CHECK-NEXT:    [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 15
111 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])
112 ; CHECK-NEXT:    ret i32 [[R]]
114   %maskedsh = and i32 %sh, 15
115   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
116   ret i32 %r
119 ; The transform is not limited to mask ops.
121 define <2 x i32> @fshr_set_but_not_demanded_vec(<2 x i32> %x, <2 x i32> %y, <2 x i32> %sh) {
122 ; CHECK-LABEL: @fshr_set_but_not_demanded_vec(
123 ; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> [[SH:%.*]])
124 ; CHECK-NEXT:    ret <2 x i32> [[R]]
126   %bogusbits = or <2 x i32> %sh, <i32 32, i32 32>
127   %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %bogusbits)
128   ret <2 x i32> %r
131 ; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.
133 define <2 x i31> @fshl_set_but_not_demanded_vec(<2 x i31> %x, <2 x i31> %y, <2 x i31> %sh) {
134 ; CHECK-LABEL: @fshl_set_but_not_demanded_vec(
135 ; CHECK-NEXT:    [[BOGUSBITS:%.*]] = or <2 x i31> [[SH:%.*]], <i31 32, i31 32>
136 ; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> [[BOGUSBITS]])
137 ; CHECK-NEXT:    ret <2 x i31> [[R]]
139   %bogusbits = or <2 x i31> %sh, <i31 32, i31 32>
140   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> %bogusbits)
141   ret <2 x i31> %r
144 ; Simplify one undef or zero operand and constant shift amount.
146 define i32 @fshl_op0_undef(i32 %x) {
147 ; CHECK-LABEL: @fshl_op0_undef(
148 ; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[X:%.*]], 25
149 ; CHECK-NEXT:    ret i32 [[R]]
151   %r = call i32 @llvm.fshl.i32(i32 undef, i32 %x, i32 7)
152   ret i32 %r
155 define i32 @fshl_op0_zero(i32 %x) {
156 ; CHECK-LABEL: @fshl_op0_zero(
157 ; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[X:%.*]], 25
158 ; CHECK-NEXT:    ret i32 [[R]]
160   %r = call i32 @llvm.fshl.i32(i32 0, i32 %x, i32 7)
161   ret i32 %r
164 define i33 @fshr_op0_undef(i33 %x) {
165 ; CHECK-LABEL: @fshr_op0_undef(
166 ; CHECK-NEXT:    [[R:%.*]] = lshr i33 [[X:%.*]], 7
167 ; CHECK-NEXT:    ret i33 [[R]]
169   %r = call i33 @llvm.fshr.i33(i33 undef, i33 %x, i33 7)
170   ret i33 %r
173 define i33 @fshr_op0_zero(i33 %x) {
174 ; CHECK-LABEL: @fshr_op0_zero(
175 ; CHECK-NEXT:    [[R:%.*]] = lshr i33 [[X:%.*]], 7
176 ; CHECK-NEXT:    ret i33 [[R]]
178   %r = call i33 @llvm.fshr.i33(i33 0, i33 %x, i33 7)
179   ret i33 %r
182 define i32 @fshl_op1_undef(i32 %x) {
183 ; CHECK-LABEL: @fshl_op1_undef(
184 ; CHECK-NEXT:    [[R:%.*]] = shl i32 [[X:%.*]], 7
185 ; CHECK-NEXT:    ret i32 [[R]]
187   %r = call i32 @llvm.fshl.i32(i32 %x, i32 undef, i32 7)
188   ret i32 %r
191 define i32 @fshl_op1_zero(i32 %x) {
192 ; CHECK-LABEL: @fshl_op1_zero(
193 ; CHECK-NEXT:    [[R:%.*]] = shl i32 [[X:%.*]], 7
194 ; CHECK-NEXT:    ret i32 [[R]]
196   %r = call i32 @llvm.fshl.i32(i32 %x, i32 0, i32 7)
197   ret i32 %r
200 define i33 @fshr_op1_undef(i33 %x) {
201 ; CHECK-LABEL: @fshr_op1_undef(
202 ; CHECK-NEXT:    [[R:%.*]] = shl i33 [[X:%.*]], 26
203 ; CHECK-NEXT:    ret i33 [[R]]
205   %r = call i33 @llvm.fshr.i33(i33 %x, i33 undef, i33 7)
206   ret i33 %r
209 define i33 @fshr_op1_zero(i33 %x) {
210 ; CHECK-LABEL: @fshr_op1_zero(
211 ; CHECK-NEXT:    [[R:%.*]] = shl i33 [[X:%.*]], 26
212 ; CHECK-NEXT:    ret i33 [[R]]
214   %r = call i33 @llvm.fshr.i33(i33 %x, i33 0, i33 7)
215   ret i33 %r
218 define <2 x i31> @fshl_op0_zero_splat_vec(<2 x i31> %x) {
219 ; CHECK-LABEL: @fshl_op0_zero_splat_vec(
220 ; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i31> [[X:%.*]], <i31 24, i31 24>
221 ; CHECK-NEXT:    ret <2 x i31> [[R]]
223   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> zeroinitializer, <2 x i31> %x, <2 x i31> <i31 7, i31 7>)
224   ret <2 x i31> %r
227 define <2 x i31> @fshl_op1_undef_splat_vec(<2 x i31> %x) {
228 ; CHECK-LABEL: @fshl_op1_undef_splat_vec(
229 ; CHECK-NEXT:    [[R:%.*]] = shl <2 x i31> [[X:%.*]], <i31 7, i31 7>
230 ; CHECK-NEXT:    ret <2 x i31> [[R]]
232   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> undef, <2 x i31> <i31 7, i31 7>)
233   ret <2 x i31> %r
236 define <2 x i32> @fshr_op0_undef_splat_vec(<2 x i32> %x) {
237 ; CHECK-LABEL: @fshr_op0_undef_splat_vec(
238 ; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 7, i32 7>
239 ; CHECK-NEXT:    ret <2 x i32> [[R]]
241   %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> undef, <2 x i32> %x, <2 x i32> <i32 7, i32 7>)
242   ret <2 x i32> %r
245 define <2 x i32> @fshr_op1_zero_splat_vec(<2 x i32> %x) {
246 ; CHECK-LABEL: @fshr_op1_zero_splat_vec(
247 ; CHECK-NEXT:    [[R:%.*]] = shl <2 x i32> [[X:%.*]], <i32 25, i32 25>
248 ; CHECK-NEXT:    ret <2 x i32> [[R]]
250   %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> zeroinitializer, <2 x i32> <i32 7, i32 7>)
251   ret <2 x i32> %r
254 define <2 x i31> @fshl_op0_zero_vec(<2 x i31> %x) {
255 ; CHECK-LABEL: @fshl_op0_zero_vec(
256 ; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i31> [[X:%.*]], <i31 30, i31 29>
257 ; CHECK-NEXT:    ret <2 x i31> [[R]]
259   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> zeroinitializer, <2 x i31> %x, <2 x i31> <i31 -1, i31 33>)
260   ret <2 x i31> %r
263 define <2 x i31> @fshl_op1_undef_vec(<2 x i31> %x) {
264 ; CHECK-LABEL: @fshl_op1_undef_vec(
265 ; CHECK-NEXT:    [[R:%.*]] = shl <2 x i31> [[X:%.*]], <i31 1, i31 2>
266 ; CHECK-NEXT:    ret <2 x i31> [[R]]
268   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> undef, <2 x i31> <i31 -1, i31 33>)
269   ret <2 x i31> %r
272 define <2 x i32> @fshr_op0_undef_vec(<2 x i32> %x) {
273 ; CHECK-LABEL: @fshr_op0_undef_vec(
274 ; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 1>
275 ; CHECK-NEXT:    ret <2 x i32> [[R]]
277   %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> undef, <2 x i32> %x, <2 x i32> <i32 -1, i32 33>)
278   ret <2 x i32> %r
281 define <2 x i32> @fshr_op1_zero_vec(<2 x i32> %x) {
282 ; CHECK-LABEL: @fshr_op1_zero_vec(
283 ; CHECK-NEXT:    [[R:%.*]] = shl <2 x i32> [[X:%.*]], <i32 1, i32 31>
284 ; CHECK-NEXT:    ret <2 x i32> [[R]]
286   %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> zeroinitializer, <2 x i32> <i32 -1, i32 33>)
287   ret <2 x i32> %r
290 ; Only demand bits from one of the operands.
292 define i32 @fshl_only_op0_demanded(i32 %x, i32 %y) {
293 ; CHECK-LABEL: @fshl_only_op0_demanded(
294 ; CHECK-NEXT:    [[Z:%.*]] = shl i32 [[X:%.*]], 7
295 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[Z]], 128
296 ; CHECK-NEXT:    ret i32 [[R]]
298   %z = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)
299   %r = and i32 %z, 128
300   ret i32 %r
303 define i32 @fshl_only_op1_demanded(i32 %x, i32 %y) {
304 ; CHECK-LABEL: @fshl_only_op1_demanded(
305 ; CHECK-NEXT:    [[Z:%.*]] = lshr i32 [[Y:%.*]], 25
306 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[Z]], 63
307 ; CHECK-NEXT:    ret i32 [[R]]
309   %z = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)
310   %r = and i32 %z, 63
311   ret i32 %r
314 define i33 @fshr_only_op1_demanded(i33 %x, i33 %y) {
315 ; CHECK-LABEL: @fshr_only_op1_demanded(
316 ; CHECK-NEXT:    [[Z:%.*]] = lshr i33 [[Y:%.*]], 7
317 ; CHECK-NEXT:    [[R:%.*]] = and i33 [[Z]], 12392
318 ; CHECK-NEXT:    ret i33 [[R]]
320   %z = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 7)
321   %r = and i33 %z, 12392
322   ret i33 %r
325 define i33 @fshr_only_op0_demanded(i33 %x, i33 %y) {
326 ; CHECK-LABEL: @fshr_only_op0_demanded(
327 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i33 [[X:%.*]], 4
328 ; CHECK-NEXT:    [[R:%.*]] = and i33 [[TMP1]], 7
329 ; CHECK-NEXT:    ret i33 [[R]]
331   %z = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 7)
332   %r = lshr i33 %z, 30
333   ret i33 %r
336 define <2 x i31> @fshl_only_op1_demanded_vec_splat(<2 x i31> %x, <2 x i31> %y) {
337 ; CHECK-LABEL: @fshl_only_op1_demanded_vec_splat(
338 ; CHECK-NEXT:    [[Z:%.*]] = lshr <2 x i31> [[Y:%.*]], <i31 24, i31 24>
339 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i31> [[Z]], <i31 63, i31 31>
340 ; CHECK-NEXT:    ret <2 x i31> [[R]]
342   %z = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 7, i31 7>)
343   %r = and <2 x i31> %z, <i31 63, i31 31>
344   ret <2 x i31> %r
347 define i32 @fshl_constant_shift_amount_modulo_bitwidth(i32 %x, i32 %y) {
348 ; CHECK-LABEL: @fshl_constant_shift_amount_modulo_bitwidth(
349 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 1)
350 ; CHECK-NEXT:    ret i32 [[R]]
352   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 33)
353   ret i32 %r
356 define i33 @fshr_constant_shift_amount_modulo_bitwidth(i33 %x, i33 %y) {
357 ; CHECK-LABEL: @fshr_constant_shift_amount_modulo_bitwidth(
358 ; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 32)
359 ; CHECK-NEXT:    ret i33 [[R]]
361   %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 34)
362   ret i33 %r
365 define i32 @fshl_undef_shift_amount(i32 %x, i32 %y) {
366 ; CHECK-LABEL: @fshl_undef_shift_amount(
367 ; CHECK-NEXT:    ret i32 [[X:%.*]]
369   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 undef)
370   ret i32 %r
373 define i33 @fshr_undef_shift_amount(i33 %x, i33 %y) {
374 ; CHECK-LABEL: @fshr_undef_shift_amount(
375 ; CHECK-NEXT:    ret i33 [[Y:%.*]]
377   %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 undef)
378   ret i33 %r
381 @external_global = external global i8
383 define i33 @fshr_constant_shift_amount_modulo_bitwidth_constexpr(i33 %x, i33 %y) {
384 ; CHECK-LABEL: @fshr_constant_shift_amount_modulo_bitwidth_constexpr(
385 ; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshr.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 ptrtoint (i8* @external_global to i33))
386 ; CHECK-NEXT:    ret i33 [[R]]
388   %shamt = ptrtoint i8* @external_global to i33
389   %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %shamt)
390   ret i33 %r
393 define <2 x i32> @fshr_constant_shift_amount_modulo_bitwidth_vec(<2 x i32> %x, <2 x i32> %y) {
394 ; CHECK-LABEL: @fshr_constant_shift_amount_modulo_bitwidth_vec(
395 ; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.fshl.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 30, i32 1>)
396 ; CHECK-NEXT:    ret <2 x i32> [[R]]
398   %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> <i32 34, i32 -1>)
399   ret <2 x i32> %r
402 define <2 x i31> @fshl_constant_shift_amount_modulo_bitwidth_vec(<2 x i31> %x, <2 x i31> %y) {
403 ; CHECK-LABEL: @fshl_constant_shift_amount_modulo_bitwidth_vec(
404 ; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> <i31 3, i31 1>)
405 ; CHECK-NEXT:    ret <2 x i31> [[R]]
407   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 34, i31 -1>)
408   ret <2 x i31> %r
411 define <2 x i31> @fshl_constant_shift_amount_modulo_bitwidth_vec_const_expr(<2 x i31> %x, <2 x i31> %y) {
412 ; CHECK-LABEL: @fshl_constant_shift_amount_modulo_bitwidth_vec_const_expr(
413 ; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> <i31 34, i31 ptrtoint (i8* @external_global to i31)>)
414 ; CHECK-NEXT:    ret <2 x i31> [[R]]
416   %shamt = ptrtoint i8* @external_global to i31
417   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 34, i31 ptrtoint (i8* @external_global to i31)>)
418   ret <2 x i31> %r
421 define <2 x i31> @fshl_undef_shift_amount_vec(<2 x i31> %x, <2 x i31> %y) {
422 ; CHECK-LABEL: @fshl_undef_shift_amount_vec(
423 ; CHECK-NEXT:    ret <2 x i31> [[X:%.*]]
425   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> undef)
426   ret <2 x i31> %r
429 define <2 x i32> @fshr_undef_shift_amount_vec(<2 x i32> %x, <2 x i32> %y) {
430 ; CHECK-LABEL: @fshr_undef_shift_amount_vec(
431 ; CHECK-NEXT:    ret <2 x i32> [[Y:%.*]]
433   %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> undef)
434   ret <2 x i32> %r
437 ; TODO: Don't let SimplifyDemandedBits split up a rotate - keep the same operand.
439 define i32 @rotl_common_demanded(i32 %a0) {
440 ; CHECK-LABEL: @rotl_common_demanded(
441 ; CHECK-NEXT:    [[X:%.*]] = xor i32 [[A0:%.*]], 2
442 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[A0]], i32 8)
443 ; CHECK-NEXT:    ret i32 [[R]]
445   %x = xor i32 %a0, 2
446   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 8)
447   ret i32 %r
450 define i33 @rotr_common_demanded(i33 %a0) {
451 ; CHECK-LABEL: @rotr_common_demanded(
452 ; CHECK-NEXT:    [[X:%.*]] = xor i33 [[A0:%.*]], 2
453 ; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X]], i33 [[A0]], i33 25)
454 ; CHECK-NEXT:    ret i33 [[R]]
456   %x = xor i33 %a0, 2
457   %r = call i33 @llvm.fshr.i33(i33 %x, i33 %x, i33 8)
458   ret i33 %r
461 ; The shift modulo bitwidth is the same for all vector elements.
463 define <2 x i31> @fshl_only_op1_demanded_vec_nonsplat(<2 x i31> %x, <2 x i31> %y) {
464 ; CHECK-LABEL: @fshl_only_op1_demanded_vec_nonsplat(
465 ; CHECK-NEXT:    [[Z:%.*]] = lshr <2 x i31> [[Y:%.*]], <i31 24, i31 24>
466 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i31> [[Z]], <i31 63, i31 31>
467 ; CHECK-NEXT:    ret <2 x i31> [[R]]
469   %z = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 7, i31 38>)
470   %r = and <2 x i31> %z, <i31 63, i31 31>
471   ret <2 x i31> %r
474 define i32 @rotl_constant_shift_amount(i32 %x) {
475 ; CHECK-LABEL: @rotl_constant_shift_amount(
476 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 1)
477 ; CHECK-NEXT:    ret i32 [[R]]
479   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 33)
480   ret i32 %r
483 define <2 x i31> @rotl_constant_shift_amount_vec(<2 x i31> %x) {
484 ; CHECK-LABEL: @rotl_constant_shift_amount_vec(
485 ; CHECK-NEXT:    [[R:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[X]], <2 x i31> <i31 1, i31 1>)
486 ; CHECK-NEXT:    ret <2 x i31> [[R]]
488   %r = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %x, <2 x i31> <i31 32, i31 -1>)
489   ret <2 x i31> %r
492 define i33 @rotr_constant_shift_amount(i33 %x) {
493 ; CHECK-LABEL: @rotr_constant_shift_amount(
494 ; CHECK-NEXT:    [[R:%.*]] = call i33 @llvm.fshl.i33(i33 [[X:%.*]], i33 [[X]], i33 32)
495 ; CHECK-NEXT:    ret i33 [[R]]
497   %r = call i33 @llvm.fshr.i33(i33 %x, i33 %x, i33 34)
498   ret i33 %r
501 define <2 x i32> @rotr_constant_shift_amount_vec(<2 x i32> %x) {
502 ; CHECK-LABEL: @rotr_constant_shift_amount_vec(
503 ; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.fshl.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[X]], <2 x i32> <i32 31, i32 1>)
504 ; CHECK-NEXT:    ret <2 x i32> [[R]]
506   %r = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %x, <2 x i32> <i32 33, i32 -1>)
507   ret <2 x i32> %r
510 ; Demand bits from both operands -- cannot simplify.
512 define i32 @fshl_both_ops_demanded(i32 %x, i32 %y) {
513 ; CHECK-LABEL: @fshl_both_ops_demanded(
514 ; CHECK-NEXT:    [[Z:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 7)
515 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[Z]], 192
516 ; CHECK-NEXT:    ret i32 [[R]]
518   %z = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)
519   %r = and i32 %z, 192
520   ret i32 %r
523 define i33 @fshr_both_ops_demanded(i33 %x, i33 %y) {
524 ; CHECK-LABEL: @fshr_both_ops_demanded(
525 ; CHECK-NEXT:    [[Z:%.*]] = call i33 @llvm.fshl.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 7)
526 ; CHECK-NEXT:    [[R:%.*]] = and i33 [[Z]], 192
527 ; CHECK-NEXT:    ret i33 [[R]]
529   %z = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 26)
530   %r = and i33 %z, 192
531   ret i33 %r
534 ; Both operands are demanded, but there are known bits.
536 define i32 @fshl_known_bits(i32 %x, i32 %y) {
537 ; CHECK-LABEL: @fshl_known_bits(
538 ; CHECK-NEXT:    ret i32 128
540   %x2 = or i32 %x, 1   ; lo bit set
541   %y2 = lshr i32 %y, 1 ; hi bit clear
542   %z = call i32 @llvm.fshl.i32(i32 %x2, i32 %y2, i32 7)
543   %r = and i32 %z, 192
544   ret i32 %r
547 define i33 @fshr_known_bits(i33 %x, i33 %y) {
548 ; CHECK-LABEL: @fshr_known_bits(
549 ; CHECK-NEXT:    ret i33 128
551   %x2 = or i33 %x, 1 ; lo bit set
552   %y2 = lshr i33 %y, 1 ; hi bit set
553   %z = call i33 @llvm.fshr.i33(i33 %x2, i33 %y2, i33 26)
554   %r = and i33 %z, 192
555   ret i33 %r
558 ; This case fails to simplify due to multiple uses.
560 define i33 @fshr_multi_use(i33 %a) {
561 ; CHECK-LABEL: @fshr_multi_use(
562 ; CHECK-NEXT:    [[B:%.*]] = call i33 @llvm.fshl.i33(i33 [[A:%.*]], i33 [[A]], i33 32)
563 ; CHECK-NEXT:    [[C:%.*]] = lshr i33 [[B]], 23
564 ; CHECK-NEXT:    [[D:%.*]] = xor i33 [[C]], [[B]]
565 ; CHECK-NEXT:    [[E:%.*]] = and i33 [[D]], 31
566 ; CHECK-NEXT:    ret i33 [[E]]
568   %b = tail call i33 @llvm.fshr.i33(i33 %a, i33 %a, i33 1)
569   %c = lshr i33 %b, 23
570   %d = xor i33 %c, %b
571   %e = and i33 %d, 31
572   ret i33 %e
575 ; This demonstrates the same simplification working if the fshr intrinsic
576 ; is expanded into shifts and or.
578 define i33 @expanded_fshr_multi_use(i33 %a) {
579 ; CHECK-LABEL: @expanded_fshr_multi_use(
580 ; CHECK-NEXT:    [[B:%.*]] = call i33 @llvm.fshl.i33(i33 [[A:%.*]], i33 [[A]], i33 32)
581 ; CHECK-NEXT:    [[C:%.*]] = lshr i33 [[B]], 23
582 ; CHECK-NEXT:    [[D:%.*]] = xor i33 [[C]], [[B]]
583 ; CHECK-NEXT:    [[E:%.*]] = and i33 [[D]], 31
584 ; CHECK-NEXT:    ret i33 [[E]]
586   %t = lshr i33 %a, 1
587   %t2 = shl i33 %a, 32
588   %b = or i33 %t, %t2
589   %c = lshr i33 %b, 23
590   %d = xor i33 %c, %b
591   %e = and i33 %d, 31
592   ret i33 %e
595 declare i16 @llvm.fshl.i16(i16, i16, i16)
596 declare i16 @llvm.fshr.i16(i16, i16, i16)
597 declare <3 x i16> @llvm.fshl.v3i16(<3 x i16>, <3 x i16>, <3 x i16>)
599 ; Special-case: rotate a 16-bit value left/right by 8-bits is bswap.
601 define i16 @fshl_bswap(i16 %x) {
602 ; CHECK-LABEL: @fshl_bswap(
603 ; CHECK-NEXT:    [[R:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])
604 ; CHECK-NEXT:    ret i16 [[R]]
606   %r = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 8)
607   ret i16 %r
610 define i16 @fshr_bswap(i16 %x) {
611 ; CHECK-LABEL: @fshr_bswap(
612 ; CHECK-NEXT:    [[R:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])
613 ; CHECK-NEXT:    ret i16 [[R]]
615   %r = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 8)
616   ret i16 %r
619 define <3 x i16> @fshl_bswap_vector(<3 x i16> %x) {
620 ; CHECK-LABEL: @fshl_bswap_vector(
621 ; CHECK-NEXT:    [[R:%.*]] = call <3 x i16> @llvm.bswap.v3i16(<3 x i16> [[X:%.*]])
622 ; CHECK-NEXT:    ret <3 x i16> [[R]]
624   %r = call <3 x i16> @llvm.fshl.v3i16(<3 x i16> %x, <3 x i16> %x, <3 x i16> <i16 8, i16 8, i16 8>)
625   ret <3 x i16> %r
628 ; Negative test
630 define i16 @fshl_bswap_wrong_op(i16 %x, i16 %y) {
631 ; CHECK-LABEL: @fshl_bswap_wrong_op(
632 ; CHECK-NEXT:    [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[Y:%.*]], i16 8)
633 ; CHECK-NEXT:    ret i16 [[R]]
635   %r = call i16 @llvm.fshl.i16(i16 %x, i16 %y, i16 8)
636   ret i16 %r
639 ; Negative test
641 define i16 @fshr_bswap_wrong_amount(i16 %x) {
642 ; CHECK-LABEL: @fshr_bswap_wrong_amount(
643 ; CHECK-NEXT:    [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 12)
644 ; CHECK-NEXT:    ret i16 [[R]]
646   %r = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 4)
647   ret i16 %r
650 ; Negative test
652 define i32 @fshl_bswap_wrong_width(i32 %x) {
653 ; CHECK-LABEL: @fshl_bswap_wrong_width(
654 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 8)
655 ; CHECK-NEXT:    ret i32 [[R]]
657   %r = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 8)
658   ret i32 %r
661 define i32 @fshl_mask_args_same1(i32 %a) {
662 ; CHECK-LABEL: @fshl_mask_args_same1(
663 ; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[A:%.*]], 16
664 ; CHECK-NEXT:    ret i32 [[T2]]
666   %t1 = and i32 %a, 4294901760 ; 0xffff0000
667   %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 16)
668   ret i32 %t2
671 define i32 @fshl_mask_args_same2(i32 %a) {
672 ; CHECK-LABEL: @fshl_mask_args_same2(
673 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[A:%.*]], 8
674 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], 65280
675 ; CHECK-NEXT:    ret i32 [[T2]]
677   %t1 = and i32 %a, 255
678   %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 8)
679   ret i32 %t2
682 define i32 @fshl_mask_args_same3(i32 %a) {
683 ; CHECK-LABEL: @fshl_mask_args_same3(
684 ; CHECK-NEXT:    [[T2:%.*]] = shl i32 [[A:%.*]], 24
685 ; CHECK-NEXT:    ret i32 [[T2]]
687   %t1 = and i32 %a, 255
688   %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 24)
689   ret i32 %t2
692 define i32 @fshl_mask_args_different(i32 %a) {
693 ; CHECK-LABEL: @fshl_mask_args_different(
694 ; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[A:%.*]], 15
695 ; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T1]], 130560
696 ; CHECK-NEXT:    ret i32 [[T3]]
698   %t2 = and i32 %a, 4294901760 ; 0xfffff00f
699   %t1 = and i32 %a, 4278190080 ; 0xff00f00f
700   %t3 = call i32 @llvm.fshl.i32(i32 %t2, i32 %t1, i32 17)
701   ret i32 %t3
704 define <2 x i31> @fshr_mask_args_same_vector(<2 x i31> %a) {
705 ; CHECK-LABEL: @fshr_mask_args_same_vector(
706 ; CHECK-NEXT:    [[T3:%.*]] = shl <2 x i31> [[A:%.*]], <i31 10, i31 10>
707 ; CHECK-NEXT:    ret <2 x i31> [[T3]]
709   %t1 = and <2 x i31> %a, <i31 1000, i31 1000>
710   %t2 = and <2 x i31> %a, <i31 6442450943, i31 6442450943>
711   %t3 = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %t2, <2 x i31> %t1, <2 x i31> <i31 10, i31 10>)
712   ret <2 x i31> %t3
715 define <2 x i32> @fshr_mask_args_same_vector2(<2 x i32> %a, <2 x i32> %b) {
716 ; CHECK-LABEL: @fshr_mask_args_same_vector2(
717 ; CHECK-NEXT:    [[T1:%.*]] = and <2 x i32> [[A:%.*]], <i32 1000000, i32 100000>
718 ; CHECK-NEXT:    [[T3:%.*]] = lshr exact <2 x i32> [[T1]], <i32 3, i32 3>
719 ; CHECK-NEXT:    ret <2 x i32> [[T3]]
721   %t1 = and <2 x i32> %a, <i32 1000000, i32 100000>
722   %t2 = and <2 x i32> %a, <i32 6442450943, i32 6442450943>
723   %t3 = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %t1, <2 x i32> %t1, <2 x i32> <i32 3, i32 3>)
724   ret <2 x i32> %t3
727 define <2 x i31> @fshr_mask_args_same_vector3_different_but_still_prunable(<2 x i31> %a) {
728 ; CHECK-LABEL: @fshr_mask_args_same_vector3_different_but_still_prunable(
729 ; CHECK-NEXT:    [[T1:%.*]] = and <2 x i31> [[A:%.*]], <i31 1000, i31 1000>
730 ; CHECK-NEXT:    [[T3:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[A]], <2 x i31> [[T1]], <2 x i31> <i31 10, i31 3>)
731 ; CHECK-NEXT:    ret <2 x i31> [[T3]]
733   %t1 = and <2 x i31> %a, <i31 1000, i31 1000>
734   %t2 = and <2 x i31> %a, <i31 6442450943, i31 6442450943>
735   %t3 = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %t2, <2 x i31> %t1, <2 x i31> <i31 10, i31 3>)
736   ret <2 x i31> %t3