xref: /llvm-project/llvm/test/Transforms/InstCombine/bswap.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4target 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"
5
6define 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]]
10;
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
21}
22
23define <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]]
27;
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
38}
39
40define 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]]
48;
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
55}
56
57define 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]]
66;
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
74}
75
76define 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]]
80;
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
91}
92
93define <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]]
97;
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
108}
109
110define <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]]
122;
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
133}
134
135define 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]]
139;
140  %t2 = lshr i16 %s, 8
141  %t4 = shl i16 %s, 8
142  %t5 = or i16 %t2, %t4
143  ret i16 %t5
144}
145
146define <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]]
150;
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
155}
156
157define <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]]
161;
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
166}
167
168define 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]]
172;
173  %t2 = lshr i16 %s, 8
174  %t4 = shl i16 %s, 8
175  %t5 = or i16 %t4, %t2
176  ret i16 %t5
177}
178
179define <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]]
183;
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
188}
189
190define 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]]
194;
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
207}
208
209define <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]]
213;
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
226}
227
228; PR2842
229define 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]]
233;
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
244}
245
246define <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]]
250;
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
261}
262
263declare void @extra_use(i32)
264
265; swaphalf = (x << 16 | x >> 16)
266; ((swaphalf & 0x00ff00ff) << 8) | ((swaphalf >> 8) & 0x00ff00ff)
267
268define 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]]
272;
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
282}
283
284; Extra use should not prevent matching to bswap.
285; swaphalf = (x << 16 | x >> 16)
286; ((swaphalf & 0x00ff00ff) << 8) | ((swaphalf >> 8) & 0x00ff00ff)
287
288define 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]]
295;
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
306}
307
308; swaphalf = (x << 16 | x >> 16)
309; ((swaphalf << 8) & 0xff00ff00) | ((swaphalf >> 8) & 0x00ff00ff)
310
311; PR23863
312define 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]]
316;
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
326}
327
328; Extra use should not prevent matching to bswap.
329; swaphalf = (x << 16 | x >> 16)
330; ((swaphalf << 8) & 0xff00ff00) | ((swaphalf >> 8) & 0x00ff00ff)
331
332define 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]]
339;
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
350}
351
352define 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]]
356;
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
364}
365
366define 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]]
370;
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
377}
378
379define 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]]
384;
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
392}
393
394define <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]]
399;
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
407}
408
409define 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]]
415;
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
428}
429
430define 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]]
436;
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
450}
451
452define 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]]
458;
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
465}
466
467define <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]]
473;
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
480}
481
482define 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]]
487;
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
495}
496
497define 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]]
503;
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
510}
511
512define 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]]
518;
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
525}
526
527define 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]]
532;
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
540}
541
542define 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]]
546;
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
555}
556declare i32 @llvm.bswap.i32(i32)
557
558define <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]]
562;
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
571}
572declare <2 x i32> @llvm.bswap.v2i32(<2 x i32>)
573
574define 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]]
578;
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
588}
589declare i16 @llvm.bitreverse.i16(i16)
590
591define 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]]
596;
597  %2 = lshr i64 %0, 56
598  %3 = shl i64 %0, 56
599  %4 = or i64 %2, %3
600  ret i64 %4
601}
602
603define 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]]
610;
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
616}
617
618define 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]]
623;
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
631}
632
633define 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]]
637;
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
652}
653
654define 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]]
659;
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
663}
664
665define 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]]
670;
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
675}
676
677define 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]]
681;
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
686}
687
688; Negative test - extra use
689declare void @use(<4 x i8>)
690
691define 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]]
697;
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
702}
703
704; Negative test - scalar type is not in the data layout
705
706define 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]]
711;
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
715}
716
717; Negative test - don't touch widening shuffles (for now)
718
719define 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]]
724;
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
728}
729
730declare i32 @llvm.fshl.i32(i32, i32, i32)
731declare i32 @llvm.fshr.i32(i32, i32, i32)
732
733define 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]]
737;
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
744}
745
746define 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]]
750;
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
759}
760
761define 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]]
765;
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
772}
773
774; Don't attempt to collectBitParts from >128 bit integers
775define 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]]
786;
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
797}
798
799; PR47191 - deep IR trees prevent ADD/XOR instructions being simplified to OR.
800
801define 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]]
805;
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
828}
829
830define 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]]
834;
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
857}
858
859define 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]]
863;
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
886}
887
888define 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]]
892;
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
915}
916
917declare i64 @llvm.bswap.i64(i64)
918
919define 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]]
924;
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
931}
932
933define 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]]
937;
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
950}
951declare i64 @llvm.fshl.i64(i64, i64, i64)
952
953define 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]]
957;
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
970}
971declare i64 @llvm.fshr.i64(i64, i64, i64)
972