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) {
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 disjoint i32 [[T1]], [[T4]]
46 ; CHECK-NEXT: [[T13:%.*]] = trunc nuw 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 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]]
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_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
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_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
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: [[R:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
545 ; CHECK-NEXT: ret i32 [[R]]
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: [[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
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 disjoint 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> poison, <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(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
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
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
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
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
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
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
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
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
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]]
808 %4 = and i64 %3, 65280
810 %6 = and i64 %5, 16711680
812 %8 = and i64 %7, 4278190080
815 %11 = and i64 %10, 71776119061217280
817 %13 = and i64 %12, 280375465082880
822 %18 = or i64 %17, %11
823 %19 = or i64 %18, %13
825 %21 = and i64 %20, 1095216660480
826 %22 = add i64 %19, %21
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]]
837 %4 = and i64 %3, 65280
839 %6 = and i64 %5, 16711680
841 %8 = and i64 %7, 4278190080
844 %11 = and i64 %10, 71776119061217280
849 %16 = or i64 %15, %11
851 %18 = and i64 %17, 280375465082880
853 %20 = and i64 %19, 1095216660480
854 %21 = or i64 %20, %18
855 %22 = xor i64 %21, %16
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]]
866 %4 = and i64 %3, 65280
868 %6 = and i64 %5, 16711680
870 %8 = and i64 %7, 4278190080
873 %11 = and i64 %10, 71776119061217280
878 %16 = or i64 %15, %11
880 %18 = and i64 %17, 280375465082880
882 %20 = and i64 %19, 1095216660480
883 %21 = or i64 %20, %18
884 %22 = xor i64 %21, %16
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]]
897 %6 = and i64 %5, 65280
900 %9 = and i64 %8, 71776119061217280
902 %11 = lshr i64 %0, 24
903 %12 = and i64 %11, 16711680
904 %13 = or i64 %10, %12
906 %15 = and i64 %14, 280375465082880
907 %16 = or i64 %13, %15
909 %18 = and i64 %17, 4278190080
910 %19 = or i64 %16, %18
912 %21 = and i64 %20, 1095216660480
913 %22 = add i64 %19, %21
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
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)
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)
971 declare i64 @llvm.fshr.i64(i64, i64, i64)