[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / bswap.ll
blob44e1616af86c549fb7acc1122731380598006e93
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
6 define i32 @test1(i32 %i) {
7 ; CHECK-LABEL: @test1(
8 ; CHECK-NEXT:    [[T12:%.*]] = call i32 @llvm.bswap.i32(i32 [[I:%.*]])
9 ; CHECK-NEXT:    ret i32 [[T12]]
11   %t1 = lshr i32 %i, 24
12   %t3 = lshr i32 %i, 8
13   %t4 = and i32 %t3, 65280
14   %t5 = or i32 %t1, %t4
15   %t7 = shl i32 %i, 8
16   %t8 = and i32 %t7, 16711680
17   %t9 = or i32 %t5, %t8
18   %t11 = shl i32 %i, 24
19   %t12 = or i32 %t9, %t11
20   ret i32 %t12
23 define <2 x i32> @test1_vector(<2 x i32> %i) {
24 ; CHECK-LABEL: @test1_vector(
25 ; CHECK-NEXT:    [[T12:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[I:%.*]])
26 ; CHECK-NEXT:    ret <2 x i32> [[T12]]
28   %t1 = lshr <2 x i32> %i, <i32 24, i32 24>
29   %t3 = lshr <2 x i32> %i, <i32 8, i32 8>
30   %t4 = and <2 x i32> %t3, <i32 65280, i32 65280>
31   %t5 = or <2 x i32> %t1, %t4
32   %t7 = shl <2 x i32> %i, <i32 8, i32 8>
33   %t8 = and <2 x i32> %t7, <i32 16711680, i32 16711680>
34   %t9 = or <2 x i32> %t5, %t8
35   %t11 = shl <2 x i32> %i, <i32 24, i32 24>
36   %t12 = or <2 x i32> %t9, %t11
37   ret <2 x i32> %t12
40 define i16 @test1_trunc(i32 %i) {
41 ; CHECK-LABEL: @test1_trunc(
42 ; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[I:%.*]], 24
43 ; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[I]], 8
44 ; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], 65280
45 ; CHECK-NEXT:    [[T5:%.*]] = or disjoint i32 [[T1]], [[T4]]
46 ; CHECK-NEXT:    [[T13:%.*]] = trunc nuw i32 [[T5]] to i16
47 ; CHECK-NEXT:    ret i16 [[T13]]
49   %t1 = lshr i32 %i, 24
50   %t3 = lshr i32 %i, 8
51   %t4 = and i32 %t3, 65280
52   %t5 = or i32 %t1, %t4
53   %t13 = trunc i32 %t5 to i16
54   ret i16 %t13
57 define i16 @test1_trunc_extra_use(i32 %i) {
58 ; CHECK-LABEL: @test1_trunc_extra_use(
59 ; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[I:%.*]], 24
60 ; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[I]], 8
61 ; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], 65280
62 ; CHECK-NEXT:    [[T5:%.*]] = or disjoint i32 [[T1]], [[T4]]
63 ; CHECK-NEXT:    call void @extra_use(i32 [[T5]])
64 ; CHECK-NEXT:    [[T13:%.*]] = trunc nuw i32 [[T5]] to i16
65 ; CHECK-NEXT:    ret i16 [[T13]]
67   %t1 = lshr i32 %i, 24
68   %t3 = lshr i32 %i, 8
69   %t4 = and i32 %t3, 65280
70   %t5 = or i32 %t1, %t4
71   call void @extra_use(i32 %t5)
72   %t13 = trunc i32 %t5 to i16
73   ret i16 %t13
76 define i32 @test2(i32 %arg) {
77 ; CHECK-LABEL: @test2(
78 ; CHECK-NEXT:    [[T14:%.*]] = call i32 @llvm.bswap.i32(i32 [[ARG:%.*]])
79 ; CHECK-NEXT:    ret i32 [[T14]]
81   %t2 = shl i32 %arg, 24
82   %t4 = shl i32 %arg, 8
83   %t5 = and i32 %t4, 16711680
84   %t6 = or i32 %t2, %t5
85   %t8 = lshr i32 %arg, 8
86   %t9 = and i32 %t8, 65280
87   %t10 = or i32 %t6, %t9
88   %t12 = lshr i32 %arg, 24
89   %t14 = or i32 %t10, %t12
90   ret i32 %t14
93 define <2 x i32> @test2_vector(<2 x i32> %arg) {
94 ; CHECK-LABEL: @test2_vector(
95 ; CHECK-NEXT:    [[T14:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[ARG:%.*]])
96 ; CHECK-NEXT:    ret <2 x i32> [[T14]]
98   %t2 = shl <2 x i32> %arg, <i32 24, i32 24>
99   %t4 = shl <2 x i32> %arg, <i32 8, i32 8>
100   %t5 = and <2 x i32> %t4, <i32 16711680, i32 16711680>
101   %t6 = or <2 x i32> %t2, %t5
102   %t8 = lshr <2 x i32> %arg, <i32 8, i32 8>
103   %t9 = and <2 x i32> %t8, <i32 65280, i32 65280>
104   %t10 = or <2 x i32> %t6, %t9
105   %t12 = lshr <2 x i32> %arg, <i32 24, i32 24>
106   %t14 = or <2 x i32> %t10, %t12
107   ret <2 x i32> %t14
110 define <2 x i32> @test2_vector_poison(<2 x i32> %arg) {
111 ; CHECK-LABEL: @test2_vector_poison(
112 ; CHECK-NEXT:    [[T2:%.*]] = shl <2 x i32> [[ARG:%.*]], <i32 24, i32 poison>
113 ; CHECK-NEXT:    [[T4:%.*]] = shl <2 x i32> [[ARG]], splat (i32 8)
114 ; CHECK-NEXT:    [[T5:%.*]] = and <2 x i32> [[T4]], <i32 16711680, i32 poison>
115 ; CHECK-NEXT:    [[T6:%.*]] = or disjoint <2 x i32> [[T2]], [[T5]]
116 ; CHECK-NEXT:    [[T8:%.*]] = lshr <2 x i32> [[ARG]], splat (i32 8)
117 ; CHECK-NEXT:    [[T9:%.*]] = and <2 x i32> [[T8]], <i32 65280, i32 poison>
118 ; CHECK-NEXT:    [[T10:%.*]] = or disjoint <2 x i32> [[T6]], [[T9]]
119 ; CHECK-NEXT:    [[T12:%.*]] = lshr <2 x i32> [[ARG]], <i32 24, i32 poison>
120 ; CHECK-NEXT:    [[T14:%.*]] = or disjoint <2 x i32> [[T10]], [[T12]]
121 ; CHECK-NEXT:    ret <2 x i32> [[T14]]
123   %t2 = shl <2 x i32> %arg, <i32 24, i32 poison>
124   %t4 = shl <2 x i32> %arg, <i32 8, i32 8>
125   %t5 = and <2 x i32> %t4, <i32 16711680, i32 poison>
126   %t6 = or <2 x i32> %t2, %t5
127   %t8 = lshr <2 x i32> %arg, <i32 8, i32 8>
128   %t9 = and <2 x i32> %t8, <i32 65280, i32 poison>
129   %t10 = or <2 x i32> %t6, %t9
130   %t12 = lshr <2 x i32> %arg, <i32 24, i32 poison>
131   %t14 = or <2 x i32> %t10, %t12
132   ret <2 x i32> %t14
135 define i16 @test3(i16 %s) {
136 ; CHECK-LABEL: @test3(
137 ; CHECK-NEXT:    [[T5:%.*]] = call i16 @llvm.bswap.i16(i16 [[S:%.*]])
138 ; CHECK-NEXT:    ret i16 [[T5]]
140   %t2 = lshr i16 %s, 8
141   %t4 = shl i16 %s, 8
142   %t5 = or i16 %t2, %t4
143   ret i16 %t5
146 define <2 x i16> @test3_vector(<2 x i16> %s) {
147 ; CHECK-LABEL: @test3_vector(
148 ; CHECK-NEXT:    [[T5:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[S:%.*]])
149 ; CHECK-NEXT:    ret <2 x i16> [[T5]]
151   %t2 = lshr <2 x i16> %s, <i16 8, i16 8>
152   %t4 = shl <2 x i16> %s, <i16 8, i16 8>
153   %t5 = or <2 x i16> %t2, %t4
154   ret <2 x i16> %t5
157 define <2 x i16> @test3_vector_poison(<2 x i16> %s) {
158 ; CHECK-LABEL: @test3_vector_poison(
159 ; CHECK-NEXT:    [[T5:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[S:%.*]])
160 ; CHECK-NEXT:    ret <2 x i16> [[T5]]
162   %t2 = lshr <2 x i16> %s, <i16 poison, i16 8>
163   %t4 = shl <2 x i16> %s, <i16 8, i16 poison>
164   %t5 = or <2 x i16> %t2, %t4
165   ret <2 x i16> %t5
168 define i16 @test4(i16 %s) {
169 ; CHECK-LABEL: @test4(
170 ; CHECK-NEXT:    [[T5:%.*]] = call i16 @llvm.bswap.i16(i16 [[S:%.*]])
171 ; CHECK-NEXT:    ret i16 [[T5]]
173   %t2 = lshr i16 %s, 8
174   %t4 = shl i16 %s, 8
175   %t5 = or i16 %t4, %t2
176   ret i16 %t5
179 define <2 x i16> @test4_vector(<2 x i16> %s) {
180 ; CHECK-LABEL: @test4_vector(
181 ; CHECK-NEXT:    [[T5:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[S:%.*]])
182 ; CHECK-NEXT:    ret <2 x i16> [[T5]]
184   %t2 = lshr <2 x i16> %s, <i16 8, i16 8>
185   %t4 = shl <2 x i16> %s, <i16 8, i16 8>
186   %t5 = or <2 x i16> %t4, %t2
187   ret <2 x i16> %t5
190 define i16 @test5(i16 %a) {
191 ; CHECK-LABEL: @test5(
192 ; CHECK-NEXT:    [[T_UPGRD_3:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])
193 ; CHECK-NEXT:    ret i16 [[T_UPGRD_3]]
195   %t = zext i16 %a to i32
196   %t1 = and i32 %t, 65280
197   %t2 = ashr i32 %t1, 8
198   %t2.upgrd.1 = trunc i32 %t2 to i16
199   %t4 = and i32 %t, 255
200   %t5 = shl i32 %t4, 8
201   %t5.upgrd.2 = trunc i32 %t5 to i16
202   %t.upgrd.3 = or i16 %t2.upgrd.1, %t5.upgrd.2
203   %t6 = bitcast i16 %t.upgrd.3 to i16
204   %t6.upgrd.4 = zext i16 %t6 to i32
205   %retval = trunc i32 %t6.upgrd.4 to i16
206   ret i16 %retval
209 define <2 x i16> @test5_vector(<2 x i16> %a) {
210 ; CHECK-LABEL: @test5_vector(
211 ; CHECK-NEXT:    [[T_UPGRD_3:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[A:%.*]])
212 ; CHECK-NEXT:    ret <2 x i16> [[T_UPGRD_3]]
214   %t = zext <2 x i16> %a to <2 x i32>
215   %t1 = and <2 x i32> %t, <i32 65280, i32 65280>
216   %t2 = ashr <2 x i32> %t1, <i32 8, i32 8>
217   %t2.upgrd.1 = trunc <2 x i32> %t2 to <2 x i16>
218   %t4 = and <2 x i32> %t, <i32 255, i32 255>
219   %t5 = shl <2 x i32> %t4, <i32 8, i32 8>
220   %t5.upgrd.2 = trunc <2 x i32> %t5 to <2 x i16>
221   %t.upgrd.3 = or <2 x i16> %t2.upgrd.1, %t5.upgrd.2
222   %t6 = bitcast <2 x i16> %t.upgrd.3 to <2 x i16>
223   %t6.upgrd.4 = zext <2 x i16> %t6 to <2 x i32>
224   %retval = trunc <2 x i32> %t6.upgrd.4 to <2 x i16>
225   ret <2 x i16> %retval
228 ; PR2842
229 define i32 @test6(i32 %x) nounwind readnone {
230 ; CHECK-LABEL: @test6(
231 ; CHECK-NEXT:    [[T7:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
232 ; CHECK-NEXT:    ret i32 [[T7]]
234   %t = shl i32 %x, 16
235   %x.mask = and i32 %x, 65280
236   %t1 = lshr i32 %x, 16
237   %t2 = and i32 %t1, 255
238   %t3 = or i32 %x.mask, %t
239   %t4 = or i32 %t3, %t2
240   %t5 = shl i32 %t4, 8
241   %t6 = lshr i32 %x, 24
242   %t7 = or i32 %t5, %t6
243   ret i32 %t7
246 define <2 x i32> @test6_vector(<2 x i32> %x) nounwind readnone {
247 ; CHECK-LABEL: @test6_vector(
248 ; CHECK-NEXT:    [[T7:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[X:%.*]])
249 ; CHECK-NEXT:    ret <2 x i32> [[T7]]
251   %t = shl <2 x i32> %x, <i32 16, i32 16>
252   %x.mask = and <2 x i32> %x, <i32 65280, i32 65280>
253   %t1 = lshr <2 x i32> %x, <i32 16, i32 16>
254   %t2 = and <2 x i32> %t1, <i32 255, i32 255>
255   %t3 = or <2 x i32> %x.mask, %t
256   %t4 = or <2 x i32> %t3, %t2
257   %t5 = shl <2 x i32> %t4, <i32 8, i32 8>
258   %t6 = lshr <2 x i32> %x, <i32 24, i32 24>
259   %t7 = or <2 x i32> %t5, %t6
260   ret <2 x i32> %t7
263 declare void @extra_use(i32)
265 ; swaphalf = (x << 16 | x >> 16)
266 ; ((swaphalf & 0x00ff00ff) << 8) | ((swaphalf >> 8) & 0x00ff00ff)
268 define i32 @bswap32_and_first(i32 %x) {
269 ; CHECK-LABEL: @bswap32_and_first(
270 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
271 ; CHECK-NEXT:    ret i32 [[BSWAP]]
273   %shl = shl i32 %x, 16
274   %shr = lshr i32 %x, 16
275   %swaphalf = or i32 %shl, %shr
276   %t = and i32 %swaphalf, 16711935
277   %tshl = shl nuw i32 %t, 8
278   %b = lshr i32 %swaphalf, 8
279   %band = and i32 %b, 16711935
280   %bswap = or i32 %tshl, %band
281   ret i32 %bswap
284 ; Extra use should not prevent matching to bswap.
285 ; swaphalf = (x << 16 | x >> 16)
286 ; ((swaphalf & 0x00ff00ff) << 8) | ((swaphalf >> 8) & 0x00ff00ff)
288 define i32 @bswap32_and_first_extra_use(i32 %x) {
289 ; CHECK-LABEL: @bswap32_and_first_extra_use(
290 ; CHECK-NEXT:    [[SWAPHALF:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 16)
291 ; CHECK-NEXT:    [[T:%.*]] = and i32 [[SWAPHALF]], 16711935
292 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X]])
293 ; CHECK-NEXT:    call void @extra_use(i32 [[T]])
294 ; CHECK-NEXT:    ret i32 [[BSWAP]]
296   %shl = shl i32 %x, 16
297   %shr = lshr i32 %x, 16
298   %swaphalf = or i32 %shl, %shr
299   %t = and i32 %swaphalf, 16711935
300   %tshl = shl nuw i32 %t, 8
301   %b = lshr i32 %swaphalf, 8
302   %band = and i32 %b, 16711935
303   %bswap = or i32 %tshl, %band
304   call void @extra_use(i32 %t)
305   ret i32 %bswap
308 ; swaphalf = (x << 16 | x >> 16)
309 ; ((swaphalf << 8) & 0xff00ff00) | ((swaphalf >> 8) & 0x00ff00ff)
311 ; PR23863
312 define i32 @bswap32_shl_first(i32 %x) {
313 ; CHECK-LABEL: @bswap32_shl_first(
314 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
315 ; CHECK-NEXT:    ret i32 [[BSWAP]]
317   %shl = shl i32 %x, 16
318   %shr = lshr i32 %x, 16
319   %swaphalf = or i32 %shl, %shr
320   %t = shl i32 %swaphalf, 8
321   %tand = and i32 %t, -16711936
322   %b = lshr i32 %swaphalf, 8
323   %band = and i32 %b, 16711935
324   %bswap = or i32 %tand, %band
325   ret i32 %bswap
328 ; Extra use should not prevent matching to bswap.
329 ; swaphalf = (x << 16 | x >> 16)
330 ; ((swaphalf << 8) & 0xff00ff00) | ((swaphalf >> 8) & 0x00ff00ff)
332 define i32 @bswap32_shl_first_extra_use(i32 %x) {
333 ; CHECK-LABEL: @bswap32_shl_first_extra_use(
334 ; CHECK-NEXT:    [[SWAPHALF:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 16)
335 ; CHECK-NEXT:    [[T:%.*]] = shl i32 [[SWAPHALF]], 8
336 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X]])
337 ; CHECK-NEXT:    call void @extra_use(i32 [[T]])
338 ; CHECK-NEXT:    ret i32 [[BSWAP]]
340   %shl = shl i32 %x, 16
341   %shr = lshr i32 %x, 16
342   %swaphalf = or i32 %shl, %shr
343   %t = shl i32 %swaphalf, 8
344   %tand = and i32 %t, -16711936
345   %b = lshr i32 %swaphalf, 8
346   %band = and i32 %b, 16711935
347   %bswap = or i32 %tand, %band
348   call void @extra_use(i32 %t)
349   ret i32 %bswap
352 define i16 @test8(i16 %a) {
353 ; CHECK-LABEL: @test8(
354 ; CHECK-NEXT:    [[OR:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])
355 ; CHECK-NEXT:    ret i16 [[OR]]
357   %conv = zext i16 %a to i32
358   %shr = lshr i16 %a, 8
359   %shl = shl i32 %conv, 8
360   %conv1 = zext i16 %shr to i32
361   %or = or i32 %conv1, %shl
362   %conv2 = trunc i32 %or to i16
363   ret i16 %conv2
366 define i16 @test9(i16 %a) {
367 ; CHECK-LABEL: @test9(
368 ; CHECK-NEXT:    [[OR:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])
369 ; CHECK-NEXT:    ret i16 [[OR]]
371   %conv = zext i16 %a to i32
372   %shr = lshr i32 %conv, 8
373   %shl = shl i32 %conv, 8
374   %or = or i32 %shr, %shl
375   %conv2 = trunc i32 %or to i16
376   ret i16 %conv2
379 define i16 @test10(i32 %a) {
380 ; CHECK-LABEL: @test10(
381 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[A:%.*]] to i16
382 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]])
383 ; CHECK-NEXT:    ret i16 [[REV]]
385   %shr1 = lshr i32 %a, 8
386   %and1 = and i32 %shr1, 255
387   %and2 = shl i32 %a, 8
388   %shl1 = and i32 %and2, 65280
389   %or = or i32 %and1, %shl1
390   %conv = trunc i32 %or to i16
391   ret i16 %conv
394 define <2 x i16> @test10_vector(<2 x i32> %a) {
395 ; CHECK-LABEL: @test10_vector(
396 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <2 x i32> [[A:%.*]] to <2 x i16>
397 ; CHECK-NEXT:    [[REV:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[TRUNC]])
398 ; CHECK-NEXT:    ret <2 x i16> [[REV]]
400   %shr1 = lshr <2 x i32> %a, <i32 8, i32 8>
401   %and1 = and <2 x i32> %shr1, <i32 255, i32 255>
402   %and2 = shl <2 x i32> %a, <i32 8, i32 8>
403   %shl1 = and <2 x i32> %and2, <i32 65280, i32 65280>
404   %or = or <2 x i32> %and1, %shl1
405   %conv = trunc <2 x i32> %or to <2 x i16>
406   ret <2 x i16> %conv
409 define i64 @PR39793_bswap_u64_as_u32(i64 %0) {
410 ; CHECK-LABEL: @PR39793_bswap_u64_as_u32(
411 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[TMP0:%.*]] to i32
412 ; CHECK-NEXT:    [[REV:%.*]] = call i32 @llvm.bswap.i32(i32 [[TRUNC]])
413 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[REV]] to i64
414 ; CHECK-NEXT:    ret i64 [[TMP2]]
416   %2 = lshr i64 %0, 24
417   %3 = and i64 %2, 255
418   %4 = lshr i64 %0, 8
419   %5 = and i64 %4, 65280
420   %6 = or i64 %3, %5
421   %7 = shl i64 %0, 8
422   %8 = and i64 %7, 16711680
423   %9 = or i64 %6, %8
424   %10 = shl i64 %0, 24
425   %11 = and i64 %10, 4278190080
426   %12 = or i64 %9, %11
427   ret i64 %12
430 define i16 @PR39793_bswap_u64_as_u32_trunc(i64 %0) {
431 ; CHECK-LABEL: @PR39793_bswap_u64_as_u32_trunc(
432 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[TMP0:%.*]] to i32
433 ; CHECK-NEXT:    [[REV:%.*]] = call i32 @llvm.bswap.i32(i32 [[TRUNC]])
434 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[REV]] to i16
435 ; CHECK-NEXT:    ret i16 [[TMP2]]
437   %2 = lshr i64 %0, 24
438   %3 = and i64 %2, 255
439   %4 = lshr i64 %0, 8
440   %5 = and i64 %4, 65280
441   %6 = or i64 %3, %5
442   %7 = shl i64 %0, 8
443   %8 = and i64 %7, 16711680
444   %9 = or i64 %6, %8
445   %10 = shl i64 %0, 24
446   %11 = and i64 %10, 4278190080
447   %12 = or i64 %9, %11
448   %13 = trunc i64 %12 to i16
449   ret i16 %13
452 define i64 @PR39793_bswap_u64_as_u16(i64 %0) {
453 ; CHECK-LABEL: @PR39793_bswap_u64_as_u16(
454 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[TMP0:%.*]] to i16
455 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]])
456 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i16 [[REV]] to i64
457 ; CHECK-NEXT:    ret i64 [[TMP2]]
459   %2 = lshr i64 %0, 8
460   %3 = and i64 %2, 255
461   %4 = shl i64 %0, 8
462   %5 = and i64 %4, 65280
463   %6 = or i64 %3, %5
464   ret i64 %6
467 define <2 x i64> @PR39793_bswap_u64_as_u16_vector(<2 x i64> %0) {
468 ; CHECK-LABEL: @PR39793_bswap_u64_as_u16_vector(
469 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <2 x i64> [[TMP0:%.*]] to <2 x i16>
470 ; CHECK-NEXT:    [[REV:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[TRUNC]])
471 ; CHECK-NEXT:    [[TMP2:%.*]] = zext <2 x i16> [[REV]] to <2 x i64>
472 ; CHECK-NEXT:    ret <2 x i64> [[TMP2]]
474   %2 = lshr <2 x i64> %0, <i64 8, i64 8>
475   %3 = and <2 x i64> %2, <i64 255, i64 255>
476   %4 = shl <2 x i64> %0, <i64 8, i64 8>
477   %5 = and <2 x i64> %4, <i64 65280, i64 65280>
478   %6 = or <2 x i64> %3, %5
479   ret <2 x i64> %6
482 define i8 @PR39793_bswap_u64_as_u16_trunc(i64 %0) {
483 ; CHECK-LABEL: @PR39793_bswap_u64_as_u16_trunc(
484 ; CHECK-NEXT:    [[REV1:%.*]] = lshr i64 [[TMP0:%.*]], 8
485 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[REV1]] to i8
486 ; CHECK-NEXT:    ret i8 [[TMP2]]
488   %2 = lshr i64 %0, 8
489   %3 = and i64 %2, 255
490   %4 = shl i64 %0, 8
491   %5 = and i64 %4, 65280
492   %6 = or i64 %3, %5
493   %7 = trunc i64 %6 to i8
494   ret i8 %7
497 define i50 @PR39793_bswap_u50_as_u16(i50 %0) {
498 ; CHECK-LABEL: @PR39793_bswap_u50_as_u16(
499 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i50 [[TMP0:%.*]] to i16
500 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]])
501 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i16 [[REV]] to i50
502 ; CHECK-NEXT:    ret i50 [[TMP2]]
504   %2 = lshr i50 %0, 8
505   %3 = and i50 %2, 255
506   %4 = shl i50 %0, 8
507   %5 = and i50 %4, 65280
508   %6 = or i50 %3, %5
509   ret i50 %6
512 define i32 @PR39793_bswap_u32_as_u16(i32 %0) {
513 ; CHECK-LABEL: @PR39793_bswap_u32_as_u16(
514 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[TMP0:%.*]] to i16
515 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]])
516 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i16 [[REV]] to i32
517 ; CHECK-NEXT:    ret i32 [[TMP2]]
519   %2 = lshr i32 %0, 8
520   %3 = and i32 %2, 255
521   %4 = shl i32 %0, 8
522   %5 = and i32 %4, 65280
523   %6 = or i32 %3, %5
524   ret i32 %6
527 define i8 @PR39793_bswap_u32_as_u16_trunc(i32 %0) {
528 ; CHECK-LABEL: @PR39793_bswap_u32_as_u16_trunc(
529 ; CHECK-NEXT:    [[REV1:%.*]] = lshr i32 [[TMP0:%.*]], 8
530 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[REV1]] to i8
531 ; CHECK-NEXT:    ret i8 [[TMP2]]
533   %2 = lshr i32 %0, 8
534   %3 = and i32 %2, 255
535   %4 = shl i32 %0, 8
536   %5 = and i32 %4, 65280
537   %6 = or i32 %3, %5
538   %7 = trunc i32 %6 to i8
539   ret i8 %7
542 define i32 @partial_bswap(i32 %x) {
543 ; CHECK-LABEL: @partial_bswap(
544 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
545 ; CHECK-NEXT:    ret i32 [[R]]
547   %x3 = shl i32 %x, 24
548   %a2 = shl i32 %x, 8
549   %x2 = and i32 %a2, 16711680
550   %x32 = or i32 %x3, %x2
551   %t1 = and i32 %x, -65536
552   %t2 = call i32 @llvm.bswap.i32(i32 %t1)
553   %r = or i32 %x32, %t2
554   ret i32 %r
556 declare i32 @llvm.bswap.i32(i32)
558 define <2 x i32> @partial_bswap_vector(<2 x i32> %x) {
559 ; CHECK-LABEL: @partial_bswap_vector(
560 ; CHECK-NEXT:    [[R:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[X:%.*]])
561 ; CHECK-NEXT:    ret <2 x i32> [[R]]
563   %x3 = shl <2 x i32> %x, <i32 24, i32 24>
564   %a2 = shl <2 x i32> %x, <i32 8, i32 8>
565   %x2 = and <2 x i32> %a2, <i32 16711680, i32 16711680>
566   %x32 = or <2 x i32> %x3, %x2
567   %t1 = and <2 x i32> %x, <i32 -65536, i32 -65536>
568   %t2 = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> %t1)
569   %r = or <2 x i32> %x32, %t2
570   ret <2 x i32> %r
572 declare <2 x i32> @llvm.bswap.v2i32(<2 x i32>)
574 define i16 @partial_bitreverse(i16 %x) {
575 ; CHECK-LABEL: @partial_bitreverse(
576 ; CHECK-NEXT:    [[OR:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])
577 ; CHECK-NEXT:    ret i16 [[OR]]
579   %rev= call i16 @llvm.bitreverse.i16(i16 %x)
580   %lo = and i16 %rev, 255
581   %hi = and i16 %rev, -256
582   %revlo = call i16 @llvm.bitreverse.i16(i16 %lo)
583   %revhi = call i16 @llvm.bitreverse.i16(i16 %hi)
584   %newlo = lshr i16 %revlo, 8
585   %newhi = shl  i16 %revhi, 8
586   %or = or i16 %newlo, %newhi
587   ret i16 %or
589 declare i16 @llvm.bitreverse.i16(i16)
591 define i64 @bswap_and_mask_0(i64 %0) {
592 ; CHECK-LABEL: @bswap_and_mask_0(
593 ; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP0:%.*]], -72057594037927681
594 ; CHECK-NEXT:    [[TMP3:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP2]])
595 ; CHECK-NEXT:    ret i64 [[TMP3]]
597   %2 = lshr i64 %0, 56
598   %3 = shl i64 %0, 56
599   %4 = or i64 %2, %3
600   ret i64 %4
603 define i64 @bswap_and_mask_1(i64 %0) {
604 ; CHECK-LABEL: @bswap_and_mask_1(
605 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i64 [[TMP0:%.*]], 56
606 ; CHECK-NEXT:    [[TMP3:%.*]] = lshr i64 [[TMP0]], 40
607 ; CHECK-NEXT:    [[TMP4:%.*]] = and i64 [[TMP3]], 65280
608 ; CHECK-NEXT:    [[TMP5:%.*]] = or disjoint i64 [[TMP4]], [[TMP2]]
609 ; CHECK-NEXT:    ret i64 [[TMP5]]
611   %2 = lshr i64 %0, 56
612   %3 = lshr i64 %0, 40
613   %4 = and i64 %3, 65280
614   %5 = or i64 %4, %2
615   ret i64 %5
618 define i64 @bswap_and_mask_2(i64 %0) {
619 ; CHECK-LABEL: @bswap_and_mask_2(
620 ; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP0:%.*]], -72057594037862401
621 ; CHECK-NEXT:    [[TMP3:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP2]])
622 ; CHECK-NEXT:    ret i64 [[TMP3]]
624   %2 = lshr i64 %0, 56
625   %3 = shl i64 %0, 56
626   %4 = or i64 %2, %3
627   %5 = shl i64 %0, 40
628   %6 = and i64 %5, 71776119061217280
629   %7 = or i64 %4, %6
630   ret i64 %7
633 define i64 @bswap_trunc(i64 %x01234567) {
634 ; CHECK-LABEL: @bswap_trunc(
635 ; CHECK-NEXT:    [[X76543210:%.*]] = call i64 @llvm.bswap.i64(i64 [[X01234567:%.*]])
636 ; CHECK-NEXT:    ret i64 [[X76543210]]
638   %x7zzzzzzz = shl i64 %x01234567, 56
639   %xz0123456 = lshr i64 %x01234567, 8
640   %xzzzzz012 = lshr i64 %x01234567, 40
641   %x3456 = trunc i64 %xz0123456 to i32
642   %xz012 = trunc i64 %xzzzzz012 to i32
643   %x6543 = call i32 @llvm.bswap.i32(i32 %x3456)
644   %x210z = call i32 @llvm.bswap.i32(i32 %xz012)
645   %xz210 = lshr i32 %x210z, 8
646   %xzzzz6543 = zext i32 %x6543 to i64
647   %xzzzzz210 = zext i32 %xz210 to i64
648   %xz6543zzz = shl i64 %xzzzz6543, 24
649   %xz6543210 = or i64 %xzzzzz210, %xz6543zzz
650   %x76543210 = or i64 %xz6543210, %x7zzzzzzz
651   ret i64 %x76543210
654 define i32 @shuf_4bytes(<4 x i8> %x) {
655 ; CHECK-LABEL: @shuf_4bytes(
656 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i8> [[X:%.*]] to i32
657 ; CHECK-NEXT:    [[CAST:%.*]] = call i32 @llvm.bswap.i32(i32 [[TMP1]])
658 ; CHECK-NEXT:    ret i32 [[CAST]]
660   %bswap = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
661   %cast = bitcast <4 x i8> %bswap to i32
662   ret i32 %cast
665 define i32 @shuf_load_4bytes(ptr %p) {
666 ; CHECK-LABEL: @shuf_load_4bytes(
667 ; CHECK-NEXT:    [[X1:%.*]] = load i32, ptr [[P:%.*]], align 4
668 ; CHECK-NEXT:    [[CAST:%.*]] = call i32 @llvm.bswap.i32(i32 [[X1]])
669 ; CHECK-NEXT:    ret i32 [[CAST]]
671   %x = load <4 x i8>, ptr %p
672   %bswap = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> <i32 3, i32 2, i32 poison, i32 0>
673   %cast = bitcast <4 x i8> %bswap to i32
674   ret i32 %cast
677 define i32 @shuf_bitcast_twice_4bytes(i32 %x) {
678 ; CHECK-LABEL: @shuf_bitcast_twice_4bytes(
679 ; CHECK-NEXT:    [[CAST2:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
680 ; CHECK-NEXT:    ret i32 [[CAST2]]
682   %cast1 = bitcast i32 %x to <4 x i8>
683   %bswap = shufflevector <4 x i8> %cast1, <4 x i8> poison, <4 x i32> <i32 poison, i32 2, i32 1, i32 0>
684   %cast2 = bitcast <4 x i8> %bswap to i32
685   ret i32 %cast2
688 ; Negative test - extra use
689 declare void @use(<4 x i8>)
691 define i32 @shuf_4bytes_extra_use(<4 x i8> %x) {
692 ; CHECK-LABEL: @shuf_4bytes_extra_use(
693 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
694 ; CHECK-NEXT:    call void @use(<4 x i8> [[BSWAP]])
695 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
696 ; CHECK-NEXT:    ret i32 [[CAST]]
698   %bswap = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
699   call void @use(<4 x i8> %bswap)
700   %cast = bitcast <4 x i8> %bswap to i32
701   ret i32 %cast
704 ; Negative test - scalar type is not in the data layout
706 define i128 @shuf_16bytes(<16 x i8> %x) {
707 ; CHECK-LABEL: @shuf_16bytes(
708 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <16 x i8> [[X:%.*]], <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
709 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <16 x i8> [[BSWAP]] to i128
710 ; CHECK-NEXT:    ret i128 [[CAST]]
712   %bswap = shufflevector <16 x i8> %x, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
713   %cast = bitcast <16 x i8> %bswap to i128
714   ret i128 %cast
717 ; Negative test - don't touch widening shuffles (for now)
719 define i32 @shuf_2bytes_widening(<2 x i8> %x) {
720 ; CHECK-LABEL: @shuf_2bytes_widening(
721 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> poison, <4 x i32> <i32 1, i32 0, i32 poison, i32 poison>
722 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
723 ; CHECK-NEXT:    ret i32 [[CAST]]
725   %bswap = shufflevector <2 x i8> %x, <2 x i8> poison, <4 x i32> <i32 1, i32 0, i32 poison, i32 poison>
726   %cast = bitcast <4 x i8> %bswap to i32
727   ret i32 %cast
730 declare i32 @llvm.fshl.i32(i32, i32, i32)
731 declare i32 @llvm.fshr.i32(i32, i32, i32)
733 define i32 @funnel_unary(i32 %abcd) {
734 ; CHECK-LABEL: @funnel_unary(
735 ; CHECK-NEXT:    [[DCBA:%.*]] = call i32 @llvm.bswap.i32(i32 [[ABCD:%.*]])
736 ; CHECK-NEXT:    ret i32 [[DCBA]]
738   %dabc = call i32 @llvm.fshl.i32(i32 %abcd, i32 %abcd, i32 24)
739   %bcda = call i32 @llvm.fshr.i32(i32 %abcd, i32 %abcd, i32 24)
740   %dzbz = and i32 %dabc, -16711936
741   %zcza = and i32 %bcda,  16711935
742   %dcba = or i32 %dzbz, %zcza
743   ret i32 %dcba
746 define i32 @funnel_binary(i32 %abcd) {
747 ; CHECK-LABEL: @funnel_binary(
748 ; CHECK-NEXT:    [[DCBA:%.*]] = call i32 @llvm.bswap.i32(i32 [[ABCD:%.*]])
749 ; CHECK-NEXT:    ret i32 [[DCBA]]
751   %cdzz = shl i32 %abcd, 16
752   %dcdz = call i32 @llvm.fshl.i32(i32 %abcd, i32 %cdzz, i32 24)
753   %zzab = lshr i32 %abcd, 16
754   %zaba = call i32 @llvm.fshr.i32(i32 %zzab, i32 %abcd, i32 24)
755   %dczz = and i32 %dcdz, -65536
756   %zzba = and i32 %zaba,  65535
757   %dcba = or i32 %dczz, %zzba
758   ret i32 %dcba
761 define i32 @funnel_and(i32 %abcd) {
762 ; CHECK-LABEL: @funnel_and(
763 ; CHECK-NEXT:    [[DCBA:%.*]] = call i32 @llvm.bswap.i32(i32 [[ABCD:%.*]])
764 ; CHECK-NEXT:    ret i32 [[DCBA]]
766   %zzcz = and i32 %abcd, 65280
767   %zcza = call i32 @llvm.fshl.i32(i32 %zzcz, i32 %abcd, i32 8)
768   %zbzz = and i32 %abcd, 16711680
769   %dzbz = call i32 @llvm.fshl.i32(i32 %abcd, i32 %zbzz, i32 24)
770   %dcba = or i32 %zcza, %dzbz
771   ret i32 %dcba
774 ; Don't attempt to collectBitParts from >128 bit integers
775 define i16 @trunc_bswap_i160(ptr %a0) {
776 ; CHECK-LABEL: @trunc_bswap_i160(
777 ; CHECK-NEXT:    [[LOAD:%.*]] = load i160, ptr [[A0:%.*]], align 4
778 ; CHECK-NEXT:    [[LSHR1:%.*]] = lshr i160 [[LOAD]], 136
779 ; CHECK-NEXT:    [[CAST1:%.*]] = trunc i160 [[LSHR1]] to i16
780 ; CHECK-NEXT:    [[AND1:%.*]] = and i16 [[CAST1]], 255
781 ; CHECK-NEXT:    [[SH_DIFF:%.*]] = lshr i160 [[LOAD]], 120
782 ; CHECK-NEXT:    [[TR_SH_DIFF:%.*]] = trunc i160 [[SH_DIFF]] to i16
783 ; CHECK-NEXT:    [[SHL:%.*]] = and i16 [[TR_SH_DIFF]], -256
784 ; CHECK-NEXT:    [[OR:%.*]] = or disjoint i16 [[AND1]], [[SHL]]
785 ; CHECK-NEXT:    ret i16 [[OR]]
787   %load = load i160, ptr %a0, align 4
788   %lshr0 = lshr i160 %load, 128
789   %lshr1 = lshr i160 %load, 136
790   %cast0 = trunc i160 %lshr0 to i16
791   %cast1 = trunc i160 %lshr1 to i16
792   %and0 = and i16 %cast0, 255
793   %and1 = and i16 %cast1, 255
794   %shl = shl i16 %and0, 8
795   %or = or i16 %and1, %shl
796   ret i16 %or
799 ; PR47191 - deep IR trees prevent ADD/XOR instructions being simplified to OR.
801 define i64 @PR47191_problem1(i64 %0) {
802 ; CHECK-LABEL: @PR47191_problem1(
803 ; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
804 ; CHECK-NEXT:    ret i64 [[TMP2]]
806   %2 = lshr i64 %0, 56
807   %3 = lshr i64 %0, 40
808   %4 = and i64 %3, 65280
809   %5 = lshr i64 %0, 24
810   %6 = and i64 %5, 16711680
811   %7 = lshr i64 %0, 8
812   %8 = and i64 %7, 4278190080
813   %9 = shl i64 %0, 56
814   %10 = shl i64 %0, 40
815   %11 = and i64 %10, 71776119061217280
816   %12 = shl i64 %0, 24
817   %13 = and i64 %12, 280375465082880
818   %14 = or i64 %9, %2
819   %15 = or i64 %14, %4
820   %16 = or i64 %15, %6
821   %17 = or i64 %16, %8
822   %18 = or i64 %17, %11
823   %19 = or i64 %18, %13
824   %20 = shl i64 %0, 8
825   %21 = and i64 %20, 1095216660480
826   %22 = add i64 %19, %21
827   ret i64 %22
830 define i64 @PR47191_problem2(i64 %0) {
831 ; CHECK-LABEL: @PR47191_problem2(
832 ; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
833 ; CHECK-NEXT:    ret i64 [[TMP2]]
835   %2 = lshr i64 %0, 56
836   %3 = lshr i64 %0, 40
837   %4 = and i64 %3, 65280
838   %5 = lshr i64 %0, 24
839   %6 = and i64 %5, 16711680
840   %7 = lshr i64 %0, 8
841   %8 = and i64 %7, 4278190080
842   %9 = shl i64 %0, 56
843   %10 = shl i64 %0, 40
844   %11 = and i64 %10, 71776119061217280
845   %12 = or i64 %9, %2
846   %13 = or i64 %12, %4
847   %14 = or i64 %13, %6
848   %15 = or i64 %14, %8
849   %16 = or i64 %15, %11
850   %17 = shl i64 %0, 24
851   %18 = and i64 %17, 280375465082880
852   %19 = shl i64 %0, 8
853   %20 = and i64 %19, 1095216660480
854   %21 = or i64 %20, %18
855   %22 = xor i64 %21, %16
856   ret i64 %22
859 define i64 @PR47191_problem3(i64 %0) {
860 ; CHECK-LABEL: @PR47191_problem3(
861 ; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
862 ; CHECK-NEXT:    ret i64 [[TMP2]]
864   %2 = lshr i64 %0, 56
865   %3 = lshr i64 %0, 40
866   %4 = and i64 %3, 65280
867   %5 = lshr i64 %0, 24
868   %6 = and i64 %5, 16711680
869   %7 = lshr i64 %0, 8
870   %8 = and i64 %7, 4278190080
871   %9 = shl i64 %0, 56
872   %10 = shl i64 %0, 40
873   %11 = and i64 %10, 71776119061217280
874   %12 = or i64 %9, %2
875   %13 = or i64 %12, %4
876   %14 = or i64 %13, %6
877   %15 = or i64 %14, %8
878   %16 = or i64 %15, %11
879   %17 = shl i64 %0, 24
880   %18 = and i64 %17, 280375465082880
881   %19 = shl i64 %0, 8
882   %20 = and i64 %19, 1095216660480
883   %21 = or i64 %20, %18
884   %22 = xor i64 %21, %16
885   ret i64 %22
888 define i64 @PR47191_problem4(i64 %0) {
889 ; CHECK-LABEL: @PR47191_problem4(
890 ; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
891 ; CHECK-NEXT:    ret i64 [[TMP2]]
893   %2 = lshr i64 %0, 56
894   %3 = shl i64 %0, 56
895   %4 = or i64 %2, %3
896   %5 = lshr i64 %0, 40
897   %6 = and i64 %5, 65280
898   %7 = or i64 %4, %6
899   %8 = shl i64 %0, 40
900   %9 = and i64 %8, 71776119061217280
901   %10 = or i64 %7, %9
902   %11 = lshr i64 %0, 24
903   %12 = and i64 %11, 16711680
904   %13 = or i64 %10, %12
905   %14 = shl i64 %0, 24
906   %15 = and i64 %14, 280375465082880
907   %16 = or i64 %13, %15
908   %17 = lshr i64 %0, 8
909   %18 = and i64 %17, 4278190080
910   %19 = or i64 %16, %18
911   %20 = shl i64 %0, 8
912   %21 = and i64 %20, 1095216660480
913   %22 = add i64 %19, %21
914   ret i64 %22
917 declare i64 @llvm.bswap.i64(i64)
919 define i32 @PR50910(i64 %t0) {
920 ; CHECK-LABEL: @PR50910(
921 ; CHECK-NEXT:    [[T5:%.*]] = call i64 @llvm.bswap.i64(i64 [[T0:%.*]])
922 ; CHECK-NEXT:    [[T6:%.*]] = trunc i64 [[T5]] to i32
923 ; CHECK-NEXT:    ret i32 [[T6]]
925   %t2 = and i64 %t0, 72057594037927935
926   %t3 = call i64 @llvm.bswap.i64(i64 %t2)
927   %t4 = lshr i64 %t0, 56
928   %t5 = or i64 %t3, %t4
929   %t6 = trunc i64 %t5 to i32
930   ret i32 %t6
933 define i64 @PR60690_call_fshl(i64 %result) {
934 ; CHECK-LABEL: @PR60690_call_fshl(
935 ; CHECK-NEXT:    [[OR_I12:%.*]] = call i64 @llvm.bswap.i64(i64 [[RESULT:%.*]])
936 ; CHECK-NEXT:    ret i64 [[OR_I12]]
938   %and.i = lshr i64 %result, 8
939   %shr.i = and i64 %and.i, 71777214294589695
940   %and1.i = shl i64 %result, 8
941   %shl.i = and i64 %and1.i, -71777214294589696
942   %or.i = or i64 %shr.i, %shl.i
943   %and.i7 = shl i64 %or.i, 16
944   %shl.i8 = and i64 %and.i7, -281470681808896
945   %and1.i9 = lshr i64 %or.i, 16
946   %shr.i10 = and i64 %and1.i9, 281470681808895
947   %or.i11 = or i64 %shl.i8, %shr.i10
948   %or.i12 = tail call i64 @llvm.fshl.i64(i64 %or.i11, i64 %or.i11, i64 32)
949   ret i64 %or.i12
951 declare i64 @llvm.fshl.i64(i64, i64, i64)
953 define i64 @PR60690_call_fshr(i64 %result) {
954 ; CHECK-LABEL: @PR60690_call_fshr(
955 ; CHECK-NEXT:    [[OR_I12:%.*]] = call i64 @llvm.bswap.i64(i64 [[RESULT:%.*]])
956 ; CHECK-NEXT:    ret i64 [[OR_I12]]
958   %and.i = lshr i64 %result, 8
959   %shr.i = and i64 %and.i, 71777214294589695
960   %and1.i = shl i64 %result, 8
961   %shl.i = and i64 %and1.i, -71777214294589696
962   %or.i = or i64 %shr.i, %shl.i
963   %and.i7 = shl i64 %or.i, 16
964   %shl.i8 = and i64 %and.i7, -281470681808896
965   %and1.i9 = lshr i64 %or.i, 16
966   %shr.i10 = and i64 %and1.i9, 281470681808895
967   %or.i11 = or i64 %shl.i8, %shr.i10
968   %or.i12 = tail call i64 @llvm.fshr.i64(i64 %or.i11, i64 %or.i11, i64 32)
969   ret i64 %or.i12
971 declare i64 @llvm.fshr.i64(i64, i64, i64)