blob: f4c54ad3c9227612681cc1ce6215ac537eccbf99 [file] [log] [blame]
Sanjay Patelbcc5a742018-11-13 16:47:16 +00001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4declare i32 @llvm.fshl.i32(i32, i32, i32)
5declare i33 @llvm.fshr.i33(i33, i33, i33)
6declare <2 x i32> @llvm.fshr.v2i32(<2 x i32>, <2 x i32>, <2 x i32>)
7declare <2 x i31> @llvm.fshl.v2i31(<2 x i31>, <2 x i31>, <2 x i31>)
8
9; If the shift mask doesn't include any demanded bits, the funnel shift can be eliminated.
10
11define i32 @fshl_mask_simplify1(i32 %x, i32 %y, i32 %sh) {
12; CHECK-LABEL: @fshl_mask_simplify1(
Sanjay Patela1395642018-11-13 23:27:23 +000013; CHECK-NEXT: ret i32 [[X:%.*]]
Sanjay Patelbcc5a742018-11-13 16:47:16 +000014;
15 %maskedsh = and i32 %sh, 32
16 %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
17 ret i32 %r
18}
19
20define <2 x i32> @fshr_mask_simplify2(<2 x i32> %x, <2 x i32> %y, <2 x i32> %sh) {
21; CHECK-LABEL: @fshr_mask_simplify2(
Sanjay Patela1395642018-11-13 23:27:23 +000022; CHECK-NEXT: ret <2 x i32> [[Y:%.*]]
Sanjay Patelbcc5a742018-11-13 16:47:16 +000023;
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
27}
28
29; Negative test.
30
31define 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]]
36;
37 %maskedsh = and i32 %sh, 16
38 %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
39 ret i32 %r
40}
41
Sanjay Patela1395642018-11-13 23:27:23 +000042; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.
Sanjay Patelbcc5a742018-11-13 16:47:16 +000043
44define 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]]
49;
50 %maskedsh = and i33 %sh, 64
51 %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %maskedsh)
52 ret i33 %r
53}
54
Sanjay Patela1395642018-11-13 23:27:23 +000055; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.
Sanjay Patelbcc5a742018-11-13 16:47:16 +000056
57define <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]]
62;
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
66}
67
Sanjay Patela1395642018-11-13 23:27:23 +000068; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.
Sanjay Patelbcc5a742018-11-13 16:47:16 +000069
70define 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]]
75;
76 %maskedsh = and i33 %sh, 32
77 %r = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 %maskedsh)
78 ret i33 %r
79}
80
81; This mask op is unnecessary.
82
83define i32 @fshl_mask_not_required(i32 %x, i32 %y, i32 %sh) {
84; CHECK-LABEL: @fshl_mask_not_required(
Sanjay Patela1395642018-11-13 23:27:23 +000085; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[SH:%.*]])
Sanjay Patelbcc5a742018-11-13 16:47:16 +000086; CHECK-NEXT: ret i32 [[R]]
87;
88 %maskedsh = and i32 %sh, 31
89 %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
90 ret i32 %r
91}
92
93; This mask op can be reduced.
94
95define i32 @fshl_mask_reduce_constant(i32 %x, i32 %y, i32 %sh) {
96; CHECK-LABEL: @fshl_mask_reduce_constant(
Sanjay Patela1395642018-11-13 23:27:23 +000097; CHECK-NEXT: [[MASKEDSH:%.*]] = and i32 [[SH:%.*]], 1
Sanjay Patelbcc5a742018-11-13 16:47:16 +000098; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[MASKEDSH]])
99; CHECK-NEXT: ret i32 [[R]]
100;
101 %maskedsh = and i32 %sh, 33
102 %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
103 ret i32 %r
104}
105
106; But this mask op is required.
107
108define 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]]
113;
114 %maskedsh = and i32 %sh, 15
115 %r = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %maskedsh)
116 ret i32 %r
117}
118
119; The transform is not limited to mask ops.
120
121define <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(
Sanjay Patela1395642018-11-13 23:27:23 +0000123; CHECK-NEXT: [[R:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> [[SH:%.*]])
Sanjay Patelbcc5a742018-11-13 16:47:16 +0000124; CHECK-NEXT: ret <2 x i32> [[R]]
125;
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
129}
130
Sanjay Patela1395642018-11-13 23:27:23 +0000131; Check again with weird bitwidths - the analysis is invalid with non-power-of-2.
132
Sanjay Patelbcc5a742018-11-13 16:47:16 +0000133define <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]]
138;
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
142}
143
Nikita Popov6e81d422018-11-23 22:45:08 +0000144; Simplify one undef or zero operand and constant shift amount.
Sanjay Patel96152dc2018-11-20 17:51:49 +0000145
146define i32 @fshl_op0_undef(i32 %x) {
147; CHECK-LABEL: @fshl_op0_undef(
Nikita Popov6e81d422018-11-23 22:45:08 +0000148; CHECK-NEXT: [[R:%.*]] = lshr i32 [[X:%.*]], 25
Sanjay Patel96152dc2018-11-20 17:51:49 +0000149; CHECK-NEXT: ret i32 [[R]]
150;
151 %r = call i32 @llvm.fshl.i32(i32 undef, i32 %x, i32 7)
152 ret i32 %r
153}
154
Nikita Popova70fdf82018-11-21 20:34:11 +0000155define i32 @fshl_op0_zero(i32 %x) {
156; CHECK-LABEL: @fshl_op0_zero(
Nikita Popov6e81d422018-11-23 22:45:08 +0000157; CHECK-NEXT: [[R:%.*]] = lshr i32 [[X:%.*]], 25
Nikita Popova70fdf82018-11-21 20:34:11 +0000158; CHECK-NEXT: ret i32 [[R]]
159;
160 %r = call i32 @llvm.fshl.i32(i32 0, i32 %x, i32 7)
161 ret i32 %r
162}
163
Sanjay Patel96152dc2018-11-20 17:51:49 +0000164define i33 @fshr_op0_undef(i33 %x) {
165; CHECK-LABEL: @fshr_op0_undef(
Nikita Popov6e81d422018-11-23 22:45:08 +0000166; CHECK-NEXT: [[R:%.*]] = lshr i33 [[X:%.*]], 7
Sanjay Patel96152dc2018-11-20 17:51:49 +0000167; CHECK-NEXT: ret i33 [[R]]
168;
169 %r = call i33 @llvm.fshr.i33(i33 undef, i33 %x, i33 7)
170 ret i33 %r
171}
172
Nikita Popova70fdf82018-11-21 20:34:11 +0000173define i33 @fshr_op0_zero(i33 %x) {
174; CHECK-LABEL: @fshr_op0_zero(
Nikita Popov6e81d422018-11-23 22:45:08 +0000175; CHECK-NEXT: [[R:%.*]] = lshr i33 [[X:%.*]], 7
Nikita Popova70fdf82018-11-21 20:34:11 +0000176; CHECK-NEXT: ret i33 [[R]]
177;
178 %r = call i33 @llvm.fshr.i33(i33 0, i33 %x, i33 7)
179 ret i33 %r
180}
181
Sanjay Patel96152dc2018-11-20 17:51:49 +0000182define i32 @fshl_op1_undef(i32 %x) {
183; CHECK-LABEL: @fshl_op1_undef(
Nikita Popov6e81d422018-11-23 22:45:08 +0000184; CHECK-NEXT: [[R:%.*]] = shl i32 [[X:%.*]], 7
Sanjay Patel96152dc2018-11-20 17:51:49 +0000185; CHECK-NEXT: ret i32 [[R]]
186;
187 %r = call i32 @llvm.fshl.i32(i32 %x, i32 undef, i32 7)
188 ret i32 %r
189}
190
Nikita Popova70fdf82018-11-21 20:34:11 +0000191define i32 @fshl_op1_zero(i32 %x) {
192; CHECK-LABEL: @fshl_op1_zero(
Nikita Popov6e81d422018-11-23 22:45:08 +0000193; CHECK-NEXT: [[R:%.*]] = shl i32 [[X:%.*]], 7
Nikita Popova70fdf82018-11-21 20:34:11 +0000194; CHECK-NEXT: ret i32 [[R]]
195;
196 %r = call i32 @llvm.fshl.i32(i32 %x, i32 0, i32 7)
197 ret i32 %r
198}
199
Sanjay Patel96152dc2018-11-20 17:51:49 +0000200define i33 @fshr_op1_undef(i33 %x) {
201; CHECK-LABEL: @fshr_op1_undef(
Nikita Popov6e81d422018-11-23 22:45:08 +0000202; CHECK-NEXT: [[R:%.*]] = shl i33 [[X:%.*]], 26
Sanjay Patel96152dc2018-11-20 17:51:49 +0000203; CHECK-NEXT: ret i33 [[R]]
204;
205 %r = call i33 @llvm.fshr.i33(i33 %x, i33 undef, i33 7)
206 ret i33 %r
207}
208
Nikita Popova70fdf82018-11-21 20:34:11 +0000209define i33 @fshr_op1_zero(i33 %x) {
210; CHECK-LABEL: @fshr_op1_zero(
Nikita Popov6e81d422018-11-23 22:45:08 +0000211; CHECK-NEXT: [[R:%.*]] = shl i33 [[X:%.*]], 26
Nikita Popova70fdf82018-11-21 20:34:11 +0000212; CHECK-NEXT: ret i33 [[R]]
213;
214 %r = call i33 @llvm.fshr.i33(i33 %x, i33 0, i33 7)
215 ret i33 %r
216}
217
Nikita Popov6e81d422018-11-23 22:45:08 +0000218define <2 x i31> @fshl_op0_zero_vec(<2 x i31> %x) {
219; CHECK-LABEL: @fshl_op0_zero_vec(
220; CHECK-NEXT: [[R:%.*]] = lshr <2 x i31> [[X:%.*]], <i31 24, i31 24>
221; CHECK-NEXT: ret <2 x i31> [[R]]
222;
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
225}
226
227define <2 x i31> @fshl_op1_undef_vec(<2 x i31> %x) {
228; CHECK-LABEL: @fshl_op1_undef_vec(
229; CHECK-NEXT: [[R:%.*]] = shl <2 x i31> [[X:%.*]], <i31 7, i31 7>
230; CHECK-NEXT: ret <2 x i31> [[R]]
231;
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
234}
235
236define <2 x i32> @fshr_op0_undef_vec(<2 x i32> %x) {
237; CHECK-LABEL: @fshr_op0_undef_vec(
238; CHECK-NEXT: [[R:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 7, i32 7>
239; CHECK-NEXT: ret <2 x i32> [[R]]
240;
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
243}
244
245define <2 x i32> @fshr_op1_zero_vec(<2 x i32> %x) {
246; CHECK-LABEL: @fshr_op1_zero_vec(
247; CHECK-NEXT: [[R:%.*]] = shl <2 x i32> [[X:%.*]], <i32 25, i32 25>
248; CHECK-NEXT: ret <2 x i32> [[R]]
249;
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
252}
253
Sanjay Patel96152dc2018-11-20 17:51:49 +0000254; Only demand bits from one of the operands.
255
256define i32 @fshl_only_op0_demanded(i32 %x, i32 %y) {
257; CHECK-LABEL: @fshl_only_op0_demanded(
Nikita Popov2c779c02018-11-24 19:00:45 +0000258; CHECK-NEXT: [[Z:%.*]] = shl i32 [[X:%.*]], 7
Sanjay Patel96152dc2018-11-20 17:51:49 +0000259; CHECK-NEXT: [[R:%.*]] = and i32 [[Z]], 128
260; CHECK-NEXT: ret i32 [[R]]
261;
262 %z = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)
263 %r = and i32 %z, 128
264 ret i32 %r
265}
266
267define i32 @fshl_only_op1_demanded(i32 %x, i32 %y) {
268; CHECK-LABEL: @fshl_only_op1_demanded(
Nikita Popov2c779c02018-11-24 19:00:45 +0000269; CHECK-NEXT: [[Z:%.*]] = lshr i32 [[Y:%.*]], 25
Sanjay Patel96152dc2018-11-20 17:51:49 +0000270; CHECK-NEXT: [[R:%.*]] = and i32 [[Z]], 63
271; CHECK-NEXT: ret i32 [[R]]
272;
273 %z = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)
274 %r = and i32 %z, 63
275 ret i32 %r
276}
277
Nikita Popov2c779c02018-11-24 19:00:45 +0000278define i33 @fshr_only_op1_demanded(i33 %x, i33 %y) {
279; CHECK-LABEL: @fshr_only_op1_demanded(
280; CHECK-NEXT: [[Z:%.*]] = lshr i33 [[Y:%.*]], 7
Sanjay Patel96152dc2018-11-20 17:51:49 +0000281; CHECK-NEXT: [[R:%.*]] = and i33 [[Z]], 12392
282; CHECK-NEXT: ret i33 [[R]]
283;
284 %z = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 7)
285 %r = and i33 %z, 12392
286 ret i33 %r
287}
288
Nikita Popov2c779c02018-11-24 19:00:45 +0000289define i33 @fshr_only_op0_demanded(i33 %x, i33 %y) {
290; CHECK-LABEL: @fshr_only_op0_demanded(
291; CHECK-NEXT: [[TMP1:%.*]] = lshr i33 [[X:%.*]], 4
292; CHECK-NEXT: [[R:%.*]] = and i33 [[TMP1]], 7
Sanjay Patel96152dc2018-11-20 17:51:49 +0000293; CHECK-NEXT: ret i33 [[R]]
294;
295 %z = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 7)
296 %r = lshr i33 %z, 30
297 ret i33 %r
298}
299
Nikita Popov2c779c02018-11-24 19:00:45 +0000300define <2 x i31> @fshl_only_op1_demanded_vec_splat(<2 x i31> %x, <2 x i31> %y) {
301; CHECK-LABEL: @fshl_only_op1_demanded_vec_splat(
302; CHECK-NEXT: [[Z:%.*]] = lshr <2 x i31> [[Y:%.*]], <i31 24, i31 24>
303; CHECK-NEXT: [[R:%.*]] = and <2 x i31> [[Z]], <i31 63, i31 31>
304; CHECK-NEXT: ret <2 x i31> [[R]]
305;
306 %z = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 7, i31 7>)
307 %r = and <2 x i31> %z, <i31 63, i31 31>
308 ret <2 x i31> %r
309}
310
311; The shift modulo bitwidth is the same for all vector elements, but this is not simplified yet.
312define <2 x i31> @fshl_only_op1_demanded_vec_nonsplat(<2 x i31> %x, <2 x i31> %y) {
313; CHECK-LABEL: @fshl_only_op1_demanded_vec_nonsplat(
314; CHECK-NEXT: [[Z:%.*]] = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> [[X:%.*]], <2 x i31> [[Y:%.*]], <2 x i31> <i31 7, i31 38>)
315; CHECK-NEXT: [[R:%.*]] = and <2 x i31> [[Z]], <i31 63, i31 31>
316; CHECK-NEXT: ret <2 x i31> [[R]]
317;
318 %z = call <2 x i31> @llvm.fshl.v2i31(<2 x i31> %x, <2 x i31> %y, <2 x i31> <i31 7, i31 38>)
319 %r = and <2 x i31> %z, <i31 63, i31 31>
320 ret <2 x i31> %r
321}
322
Sanjay Patel96152dc2018-11-20 17:51:49 +0000323; Demand bits from both operands -- cannot simplify.
324
325define i32 @fshl_both_ops_demanded(i32 %x, i32 %y) {
326; CHECK-LABEL: @fshl_both_ops_demanded(
327; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 7)
328; CHECK-NEXT: [[R:%.*]] = and i32 [[Z]], 192
329; CHECK-NEXT: ret i32 [[R]]
330;
331 %z = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 7)
332 %r = and i32 %z, 192
333 ret i32 %r
334}
335
336define i33 @fshr_both_ops_demanded(i33 %x, i33 %y) {
337; CHECK-LABEL: @fshr_both_ops_demanded(
338; CHECK-NEXT: [[Z:%.*]] = call i33 @llvm.fshr.i33(i33 [[X:%.*]], i33 [[Y:%.*]], i33 26)
339; CHECK-NEXT: [[R:%.*]] = and i33 [[Z]], 192
340; CHECK-NEXT: ret i33 [[R]]
341;
342 %z = call i33 @llvm.fshr.i33(i33 %x, i33 %y, i33 26)
343 %r = and i33 %z, 192
344 ret i33 %r
345}
346
347; Both operands are demanded, but there are known bits.
348
349define i32 @fshl_known_bits(i32 %x, i32 %y) {
350; CHECK-LABEL: @fshl_known_bits(
Nikita Popov2c779c02018-11-24 19:00:45 +0000351; CHECK-NEXT: ret i32 128
Sanjay Patel96152dc2018-11-20 17:51:49 +0000352;
353 %x2 = or i32 %x, 1 ; lo bit set
354 %y2 = lshr i32 %y, 1 ; hi bit clear
355 %z = call i32 @llvm.fshl.i32(i32 %x2, i32 %y2, i32 7)
356 %r = and i32 %z, 192
357 ret i32 %r
358}
359
360define i33 @fshr_known_bits(i33 %x, i33 %y) {
361; CHECK-LABEL: @fshr_known_bits(
Nikita Popov2c779c02018-11-24 19:00:45 +0000362; CHECK-NEXT: ret i33 128
Sanjay Patel96152dc2018-11-20 17:51:49 +0000363;
364 %x2 = or i33 %x, 1 ; lo bit set
365 %y2 = lshr i33 %y, 1 ; hi bit set
366 %z = call i33 @llvm.fshr.i33(i33 %x2, i33 %y2, i33 26)
367 %r = and i33 %z, 192
368 ret i33 %r
369}
370
371; This case fails to simplify due to multiple uses.
372
373define i33 @fshr_multi_use(i33 %a) {
374; CHECK-LABEL: @fshr_multi_use(
375; CHECK-NEXT: [[B:%.*]] = tail call i33 @llvm.fshr.i33(i33 [[A:%.*]], i33 [[A]], i33 1)
376; CHECK-NEXT: [[C:%.*]] = lshr i33 [[B]], 23
377; CHECK-NEXT: [[D:%.*]] = xor i33 [[C]], [[B]]
378; CHECK-NEXT: [[E:%.*]] = and i33 [[D]], 31
379; CHECK-NEXT: ret i33 [[E]]
380;
381 %b = tail call i33 @llvm.fshr.i33(i33 %a, i33 %a, i33 1)
382 %c = lshr i33 %b, 23
383 %d = xor i33 %c, %b
384 %e = and i33 %d, 31
385 ret i33 %e
386}
387
388; This demonstrates the same simplification working if the fshr intrinsic
389; is expanded into shifts and or.
390
391define i33 @expanded_fshr_multi_use(i33 %a) {
392; CHECK-LABEL: @expanded_fshr_multi_use(
393; CHECK-NEXT: [[TMP:%.*]] = lshr i33 [[A:%.*]], 1
394; CHECK-NEXT: [[C:%.*]] = lshr i33 [[A]], 24
395; CHECK-NEXT: [[D:%.*]] = xor i33 [[C]], [[TMP]]
396; CHECK-NEXT: [[E:%.*]] = and i33 [[D]], 31
397; CHECK-NEXT: ret i33 [[E]]
398;
399 %tmp = lshr i33 %a, 1
400 %tmp2 = shl i33 %a, 32
401 %b = or i33 %tmp, %tmp2
402 %c = lshr i33 %b, 23
403 %d = xor i33 %c, %b
404 %e = and i33 %d, 31
405 ret i33 %e
406}
407
Sanjay Patel703299e2018-11-27 00:08:21 +0000408declare i16 @llvm.fshl.i16(i16, i16, i16)
409declare i16 @llvm.fshr.i16(i16, i16, i16)
410
411; Special-case: rotate a 16-bit value left/right by 8-bits is bswap.
412
413define i16 @fshl_bswap(i16 %x) {
414; CHECK-LABEL: @fshl_bswap(
415; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 8)
416; CHECK-NEXT: ret i16 [[R]]
417;
418 %r = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 8)
419 ret i16 %r
420}
421
422define i16 @fshr_bswap(i16 %x) {
423; CHECK-LABEL: @fshr_bswap(
424; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.fshr.i16(i16 [[X:%.*]], i16 [[X]], i16 8)
425; CHECK-NEXT: ret i16 [[R]]
426;
427 %r = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 8)
428 ret i16 %r
429}
430