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) {
8 ; CHECK-NEXT: [[T12:%.*]] = call i32 @llvm.bswap.i32(i32 [[I:%.*]])
9 ; CHECK-NEXT: ret i32 [[T12]]
13 %t4 = and i32 %t3, 65280
16 %t8 = and i32 %t7, 16711680
19 %t12 = or i32 %t9, %t11
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
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 i32 [[T1]], [[T4]]
46 ; CHECK-NEXT: [[T13:%.*]] = trunc i32 [[T5]] to i16
47 ; CHECK-NEXT: ret i16 [[T13]]
51 %t4 = and i32 %t3, 65280
53 %t13 = trunc i32 %t5 to i16
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 i32 [[T1]], [[T4]]
63 ; CHECK-NEXT: call void @extra_use(i32 [[T5]])
64 ; CHECK-NEXT: [[T13:%.*]] = trunc i32 [[T5]] to i16
65 ; CHECK-NEXT: ret i16 [[T13]]
69 %t4 = and i32 %t3, 65280
71 call void @extra_use(i32 %t5)
72 %t13 = trunc i32 %t5 to i16
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
83 %t5 = and i32 %t4, 16711680
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
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
110 define <2 x i32> @test2_vector_undef(<2 x i32> %arg) {
111 ; CHECK-LABEL: @test2_vector_undef(
112 ; CHECK-NEXT: [[T2:%.*]] = shl <2 x i32> [[ARG:%.*]], <i32 24, i32 undef>
113 ; CHECK-NEXT: [[T4:%.*]] = shl <2 x i32> [[ARG]], <i32 8, i32 8>
114 ; CHECK-NEXT: [[T5:%.*]] = and <2 x i32> [[T4]], <i32 16711680, i32 undef>
115 ; CHECK-NEXT: [[T6:%.*]] = or <2 x i32> [[T2]], [[T5]]
116 ; CHECK-NEXT: [[T8:%.*]] = lshr <2 x i32> [[ARG]], <i32 8, i32 8>
117 ; CHECK-NEXT: [[T9:%.*]] = and <2 x i32> [[T8]], <i32 65280, i32 undef>
118 ; CHECK-NEXT: [[T10:%.*]] = or <2 x i32> [[T6]], [[T9]]
119 ; CHECK-NEXT: [[T12:%.*]] = lshr <2 x i32> [[ARG]], <i32 24, i32 undef>
120 ; CHECK-NEXT: [[T14:%.*]] = or <2 x i32> [[T10]], [[T12]]
121 ; CHECK-NEXT: ret <2 x i32> [[T14]]
123 %t2 = shl <2 x i32> %arg, <i32 24, i32 undef>
124 %t4 = shl <2 x i32> %arg, <i32 8, i32 8>
125 %t5 = and <2 x i32> %t4, <i32 16711680, i32 undef>
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 undef>
129 %t10 = or <2 x i32> %t6, %t9
130 %t12 = lshr <2 x i32> %arg, <i32 24, i32 undef>
131 %t14 = or <2 x i32> %t10, %t12
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]]
142 %t5 = or i16 %t2, %t4
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
157 define <2 x i16> @test3_vector_undef(<2 x i16> %s) {
158 ; CHECK-LABEL: @test3_vector_undef(
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 undef, i16 8>
163 %t4 = shl <2 x i16> %s, <i16 8, i16 undef>
164 %t5 = or <2 x i16> %t2, %t4
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]]
175 %t5 = or i16 %t4, %t2
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
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
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
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
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]]
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
241 %t6 = lshr i32 %x, 24
242 %t7 = or i32 %t5, %t6
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
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
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)
308 ; swaphalf = (x << 16 | x >> 16)
309 ; ((swaphalf << 8) & 0xff00ff00) | ((swaphalf >> 8) & 0x00ff00ff)
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
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)
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
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
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
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>
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]]
419 %5 = and i64 %4, 65280
422 %8 = and i64 %7, 16711680
425 %11 = and i64 %10, 4278190080
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]]
440 %5 = and i64 %4, 65280
443 %8 = and i64 %7, 16711680
446 %11 = and i64 %10, 4278190080
448 %13 = trunc i64 %12 to i16
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]]
462 %5 = and i64 %4, 65280
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
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]]
491 %5 = and i64 %4, 65280
493 %7 = trunc i64 %6 to i8
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]]
507 %5 = and i50 %4, 65280
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]]
522 %5 = and i32 %4, 65280
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]]
536 %5 = and i32 %4, 65280
538 %7 = trunc i32 %6 to i8
542 define i32 @partial_bswap(i32 %x) {
543 ; CHECK-LABEL: @partial_bswap(
544 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
545 ; CHECK-NEXT: ret i32 [[TMP1]]
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
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: [[TMP1:%.*]] = call <2 x i32> @llvm.bswap.v2i32(<2 x i32> [[X:%.*]])
561 ; CHECK-NEXT: ret <2 x i32> [[TMP1]]
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
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
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]]
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 i64 [[TMP4]], [[TMP2]]
609 ; CHECK-NEXT: ret i64 [[TMP5]]
613 %4 = and i64 %3, 65280
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]]
628 %6 = and i64 %5, 71776119061217280
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
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> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
661 %cast = bitcast <4 x i8> %bswap to i32
665 define i32 @shuf_load_4bytes(<4 x i8>* %p) {
666 ; CHECK-LABEL: @shuf_load_4bytes(
667 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i8>* [[P:%.*]] to i32*
668 ; CHECK-NEXT: [[X1:%.*]] = load i32, i32* [[TMP1]], align 4
669 ; CHECK-NEXT: [[CAST:%.*]] = call i32 @llvm.bswap.i32(i32 [[X1]])
670 ; CHECK-NEXT: ret i32 [[CAST]]
672 %x = load <4 x i8>, <4 x i8>* %p
673 %bswap = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 undef, i32 0>
674 %cast = bitcast <4 x i8> %bswap to i32
678 define i32 @shuf_bitcast_twice_4bytes(i32 %x) {
679 ; CHECK-LABEL: @shuf_bitcast_twice_4bytes(
680 ; CHECK-NEXT: [[CAST2:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
681 ; CHECK-NEXT: ret i32 [[CAST2]]
683 %cast1 = bitcast i32 %x to <4 x i8>
684 %bswap = shufflevector <4 x i8> %cast1, <4 x i8> undef, <4 x i32> <i32 undef, i32 2, i32 1, i32 0>
685 %cast2 = bitcast <4 x i8> %bswap to i32
689 ; Negative test - extra use
690 declare void @use(<4 x i8>)
692 define i32 @shuf_4bytes_extra_use(<4 x i8> %x) {
693 ; CHECK-LABEL: @shuf_4bytes_extra_use(
694 ; CHECK-NEXT: [[BSWAP:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
695 ; CHECK-NEXT: call void @use(<4 x i8> [[BSWAP]])
696 ; CHECK-NEXT: [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
697 ; CHECK-NEXT: ret i32 [[CAST]]
699 %bswap = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
700 call void @use(<4 x i8> %bswap)
701 %cast = bitcast <4 x i8> %bswap to i32
705 ; Negative test - scalar type is not in the data layout
707 define i128 @shuf_16bytes(<16 x i8> %x) {
708 ; CHECK-LABEL: @shuf_16bytes(
709 ; 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>
710 ; CHECK-NEXT: [[CAST:%.*]] = bitcast <16 x i8> [[BSWAP]] to i128
711 ; CHECK-NEXT: ret i128 [[CAST]]
713 %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>
714 %cast = bitcast <16 x i8> %bswap to i128
718 ; Negative test - don't touch widening shuffles (for now)
720 define i32 @shuf_2bytes_widening(<2 x i8> %x) {
721 ; CHECK-LABEL: @shuf_2bytes_widening(
722 ; CHECK-NEXT: [[BSWAP:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> undef, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
723 ; CHECK-NEXT: [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
724 ; CHECK-NEXT: ret i32 [[CAST]]
726 %bswap = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
727 %cast = bitcast <4 x i8> %bswap to i32
731 declare i32 @llvm.fshl.i32(i32, i32, i32)
732 declare i32 @llvm.fshr.i32(i32, i32, i32)
734 define i32 @funnel_unary(i32 %abcd) {
735 ; CHECK-LABEL: @funnel_unary(
736 ; CHECK-NEXT: [[DCBA:%.*]] = call i32 @llvm.bswap.i32(i32 [[ABCD:%.*]])
737 ; CHECK-NEXT: ret i32 [[DCBA]]
739 %dabc = call i32 @llvm.fshl.i32(i32 %abcd, i32 %abcd, i32 24)
740 %bcda = call i32 @llvm.fshr.i32(i32 %abcd, i32 %abcd, i32 24)
741 %dzbz = and i32 %dabc, -16711936
742 %zcza = and i32 %bcda, 16711935
743 %dcba = or i32 %dzbz, %zcza
747 define i32 @funnel_binary(i32 %abcd) {
748 ; CHECK-LABEL: @funnel_binary(
749 ; CHECK-NEXT: [[DCBA:%.*]] = call i32 @llvm.bswap.i32(i32 [[ABCD:%.*]])
750 ; CHECK-NEXT: ret i32 [[DCBA]]
752 %cdzz = shl i32 %abcd, 16
753 %dcdz = call i32 @llvm.fshl.i32(i32 %abcd, i32 %cdzz, i32 24)
754 %zzab = lshr i32 %abcd, 16
755 %zaba = call i32 @llvm.fshr.i32(i32 %zzab, i32 %abcd, i32 24)
756 %dczz = and i32 %dcdz, -65536
757 %zzba = and i32 %zaba, 65535
758 %dcba = or i32 %dczz, %zzba
762 define i32 @funnel_and(i32 %abcd) {
763 ; CHECK-LABEL: @funnel_and(
764 ; CHECK-NEXT: [[DCBA:%.*]] = call i32 @llvm.bswap.i32(i32 [[ABCD:%.*]])
765 ; CHECK-NEXT: ret i32 [[DCBA]]
767 %zzcz = and i32 %abcd, 65280
768 %zcza = call i32 @llvm.fshl.i32(i32 %zzcz, i32 %abcd, i32 8)
769 %zbzz = and i32 %abcd, 16711680
770 %dzbz = call i32 @llvm.fshl.i32(i32 %abcd, i32 %zbzz, i32 24)
771 %dcba = or i32 %zcza, %dzbz
775 ; Don't attempt to collectBitParts from >128 bit integers
776 define i16 @trunc_bswap_i160(i160* %a0) {
777 ; CHECK-LABEL: @trunc_bswap_i160(
778 ; CHECK-NEXT: [[LOAD:%.*]] = load i160, i160* [[A0:%.*]], align 4
779 ; CHECK-NEXT: [[LSHR1:%.*]] = lshr i160 [[LOAD]], 136
780 ; CHECK-NEXT: [[CAST1:%.*]] = trunc i160 [[LSHR1]] to i16
781 ; CHECK-NEXT: [[AND1:%.*]] = and i16 [[CAST1]], 255
782 ; CHECK-NEXT: [[SH_DIFF:%.*]] = lshr i160 [[LOAD]], 120
783 ; CHECK-NEXT: [[TR_SH_DIFF:%.*]] = trunc i160 [[SH_DIFF]] to i16
784 ; CHECK-NEXT: [[SHL:%.*]] = and i16 [[TR_SH_DIFF]], -256
785 ; CHECK-NEXT: [[OR:%.*]] = or i16 [[AND1]], [[SHL]]
786 ; CHECK-NEXT: ret i16 [[OR]]
788 %load = load i160, i160* %a0, align 4
789 %lshr0 = lshr i160 %load, 128
790 %lshr1 = lshr i160 %load, 136
791 %cast0 = trunc i160 %lshr0 to i16
792 %cast1 = trunc i160 %lshr1 to i16
793 %and0 = and i16 %cast0, 255
794 %and1 = and i16 %cast1, 255
795 %shl = shl i16 %and0, 8
796 %or = or i16 %and1, %shl
800 ; PR47191 - deep IR trees prevent ADD/XOR instructions being simplified to OR.
802 define i64 @PR47191_problem1(i64 %0) {
803 ; CHECK-LABEL: @PR47191_problem1(
804 ; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
805 ; CHECK-NEXT: ret i64 [[TMP2]]
809 %4 = and i64 %3, 65280
811 %6 = and i64 %5, 16711680
813 %8 = and i64 %7, 4278190080
816 %11 = and i64 %10, 71776119061217280
818 %13 = and i64 %12, 280375465082880
823 %18 = or i64 %17, %11
824 %19 = or i64 %18, %13
826 %21 = and i64 %20, 1095216660480
827 %22 = add i64 %19, %21
831 define i64 @PR47191_problem2(i64 %0) {
832 ; CHECK-LABEL: @PR47191_problem2(
833 ; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
834 ; CHECK-NEXT: ret i64 [[TMP2]]
838 %4 = and i64 %3, 65280
840 %6 = and i64 %5, 16711680
842 %8 = and i64 %7, 4278190080
845 %11 = and i64 %10, 71776119061217280
850 %16 = or i64 %15, %11
852 %18 = and i64 %17, 280375465082880
854 %20 = and i64 %19, 1095216660480
855 %21 = or i64 %20, %18
856 %22 = xor i64 %21, %16
860 define i64 @PR47191_problem3(i64 %0) {
861 ; CHECK-LABEL: @PR47191_problem3(
862 ; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
863 ; CHECK-NEXT: ret i64 [[TMP2]]
867 %4 = and i64 %3, 65280
869 %6 = and i64 %5, 16711680
871 %8 = and i64 %7, 4278190080
874 %11 = and i64 %10, 71776119061217280
879 %16 = or i64 %15, %11
881 %18 = and i64 %17, 280375465082880
883 %20 = and i64 %19, 1095216660480
884 %21 = or i64 %20, %18
885 %22 = xor i64 %21, %16
889 define i64 @PR47191_problem4(i64 %0) {
890 ; CHECK-LABEL: @PR47191_problem4(
891 ; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP0:%.*]])
892 ; CHECK-NEXT: ret i64 [[TMP2]]
898 %6 = and i64 %5, 65280
901 %9 = and i64 %8, 71776119061217280
903 %11 = lshr i64 %0, 24
904 %12 = and i64 %11, 16711680
905 %13 = or i64 %10, %12
907 %15 = and i64 %14, 280375465082880
908 %16 = or i64 %13, %15
910 %18 = and i64 %17, 4278190080
911 %19 = or i64 %16, %18
913 %21 = and i64 %20, 1095216660480
914 %22 = add i64 %19, %21
918 declare i64 @llvm.bswap.i64(i64)
920 define i32 @PR50910(i64 %t0) {
921 ; CHECK-LABEL: @PR50910(
922 ; CHECK-NEXT: [[T5:%.*]] = call i64 @llvm.bswap.i64(i64 [[T0:%.*]])
923 ; CHECK-NEXT: [[T6:%.*]] = trunc i64 [[T5]] to i32
924 ; CHECK-NEXT: ret i32 [[T6]]
926 %t2 = and i64 %t0, 72057594037927935
927 %t3 = call i64 @llvm.bswap.i64(i64 %t2)
928 %t4 = lshr i64 %t0, 56
929 %t5 = or i64 %t3, %t4
930 %t6 = trunc i64 %t5 to i32