[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / bswap.ll
blob32caf4a89d60eaf3376f799acc10ed684be40fb3
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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 i32 @test2(i32 %arg) {
41 ; CHECK-LABEL: @test2(
42 ; CHECK-NEXT:    [[T14:%.*]] = call i32 @llvm.bswap.i32(i32 [[ARG:%.*]])
43 ; CHECK-NEXT:    ret i32 [[T14]]
45   %t2 = shl i32 %arg, 24
46   %t4 = shl i32 %arg, 8
47   %t5 = and i32 %t4, 16711680
48   %t6 = or i32 %t2, %t5
49   %t8 = lshr i32 %arg, 8
50   %t9 = and i32 %t8, 65280
51   %t10 = or i32 %t6, %t9
52   %t12 = lshr i32 %arg, 24
53   %t14 = or i32 %t10, %t12
54   ret i32 %t14
57 define <2 x i32> @test2_vector(<2 x i32> %arg) {
58 ; CHECK-LABEL: @test2_vector(
59 ; CHECK-NEXT:    [[T14:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[ARG:%.*]])
60 ; CHECK-NEXT:    ret <2 x i32> [[T14]]
62   %t2 = shl <2 x i32> %arg, <i32 24, i32 24>
63   %t4 = shl <2 x i32> %arg, <i32 8, i32 8>
64   %t5 = and <2 x i32> %t4, <i32 16711680, i32 16711680>
65   %t6 = or <2 x i32> %t2, %t5
66   %t8 = lshr <2 x i32> %arg, <i32 8, i32 8>
67   %t9 = and <2 x i32> %t8, <i32 65280, i32 65280>
68   %t10 = or <2 x i32> %t6, %t9
69   %t12 = lshr <2 x i32> %arg, <i32 24, i32 24>
70   %t14 = or <2 x i32> %t10, %t12
71   ret <2 x i32> %t14
74 define <2 x i32> @test2_vector_undef(<2 x i32> %arg) {
75 ; CHECK-LABEL: @test2_vector_undef(
76 ; CHECK-NEXT:    [[T2:%.*]] = shl <2 x i32> [[ARG:%.*]], <i32 24, i32 undef>
77 ; CHECK-NEXT:    [[T4:%.*]] = shl <2 x i32> [[ARG]], <i32 8, i32 8>
78 ; CHECK-NEXT:    [[T5:%.*]] = and <2 x i32> [[T4]], <i32 16711680, i32 undef>
79 ; CHECK-NEXT:    [[T6:%.*]] = or <2 x i32> [[T2]], [[T5]]
80 ; CHECK-NEXT:    [[T8:%.*]] = lshr <2 x i32> [[ARG]], <i32 8, i32 8>
81 ; CHECK-NEXT:    [[T9:%.*]] = and <2 x i32> [[T8]], <i32 65280, i32 undef>
82 ; CHECK-NEXT:    [[T10:%.*]] = or <2 x i32> [[T6]], [[T9]]
83 ; CHECK-NEXT:    [[T12:%.*]] = lshr <2 x i32> [[ARG]], <i32 24, i32 undef>
84 ; CHECK-NEXT:    [[T14:%.*]] = or <2 x i32> [[T10]], [[T12]]
85 ; CHECK-NEXT:    ret <2 x i32> [[T14]]
87   %t2 = shl <2 x i32> %arg, <i32 24, i32 undef>
88   %t4 = shl <2 x i32> %arg, <i32 8, i32 8>
89   %t5 = and <2 x i32> %t4, <i32 16711680, i32 undef>
90   %t6 = or <2 x i32> %t2, %t5
91   %t8 = lshr <2 x i32> %arg, <i32 8, i32 8>
92   %t9 = and <2 x i32> %t8, <i32 65280, i32 undef>
93   %t10 = or <2 x i32> %t6, %t9
94   %t12 = lshr <2 x i32> %arg, <i32 24, i32 undef>
95   %t14 = or <2 x i32> %t10, %t12
96   ret <2 x i32> %t14
99 define i16 @test3(i16 %s) {
100 ; CHECK-LABEL: @test3(
101 ; CHECK-NEXT:    [[T5:%.*]] = call i16 @llvm.bswap.i16(i16 [[S:%.*]])
102 ; CHECK-NEXT:    ret i16 [[T5]]
104   %t2 = lshr i16 %s, 8
105   %t4 = shl i16 %s, 8
106   %t5 = or i16 %t2, %t4
107   ret i16 %t5
110 define <2 x i16> @test3_vector(<2 x i16> %s) {
111 ; CHECK-LABEL: @test3_vector(
112 ; CHECK-NEXT:    [[T5:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[S:%.*]])
113 ; CHECK-NEXT:    ret <2 x i16> [[T5]]
115   %t2 = lshr <2 x i16> %s, <i16 8, i16 8>
116   %t4 = shl <2 x i16> %s, <i16 8, i16 8>
117   %t5 = or <2 x i16> %t2, %t4
118   ret <2 x i16> %t5
121 define <2 x i16> @test3_vector_undef(<2 x i16> %s) {
122 ; CHECK-LABEL: @test3_vector_undef(
123 ; CHECK-NEXT:    [[T5:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[S:%.*]])
124 ; CHECK-NEXT:    ret <2 x i16> [[T5]]
126   %t2 = lshr <2 x i16> %s, <i16 undef, i16 8>
127   %t4 = shl <2 x i16> %s, <i16 8, i16 undef>
128   %t5 = or <2 x i16> %t2, %t4
129   ret <2 x i16> %t5
132 define i16 @test4(i16 %s) {
133 ; CHECK-LABEL: @test4(
134 ; CHECK-NEXT:    [[T5:%.*]] = call i16 @llvm.bswap.i16(i16 [[S:%.*]])
135 ; CHECK-NEXT:    ret i16 [[T5]]
137   %t2 = lshr i16 %s, 8
138   %t4 = shl i16 %s, 8
139   %t5 = or i16 %t4, %t2
140   ret i16 %t5
143 define <2 x i16> @test4_vector(<2 x i16> %s) {
144 ; CHECK-LABEL: @test4_vector(
145 ; CHECK-NEXT:    [[T5:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[S:%.*]])
146 ; CHECK-NEXT:    ret <2 x i16> [[T5]]
148   %t2 = lshr <2 x i16> %s, <i16 8, i16 8>
149   %t4 = shl <2 x i16> %s, <i16 8, i16 8>
150   %t5 = or <2 x i16> %t4, %t2
151   ret <2 x i16> %t5
154 define i16 @test5(i16 %a) {
155 ; CHECK-LABEL: @test5(
156 ; CHECK-NEXT:    [[T_UPGRD_3:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])
157 ; CHECK-NEXT:    ret i16 [[T_UPGRD_3]]
159   %t = zext i16 %a to i32
160   %t1 = and i32 %t, 65280
161   %t2 = ashr i32 %t1, 8
162   %t2.upgrd.1 = trunc i32 %t2 to i16
163   %t4 = and i32 %t, 255
164   %t5 = shl i32 %t4, 8
165   %t5.upgrd.2 = trunc i32 %t5 to i16
166   %t.upgrd.3 = or i16 %t2.upgrd.1, %t5.upgrd.2
167   %t6 = bitcast i16 %t.upgrd.3 to i16
168   %t6.upgrd.4 = zext i16 %t6 to i32
169   %retval = trunc i32 %t6.upgrd.4 to i16
170   ret i16 %retval
173 define <2 x i16> @test5_vector(<2 x i16> %a) {
174 ; CHECK-LABEL: @test5_vector(
175 ; CHECK-NEXT:    [[T_UPGRD_3:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[A:%.*]])
176 ; CHECK-NEXT:    ret <2 x i16> [[T_UPGRD_3]]
178   %t = zext <2 x i16> %a to <2 x i32>
179   %t1 = and <2 x i32> %t, <i32 65280, i32 65280>
180   %t2 = ashr <2 x i32> %t1, <i32 8, i32 8>
181   %t2.upgrd.1 = trunc <2 x i32> %t2 to <2 x i16>
182   %t4 = and <2 x i32> %t, <i32 255, i32 255>
183   %t5 = shl <2 x i32> %t4, <i32 8, i32 8>
184   %t5.upgrd.2 = trunc <2 x i32> %t5 to <2 x i16>
185   %t.upgrd.3 = or <2 x i16> %t2.upgrd.1, %t5.upgrd.2
186   %t6 = bitcast <2 x i16> %t.upgrd.3 to <2 x i16>
187   %t6.upgrd.4 = zext <2 x i16> %t6 to <2 x i32>
188   %retval = trunc <2 x i32> %t6.upgrd.4 to <2 x i16>
189   ret <2 x i16> %retval
192 ; PR2842
193 define i32 @test6(i32 %x) nounwind readnone {
194 ; CHECK-LABEL: @test6(
195 ; CHECK-NEXT:    [[T7:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
196 ; CHECK-NEXT:    ret i32 [[T7]]
198   %t = shl i32 %x, 16
199   %x.mask = and i32 %x, 65280
200   %t1 = lshr i32 %x, 16
201   %t2 = and i32 %t1, 255
202   %t3 = or i32 %x.mask, %t
203   %t4 = or i32 %t3, %t2
204   %t5 = shl i32 %t4, 8
205   %t6 = lshr i32 %x, 24
206   %t7 = or i32 %t5, %t6
207   ret i32 %t7
210 define <2 x i32> @test6_vector(<2 x i32> %x) nounwind readnone {
211 ; CHECK-LABEL: @test6_vector(
212 ; CHECK-NEXT:    [[T7:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[X:%.*]])
213 ; CHECK-NEXT:    ret <2 x i32> [[T7]]
215   %t = shl <2 x i32> %x, <i32 16, i32 16>
216   %x.mask = and <2 x i32> %x, <i32 65280, i32 65280>
217   %t1 = lshr <2 x i32> %x, <i32 16, i32 16>
218   %t2 = and <2 x i32> %t1, <i32 255, i32 255>
219   %t3 = or <2 x i32> %x.mask, %t
220   %t4 = or <2 x i32> %t3, %t2
221   %t5 = shl <2 x i32> %t4, <i32 8, i32 8>
222   %t6 = lshr <2 x i32> %x, <i32 24, i32 24>
223   %t7 = or <2 x i32> %t5, %t6
224   ret <2 x i32> %t7
227 declare void @extra_use(i32)
229 ; swaphalf = (x << 16 | x >> 16)
230 ; ((swaphalf & 0x00ff00ff) << 8) | ((swaphalf >> 8) & 0x00ff00ff)
232 define i32 @bswap32_and_first(i32 %x) {
233 ; CHECK-LABEL: @bswap32_and_first(
234 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
235 ; CHECK-NEXT:    ret i32 [[BSWAP]]
237   %shl = shl i32 %x, 16
238   %shr = lshr i32 %x, 16
239   %swaphalf = or i32 %shl, %shr
240   %t = and i32 %swaphalf, 16711935
241   %tshl = shl nuw i32 %t, 8
242   %b = lshr i32 %swaphalf, 8
243   %band = and i32 %b, 16711935
244   %bswap = or i32 %tshl, %band
245   ret i32 %bswap
248 ; Extra use should not prevent matching to bswap.
249 ; swaphalf = (x << 16 | x >> 16)
250 ; ((swaphalf & 0x00ff00ff) << 8) | ((swaphalf >> 8) & 0x00ff00ff)
252 define i32 @bswap32_and_first_extra_use(i32 %x) {
253 ; CHECK-LABEL: @bswap32_and_first_extra_use(
254 ; CHECK-NEXT:    [[SWAPHALF:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 16)
255 ; CHECK-NEXT:    [[T:%.*]] = and i32 [[SWAPHALF]], 16711935
256 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X]])
257 ; CHECK-NEXT:    call void @extra_use(i32 [[T]])
258 ; CHECK-NEXT:    ret i32 [[BSWAP]]
260   %shl = shl i32 %x, 16
261   %shr = lshr i32 %x, 16
262   %swaphalf = or i32 %shl, %shr
263   %t = and i32 %swaphalf, 16711935
264   %tshl = shl nuw i32 %t, 8
265   %b = lshr i32 %swaphalf, 8
266   %band = and i32 %b, 16711935
267   %bswap = or i32 %tshl, %band
268   call void @extra_use(i32 %t)
269   ret i32 %bswap
272 ; swaphalf = (x << 16 | x >> 16)
273 ; ((swaphalf << 8) & 0xff00ff00) | ((swaphalf >> 8) & 0x00ff00ff)
275 ; PR23863
276 define i32 @bswap32_shl_first(i32 %x) {
277 ; CHECK-LABEL: @bswap32_shl_first(
278 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
279 ; CHECK-NEXT:    ret i32 [[BSWAP]]
281   %shl = shl i32 %x, 16
282   %shr = lshr i32 %x, 16
283   %swaphalf = or i32 %shl, %shr
284   %t = shl i32 %swaphalf, 8
285   %tand = and i32 %t, -16711936
286   %b = lshr i32 %swaphalf, 8
287   %band = and i32 %b, 16711935
288   %bswap = or i32 %tand, %band
289   ret i32 %bswap
292 ; Extra use should not prevent matching to bswap.
293 ; swaphalf = (x << 16 | x >> 16)
294 ; ((swaphalf << 8) & 0xff00ff00) | ((swaphalf >> 8) & 0x00ff00ff)
296 define i32 @bswap32_shl_first_extra_use(i32 %x) {
297 ; CHECK-LABEL: @bswap32_shl_first_extra_use(
298 ; CHECK-NEXT:    [[SWAPHALF:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 16)
299 ; CHECK-NEXT:    [[T:%.*]] = shl i32 [[SWAPHALF]], 8
300 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X]])
301 ; CHECK-NEXT:    call void @extra_use(i32 [[T]])
302 ; CHECK-NEXT:    ret i32 [[BSWAP]]
304   %shl = shl i32 %x, 16
305   %shr = lshr i32 %x, 16
306   %swaphalf = or i32 %shl, %shr
307   %t = shl i32 %swaphalf, 8
308   %tand = and i32 %t, -16711936
309   %b = lshr i32 %swaphalf, 8
310   %band = and i32 %b, 16711935
311   %bswap = or i32 %tand, %band
312   call void @extra_use(i32 %t)
313   ret i32 %bswap
316 define i16 @test8(i16 %a) {
317 ; CHECK-LABEL: @test8(
318 ; CHECK-NEXT:    [[OR:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])
319 ; CHECK-NEXT:    ret i16 [[OR]]
321   %conv = zext i16 %a to i32
322   %shr = lshr i16 %a, 8
323   %shl = shl i32 %conv, 8
324   %conv1 = zext i16 %shr to i32
325   %or = or i32 %conv1, %shl
326   %conv2 = trunc i32 %or to i16
327   ret i16 %conv2
330 define i16 @test9(i16 %a) {
331 ; CHECK-LABEL: @test9(
332 ; CHECK-NEXT:    [[OR:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])
333 ; CHECK-NEXT:    ret i16 [[OR]]
335   %conv = zext i16 %a to i32
336   %shr = lshr i32 %conv, 8
337   %shl = shl i32 %conv, 8
338   %or = or i32 %shr, %shl
339   %conv2 = trunc i32 %or to i16
340   ret i16 %conv2
343 define i16 @test10(i32 %a) {
344 ; CHECK-LABEL: @test10(
345 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[A:%.*]] to i16
346 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]])
347 ; CHECK-NEXT:    ret i16 [[REV]]
349   %shr1 = lshr i32 %a, 8
350   %and1 = and i32 %shr1, 255
351   %and2 = shl i32 %a, 8
352   %shl1 = and i32 %and2, 65280
353   %or = or i32 %and1, %shl1
354   %conv = trunc i32 %or to i16
355   ret i16 %conv
358 define <2 x i16> @test10_vector(<2 x i32> %a) {
359 ; CHECK-LABEL: @test10_vector(
360 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <2 x i32> [[A:%.*]] to <2 x i16>
361 ; CHECK-NEXT:    [[REV:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[TRUNC]])
362 ; CHECK-NEXT:    ret <2 x i16> [[REV]]
364   %shr1 = lshr <2 x i32> %a, <i32 8, i32 8>
365   %and1 = and <2 x i32> %shr1, <i32 255, i32 255>
366   %and2 = shl <2 x i32> %a, <i32 8, i32 8>
367   %shl1 = and <2 x i32> %and2, <i32 65280, i32 65280>
368   %or = or <2 x i32> %and1, %shl1
369   %conv = trunc <2 x i32> %or to <2 x i16>
370   ret <2 x i16> %conv
373 define i64 @PR39793_bswap_u64_as_u32(i64 %0) {
374 ; CHECK-LABEL: @PR39793_bswap_u64_as_u32(
375 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[TMP0:%.*]] to i32
376 ; CHECK-NEXT:    [[REV:%.*]] = call i32 @llvm.bswap.i32(i32 [[TRUNC]])
377 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[REV]] to i64
378 ; CHECK-NEXT:    ret i64 [[TMP2]]
380   %2 = lshr i64 %0, 24
381   %3 = and i64 %2, 255
382   %4 = lshr i64 %0, 8
383   %5 = and i64 %4, 65280
384   %6 = or i64 %3, %5
385   %7 = shl i64 %0, 8
386   %8 = and i64 %7, 16711680
387   %9 = or i64 %6, %8
388   %10 = shl i64 %0, 24
389   %11 = and i64 %10, 4278190080
390   %12 = or i64 %9, %11
391   ret i64 %12
394 define i16 @PR39793_bswap_u64_as_u32_trunc(i64 %0) {
395 ; CHECK-LABEL: @PR39793_bswap_u64_as_u32_trunc(
396 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[TMP0:%.*]] to i32
397 ; CHECK-NEXT:    [[REV:%.*]] = call i32 @llvm.bswap.i32(i32 [[TRUNC]])
398 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[REV]] to i16
399 ; CHECK-NEXT:    ret i16 [[TMP2]]
401   %2 = lshr i64 %0, 24
402   %3 = and i64 %2, 255
403   %4 = lshr i64 %0, 8
404   %5 = and i64 %4, 65280
405   %6 = or i64 %3, %5
406   %7 = shl i64 %0, 8
407   %8 = and i64 %7, 16711680
408   %9 = or i64 %6, %8
409   %10 = shl i64 %0, 24
410   %11 = and i64 %10, 4278190080
411   %12 = or i64 %9, %11
412   %13 = trunc i64 %12 to i16
413   ret i16 %13
416 define i64 @PR39793_bswap_u64_as_u16(i64 %0) {
417 ; CHECK-LABEL: @PR39793_bswap_u64_as_u16(
418 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[TMP0:%.*]] to i16
419 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]])
420 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i16 [[REV]] to i64
421 ; CHECK-NEXT:    ret i64 [[TMP2]]
423   %2 = lshr i64 %0, 8
424   %3 = and i64 %2, 255
425   %4 = shl i64 %0, 8
426   %5 = and i64 %4, 65280
427   %6 = or i64 %3, %5
428   ret i64 %6
431 define <2 x i64> @PR39793_bswap_u64_as_u16_vector(<2 x i64> %0) {
432 ; CHECK-LABEL: @PR39793_bswap_u64_as_u16_vector(
433 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <2 x i64> [[TMP0:%.*]] to <2 x i16>
434 ; CHECK-NEXT:    [[REV:%.*]] = call <2 x i16> @llvm.bswap.v2i16(<2 x i16> [[TRUNC]])
435 ; CHECK-NEXT:    [[TMP2:%.*]] = zext <2 x i16> [[REV]] to <2 x i64>
436 ; CHECK-NEXT:    ret <2 x i64> [[TMP2]]
438   %2 = lshr <2 x i64> %0, <i64 8, i64 8>
439   %3 = and <2 x i64> %2, <i64 255, i64 255>
440   %4 = shl <2 x i64> %0, <i64 8, i64 8>
441   %5 = and <2 x i64> %4, <i64 65280, i64 65280>
442   %6 = or <2 x i64> %3, %5
443   ret <2 x i64> %6
446 define i8 @PR39793_bswap_u64_as_u16_trunc(i64 %0) {
447 ; CHECK-LABEL: @PR39793_bswap_u64_as_u16_trunc(
448 ; CHECK-NEXT:    [[REV1:%.*]] = lshr i64 [[TMP0:%.*]], 8
449 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[REV1]] to i8
450 ; CHECK-NEXT:    ret i8 [[TMP2]]
452   %2 = lshr i64 %0, 8
453   %3 = and i64 %2, 255
454   %4 = shl i64 %0, 8
455   %5 = and i64 %4, 65280
456   %6 = or i64 %3, %5
457   %7 = trunc i64 %6 to i8
458   ret i8 %7
461 define i50 @PR39793_bswap_u50_as_u16(i50 %0) {
462 ; CHECK-LABEL: @PR39793_bswap_u50_as_u16(
463 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i50 [[TMP0:%.*]] to i16
464 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]])
465 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i16 [[REV]] to i50
466 ; CHECK-NEXT:    ret i50 [[TMP2]]
468   %2 = lshr i50 %0, 8
469   %3 = and i50 %2, 255
470   %4 = shl i50 %0, 8
471   %5 = and i50 %4, 65280
472   %6 = or i50 %3, %5
473   ret i50 %6
476 define i32 @PR39793_bswap_u32_as_u16(i32 %0) {
477 ; CHECK-LABEL: @PR39793_bswap_u32_as_u16(
478 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[TMP0:%.*]] to i16
479 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]])
480 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i16 [[REV]] to i32
481 ; CHECK-NEXT:    ret i32 [[TMP2]]
483   %2 = lshr i32 %0, 8
484   %3 = and i32 %2, 255
485   %4 = shl i32 %0, 8
486   %5 = and i32 %4, 65280
487   %6 = or i32 %3, %5
488   ret i32 %6
491 define i8 @PR39793_bswap_u32_as_u16_trunc(i32 %0) {
492 ; CHECK-LABEL: @PR39793_bswap_u32_as_u16_trunc(
493 ; CHECK-NEXT:    [[REV1:%.*]] = lshr i32 [[TMP0:%.*]], 8
494 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i32 [[REV1]] to i8
495 ; CHECK-NEXT:    ret i8 [[TMP2]]
497   %2 = lshr i32 %0, 8
498   %3 = and i32 %2, 255
499   %4 = shl i32 %0, 8
500   %5 = and i32 %4, 65280
501   %6 = or i32 %3, %5
502   %7 = trunc i32 %6 to i8
503   ret i8 %7
506 define i32 @partial_bswap(i32 %x) {
507 ; CHECK-LABEL: @partial_bswap(
508 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
509 ; CHECK-NEXT:    ret i32 [[TMP1]]
511   %x3 = shl i32 %x, 24
512   %a2 = shl i32 %x, 8
513   %x2 = and i32 %a2, 16711680
514   %x32 = or i32 %x3, %x2
515   %t1 = and i32 %x, -65536
516   %t2 = call i32 @llvm.bswap.i32(i32 %t1)
517   %r = or i32 %x32, %t2
518   ret i32 %r
520 declare i32 @llvm.bswap.i32(i32)
522 define <2 x i32> @partial_bswap_vector(<2 x i32> %x) {
523 ; CHECK-LABEL: @partial_bswap_vector(
524 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[X:%.*]])
525 ; CHECK-NEXT:    ret <2 x i32> [[TMP1]]
527   %x3 = shl <2 x i32> %x, <i32 24, i32 24>
528   %a2 = shl <2 x i32> %x, <i32 8, i32 8>
529   %x2 = and <2 x i32> %a2, <i32 16711680, i32 16711680>
530   %x32 = or <2 x i32> %x3, %x2
531   %t1 = and <2 x i32> %x, <i32 -65536, i32 -65536>
532   %t2 = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> %t1)
533   %r = or <2 x i32> %x32, %t2
534   ret <2 x i32> %r
536 declare <2 x i32> @llvm.bswap.v2i32(<2 x i32>)
538 define i16 @partial_bitreverse(i16 %x) {
539 ; CHECK-LABEL: @partial_bitreverse(
540 ; CHECK-NEXT:    [[OR:%.*]] = call i16 @llvm.bswap.i16(i16 [[X:%.*]])
541 ; CHECK-NEXT:    ret i16 [[OR]]
543   %rev= call i16 @llvm.bitreverse.i16(i16 %x)
544   %lo = and i16 %rev, 255
545   %hi = and i16 %rev, -256
546   %revlo = call i16 @llvm.bitreverse.i16(i16 %lo)
547   %revhi = call i16 @llvm.bitreverse.i16(i16 %hi)
548   %newlo = lshr i16 %revlo, 8
549   %newhi = shl  i16 %revhi, 8
550   %or = or i16 %newlo, %newhi
551   ret i16 %or
553 declare i16 @llvm.bitreverse.i16(i16)
555 define i64 @bswap_and_mask_0(i64 %0) {
556 ; CHECK-LABEL: @bswap_and_mask_0(
557 ; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP0:%.*]], -72057594037927681
558 ; CHECK-NEXT:    [[TMP3:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP2]])
559 ; CHECK-NEXT:    ret i64 [[TMP3]]
561   %2 = lshr i64 %0, 56
562   %3 = shl i64 %0, 56
563   %4 = or i64 %2, %3
564   ret i64 %4
567 define i64 @bswap_and_mask_1(i64 %0) {
568 ; CHECK-LABEL: @bswap_and_mask_1(
569 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i64 [[TMP0:%.*]], 56
570 ; CHECK-NEXT:    [[TMP3:%.*]] = lshr i64 [[TMP0]], 40
571 ; CHECK-NEXT:    [[TMP4:%.*]] = and i64 [[TMP3]], 65280
572 ; CHECK-NEXT:    [[TMP5:%.*]] = or i64 [[TMP4]], [[TMP2]]
573 ; CHECK-NEXT:    ret i64 [[TMP5]]
575   %2 = lshr i64 %0, 56
576   %3 = lshr i64 %0, 40
577   %4 = and i64 %3, 65280
578   %5 = or i64 %4, %2
579   ret i64 %5
582 define i64 @bswap_and_mask_2(i64 %0) {
583 ; CHECK-LABEL: @bswap_and_mask_2(
584 ; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP0:%.*]], -72057594037862401
585 ; CHECK-NEXT:    [[TMP3:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP2]])
586 ; CHECK-NEXT:    ret i64 [[TMP3]]
588   %2 = lshr i64 %0, 56
589   %3 = shl i64 %0, 56
590   %4 = or i64 %2, %3
591   %5 = shl i64 %0, 40
592   %6 = and i64 %5, 71776119061217280
593   %7 = or i64 %4, %6
594   ret i64 %7
597 define i64 @bswap_trunc(i64 %x01234567) {
598 ; CHECK-LABEL: @bswap_trunc(
599 ; CHECK-NEXT:    [[X76543210:%.*]] = call i64 @llvm.bswap.i64(i64 [[X01234567:%.*]])
600 ; CHECK-NEXT:    ret i64 [[X76543210]]
602   %x7zzzzzzz = shl i64 %x01234567, 56
603   %xz0123456 = lshr i64 %x01234567, 8
604   %xzzzzz012 = lshr i64 %x01234567, 40
605   %x3456 = trunc i64 %xz0123456 to i32
606   %xz012 = trunc i64 %xzzzzz012 to i32
607   %x6543 = call i32 @llvm.bswap.i32(i32 %x3456)
608   %x210z = call i32 @llvm.bswap.i32(i32 %xz012)
609   %xz210 = lshr i32 %x210z, 8
610   %xzzzz6543 = zext i32 %x6543 to i64
611   %xzzzzz210 = zext i32 %xz210 to i64
612   %xz6543zzz = shl i64 %xzzzz6543, 24
613   %xz6543210 = or i64 %xzzzzz210, %xz6543zzz
614   %x76543210 = or i64 %xz6543210, %x7zzzzzzz
615   ret i64 %x76543210
618 define i32 @shuf_4bytes(<4 x i8> %x) {
619 ; CHECK-LABEL: @shuf_4bytes(
620 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i8> [[X:%.*]] to i32
621 ; CHECK-NEXT:    [[CAST:%.*]] = call i32 @llvm.bswap.i32(i32 [[TMP1]])
622 ; CHECK-NEXT:    ret i32 [[CAST]]
624   %bswap = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
625   %cast = bitcast <4 x i8> %bswap to i32
626   ret i32 %cast
629 define i32 @shuf_load_4bytes(<4 x i8>* %p) {
630 ; CHECK-LABEL: @shuf_load_4bytes(
631 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i8>* [[P:%.*]] to i32*
632 ; CHECK-NEXT:    [[X1:%.*]] = load i32, i32* [[TMP1]], align 4
633 ; CHECK-NEXT:    [[CAST:%.*]] = call i32 @llvm.bswap.i32(i32 [[X1]])
634 ; CHECK-NEXT:    ret i32 [[CAST]]
636   %x = load <4 x i8>, <4 x i8>* %p
637   %bswap = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 undef, i32 0>
638   %cast = bitcast <4 x i8> %bswap to i32
639   ret i32 %cast
642 define i32 @shuf_bitcast_twice_4bytes(i32 %x) {
643 ; CHECK-LABEL: @shuf_bitcast_twice_4bytes(
644 ; CHECK-NEXT:    [[CAST2:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
645 ; CHECK-NEXT:    ret i32 [[CAST2]]
647   %cast1 = bitcast i32 %x to <4 x i8>
648   %bswap = shufflevector <4 x i8> %cast1, <4 x i8> undef, <4 x i32> <i32 undef, i32 2, i32 1, i32 0>
649   %cast2 = bitcast <4 x i8> %bswap to i32
650   ret i32 %cast2
653 ; Negative test - extra use
654 declare void @use(<4 x i8>)
656 define i32 @shuf_4bytes_extra_use(<4 x i8> %x) {
657 ; CHECK-LABEL: @shuf_4bytes_extra_use(
658 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
659 ; CHECK-NEXT:    call void @use(<4 x i8> [[BSWAP]])
660 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
661 ; CHECK-NEXT:    ret i32 [[CAST]]
663   %bswap = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
664   call void @use(<4 x i8> %bswap)
665   %cast = bitcast <4 x i8> %bswap to i32
666   ret i32 %cast
669 ; Negative test - scalar type is not in the data layout
671 define i128 @shuf_16bytes(<16 x i8> %x) {
672 ; CHECK-LABEL: @shuf_16bytes(
673 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <16 x i8> [[X:%.*]], <16 x i8> undef, <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>
674 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <16 x i8> [[BSWAP]] to i128
675 ; CHECK-NEXT:    ret i128 [[CAST]]
677   %bswap = shufflevector <16 x i8> %x, <16 x i8> undef, <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>
678   %cast = bitcast <16 x i8> %bswap to i128
679   ret i128 %cast
682 ; Negative test - don't touch widening shuffles (for now)
684 define i32 @shuf_2bytes_widening(<2 x i8> %x) {
685 ; CHECK-LABEL: @shuf_2bytes_widening(
686 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> undef, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
687 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
688 ; CHECK-NEXT:    ret i32 [[CAST]]
690   %bswap = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
691   %cast = bitcast <4 x i8> %bswap to i32
692   ret i32 %cast
695 declare i32 @llvm.fshl.i32(i32, i32, i32)
696 declare i32 @llvm.fshr.i32(i32, i32, i32)
698 define i32 @funnel_unary(i32 %abcd) {
699 ; CHECK-LABEL: @funnel_unary(
700 ; CHECK-NEXT:    [[DCBA:%.*]] = call i32 @llvm.bswap.i32(i32 [[ABCD:%.*]])
701 ; CHECK-NEXT:    ret i32 [[DCBA]]
703   %dabc = call i32 @llvm.fshl.i32(i32 %abcd, i32 %abcd, i32 24)
704   %bcda = call i32 @llvm.fshr.i32(i32 %abcd, i32 %abcd, i32 24)
705   %dzbz = and i32 %dabc, -16711936
706   %zcza = and i32 %bcda,  16711935
707   %dcba = or i32 %dzbz, %zcza
708   ret i32 %dcba
711 define i32 @funnel_binary(i32 %abcd) {
712 ; CHECK-LABEL: @funnel_binary(
713 ; CHECK-NEXT:    [[DCBA:%.*]] = call i32 @llvm.bswap.i32(i32 [[ABCD:%.*]])
714 ; CHECK-NEXT:    ret i32 [[DCBA]]
716   %cdzz = shl i32 %abcd, 16
717   %dcdz = call i32 @llvm.fshl.i32(i32 %abcd, i32 %cdzz, i32 24)
718   %zzab = lshr i32 %abcd, 16
719   %zaba = call i32 @llvm.fshr.i32(i32 %zzab, i32 %abcd, i32 24)
720   %dczz = and i32 %dcdz, -65536
721   %zzba = and i32 %zaba,  65535
722   %dcba = or i32 %dczz, %zzba
723   ret i32 %dcba
726 define i32 @funnel_and(i32 %abcd) {
727 ; CHECK-LABEL: @funnel_and(
728 ; CHECK-NEXT:    [[DCBA:%.*]] = call i32 @llvm.bswap.i32(i32 [[ABCD:%.*]])
729 ; CHECK-NEXT:    ret i32 [[DCBA]]
731   %zzcz = and i32 %abcd, 65280
732   %zcza = call i32 @llvm.fshl.i32(i32 %zzcz, i32 %abcd, i32 8)
733   %zbzz = and i32 %abcd, 16711680
734   %dzbz = call i32 @llvm.fshl.i32(i32 %abcd, i32 %zbzz, i32 24)
735   %dcba = or i32 %zcza, %dzbz
736   ret i32 %dcba
739 ; Don't attempt to collectBitParts from >128 bit integers
740 define i16 @trunc_bswap_i160(i160* %a0) {
741 ; CHECK-LABEL: @trunc_bswap_i160(
742 ; CHECK-NEXT:    [[LOAD:%.*]] = load i160, i160* [[A0:%.*]], align 4
743 ; CHECK-NEXT:    [[LSHR1:%.*]] = lshr i160 [[LOAD]], 136
744 ; CHECK-NEXT:    [[CAST1:%.*]] = trunc i160 [[LSHR1]] to i16
745 ; CHECK-NEXT:    [[AND1:%.*]] = and i16 [[CAST1]], 255
746 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i160 [[LOAD]], 120
747 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i160 [[TMP1]] to i16
748 ; CHECK-NEXT:    [[SHL:%.*]] = and i16 [[TMP2]], -256
749 ; CHECK-NEXT:    [[OR:%.*]] = or i16 [[AND1]], [[SHL]]
750 ; CHECK-NEXT:    ret i16 [[OR]]
752   %load = load i160, i160* %a0, align 4
753   %lshr0 = lshr i160 %load, 128
754   %lshr1 = lshr i160 %load, 136
755   %cast0 = trunc i160 %lshr0 to i16
756   %cast1 = trunc i160 %lshr1 to i16
757   %and0 = and i16 %cast0, 255
758   %and1 = and i16 %cast1, 255
759   %shl = shl i16 %and0, 8
760   %or = or i16 %and1, %shl
761   ret i16 %or
764 ; PR47191 - deep IR trees prevent ADD/XOR instructions being simplified to OR.
766 define i64 @PR47191_problem1(i64 %0) {
767 ; CHECK-LABEL: @PR47191_problem1(
768 ; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
769 ; CHECK-NEXT:    ret i64 [[TMP2]]
771   %2 = lshr i64 %0, 56
772   %3 = lshr i64 %0, 40
773   %4 = and i64 %3, 65280
774   %5 = lshr i64 %0, 24
775   %6 = and i64 %5, 16711680
776   %7 = lshr i64 %0, 8
777   %8 = and i64 %7, 4278190080
778   %9 = shl i64 %0, 56
779   %10 = shl i64 %0, 40
780   %11 = and i64 %10, 71776119061217280
781   %12 = shl i64 %0, 24
782   %13 = and i64 %12, 280375465082880
783   %14 = or i64 %9, %2
784   %15 = or i64 %14, %4
785   %16 = or i64 %15, %6
786   %17 = or i64 %16, %8
787   %18 = or i64 %17, %11
788   %19 = or i64 %18, %13
789   %20 = shl i64 %0, 8
790   %21 = and i64 %20, 1095216660480
791   %22 = add i64 %19, %21
792   ret i64 %22
795 define i64 @PR47191_problem2(i64 %0) {
796 ; CHECK-LABEL: @PR47191_problem2(
797 ; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
798 ; CHECK-NEXT:    ret i64 [[TMP2]]
800   %2 = lshr i64 %0, 56
801   %3 = lshr i64 %0, 40
802   %4 = and i64 %3, 65280
803   %5 = lshr i64 %0, 24
804   %6 = and i64 %5, 16711680
805   %7 = lshr i64 %0, 8
806   %8 = and i64 %7, 4278190080
807   %9 = shl i64 %0, 56
808   %10 = shl i64 %0, 40
809   %11 = and i64 %10, 71776119061217280
810   %12 = or i64 %9, %2
811   %13 = or i64 %12, %4
812   %14 = or i64 %13, %6
813   %15 = or i64 %14, %8
814   %16 = or i64 %15, %11
815   %17 = shl i64 %0, 24
816   %18 = and i64 %17, 280375465082880
817   %19 = shl i64 %0, 8
818   %20 = and i64 %19, 1095216660480
819   %21 = or i64 %20, %18
820   %22 = xor i64 %21, %16
821   ret i64 %22
824 define i64 @PR47191_problem3(i64 %0) {
825 ; CHECK-LABEL: @PR47191_problem3(
826 ; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
827 ; CHECK-NEXT:    ret i64 [[TMP2]]
829   %2 = lshr i64 %0, 56
830   %3 = lshr i64 %0, 40
831   %4 = and i64 %3, 65280
832   %5 = lshr i64 %0, 24
833   %6 = and i64 %5, 16711680
834   %7 = lshr i64 %0, 8
835   %8 = and i64 %7, 4278190080
836   %9 = shl i64 %0, 56
837   %10 = shl i64 %0, 40
838   %11 = and i64 %10, 71776119061217280
839   %12 = or i64 %9, %2
840   %13 = or i64 %12, %4
841   %14 = or i64 %13, %6
842   %15 = or i64 %14, %8
843   %16 = or i64 %15, %11
844   %17 = shl i64 %0, 24
845   %18 = and i64 %17, 280375465082880
846   %19 = shl i64 %0, 8
847   %20 = and i64 %19, 1095216660480
848   %21 = or i64 %20, %18
849   %22 = xor i64 %21, %16
850   ret i64 %22
853 define i64 @PR47191_problem4(i64 %0) {
854 ; CHECK-LABEL: @PR47191_problem4(
855 ; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
856 ; CHECK-NEXT:    ret i64 [[TMP2]]
858   %2 = lshr i64 %0, 56
859   %3 = shl i64 %0, 56
860   %4 = or i64 %2, %3
861   %5 = lshr i64 %0, 40
862   %6 = and i64 %5, 65280
863   %7 = or i64 %4, %6
864   %8 = shl i64 %0, 40
865   %9 = and i64 %8, 71776119061217280
866   %10 = or i64 %7, %9
867   %11 = lshr i64 %0, 24
868   %12 = and i64 %11, 16711680
869   %13 = or i64 %10, %12
870   %14 = shl i64 %0, 24
871   %15 = and i64 %14, 280375465082880
872   %16 = or i64 %13, %15
873   %17 = lshr i64 %0, 8
874   %18 = and i64 %17, 4278190080
875   %19 = or i64 %16, %18
876   %20 = shl i64 %0, 8
877   %21 = and i64 %20, 1095216660480
878   %22 = add i64 %19, %21
879   ret i64 %22