[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / bswap.ll
blob2d8a69b86a59c6df0e6ed085495c37bc5d122bc9
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:    [[TMP12:%.*]] = call i32 @llvm.bswap.i32(i32 [[I:%.*]])
9 ; CHECK-NEXT:    ret i32 [[TMP12]]
11   %tmp1 = lshr i32 %i, 24
12   %tmp3 = lshr i32 %i, 8
13   %tmp4 = and i32 %tmp3, 65280
14   %tmp5 = or i32 %tmp1, %tmp4
15   %tmp7 = shl i32 %i, 8
16   %tmp8 = and i32 %tmp7, 16711680
17   %tmp9 = or i32 %tmp5, %tmp8
18   %tmp11 = shl i32 %i, 24
19   %tmp12 = or i32 %tmp9, %tmp11
20   ret i32 %tmp12
23 define i32 @test2(i32 %arg) {
24 ; CHECK-LABEL: @test2(
25 ; CHECK-NEXT:    [[TMP14:%.*]] = call i32 @llvm.bswap.i32(i32 [[ARG:%.*]])
26 ; CHECK-NEXT:    ret i32 [[TMP14]]
28   %tmp2 = shl i32 %arg, 24
29   %tmp4 = shl i32 %arg, 8
30   %tmp5 = and i32 %tmp4, 16711680
31   %tmp6 = or i32 %tmp2, %tmp5
32   %tmp8 = lshr i32 %arg, 8
33   %tmp9 = and i32 %tmp8, 65280
34   %tmp10 = or i32 %tmp6, %tmp9
35   %tmp12 = lshr i32 %arg, 24
36   %tmp14 = or i32 %tmp10, %tmp12
37   ret i32 %tmp14
40 define i16 @test3(i16 %s) {
41 ; CHECK-LABEL: @test3(
42 ; CHECK-NEXT:    [[TMP5:%.*]] = call i16 @llvm.bswap.i16(i16 [[S:%.*]])
43 ; CHECK-NEXT:    ret i16 [[TMP5]]
45   %tmp2 = lshr i16 %s, 8
46   %tmp4 = shl i16 %s, 8
47   %tmp5 = or i16 %tmp2, %tmp4
48   ret i16 %tmp5
51 define i16 @test4(i16 %s) {
52 ; CHECK-LABEL: @test4(
53 ; CHECK-NEXT:    [[TMP5:%.*]] = call i16 @llvm.bswap.i16(i16 [[S:%.*]])
54 ; CHECK-NEXT:    ret i16 [[TMP5]]
56   %tmp2 = lshr i16 %s, 8
57   %tmp4 = shl i16 %s, 8
58   %tmp5 = or i16 %tmp4, %tmp2
59   ret i16 %tmp5
62 define i16 @test5(i16 %a) {
63 ; CHECK-LABEL: @test5(
64 ; CHECK-NEXT:    [[TMP_UPGRD_3:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])
65 ; CHECK-NEXT:    ret i16 [[TMP_UPGRD_3]]
67   %tmp = zext i16 %a to i32
68   %tmp1 = and i32 %tmp, 65280
69   %tmp2 = ashr i32 %tmp1, 8
70   %tmp2.upgrd.1 = trunc i32 %tmp2 to i16
71   %tmp4 = and i32 %tmp, 255
72   %tmp5 = shl i32 %tmp4, 8
73   %tmp5.upgrd.2 = trunc i32 %tmp5 to i16
74   %tmp.upgrd.3 = or i16 %tmp2.upgrd.1, %tmp5.upgrd.2
75   %tmp6 = bitcast i16 %tmp.upgrd.3 to i16
76   %tmp6.upgrd.4 = zext i16 %tmp6 to i32
77   %retval = trunc i32 %tmp6.upgrd.4 to i16
78   ret i16 %retval
81 ; PR2842
82 define i32 @test6(i32 %x) nounwind readnone {
83 ; CHECK-LABEL: @test6(
84 ; CHECK-NEXT:    [[TMP7:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
85 ; CHECK-NEXT:    ret i32 [[TMP7]]
87   %tmp = shl i32 %x, 16
88   %x.mask = and i32 %x, 65280
89   %tmp1 = lshr i32 %x, 16
90   %tmp2 = and i32 %tmp1, 255
91   %tmp3 = or i32 %x.mask, %tmp
92   %tmp4 = or i32 %tmp3, %tmp2
93   %tmp5 = shl i32 %tmp4, 8
94   %tmp6 = lshr i32 %x, 24
95   %tmp7 = or i32 %tmp5, %tmp6
96   ret i32 %tmp7
99 declare void @extra_use(i32)
101 ; swaphalf = (x << 16 | x >> 16)
102 ; ((swaphalf & 0x00ff00ff) << 8) | ((swaphalf >> 8) & 0x00ff00ff)
104 define i32 @bswap32_and_first(i32 %x) {
105 ; CHECK-LABEL: @bswap32_and_first(
106 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
107 ; CHECK-NEXT:    ret i32 [[BSWAP]]
109   %shl = shl i32 %x, 16
110   %shr = lshr i32 %x, 16
111   %swaphalf = or i32 %shl, %shr
112   %t = and i32 %swaphalf, 16711935
113   %tshl = shl nuw i32 %t, 8
114   %b = lshr i32 %swaphalf, 8
115   %band = and i32 %b, 16711935
116   %bswap = or i32 %tshl, %band
117   ret i32 %bswap
120 ; Extra use should not prevent matching to bswap.
121 ; swaphalf = (x << 16 | x >> 16)
122 ; ((swaphalf & 0x00ff00ff) << 8) | ((swaphalf >> 8) & 0x00ff00ff)
124 define i32 @bswap32_and_first_extra_use(i32 %x) {
125 ; CHECK-LABEL: @bswap32_and_first_extra_use(
126 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], 16
127 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[X]], 16
128 ; CHECK-NEXT:    [[SWAPHALF:%.*]] = or i32 [[SHL]], [[SHR]]
129 ; CHECK-NEXT:    [[T:%.*]] = and i32 [[SWAPHALF]], 16711935
130 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X]])
131 ; CHECK-NEXT:    call void @extra_use(i32 [[T]])
132 ; CHECK-NEXT:    ret i32 [[BSWAP]]
134   %shl = shl i32 %x, 16
135   %shr = lshr i32 %x, 16
136   %swaphalf = or i32 %shl, %shr
137   %t = and i32 %swaphalf, 16711935
138   %tshl = shl nuw i32 %t, 8
139   %b = lshr i32 %swaphalf, 8
140   %band = and i32 %b, 16711935
141   %bswap = or i32 %tshl, %band
142   call void @extra_use(i32 %t)
143   ret i32 %bswap
146 ; swaphalf = (x << 16 | x >> 16)
147 ; ((swaphalf << 8) & 0xff00ff00) | ((swaphalf >> 8) & 0x00ff00ff)
149 ; PR23863
150 define i32 @bswap32_shl_first(i32 %x) {
151 ; CHECK-LABEL: @bswap32_shl_first(
152 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
153 ; CHECK-NEXT:    ret i32 [[BSWAP]]
155   %shl = shl i32 %x, 16
156   %shr = lshr i32 %x, 16
157   %swaphalf = or i32 %shl, %shr
158   %t = shl i32 %swaphalf, 8
159   %tand = and i32 %t, -16711936
160   %b = lshr i32 %swaphalf, 8
161   %band = and i32 %b, 16711935
162   %bswap = or i32 %tand, %band
163   ret i32 %bswap
166 ; Extra use should not prevent matching to bswap.
167 ; swaphalf = (x << 16 | x >> 16)
168 ; ((swaphalf << 8) & 0xff00ff00) | ((swaphalf >> 8) & 0x00ff00ff)
170 define i32 @bswap32_shl_first_extra_use(i32 %x) {
171 ; CHECK-LABEL: @bswap32_shl_first_extra_use(
172 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], 16
173 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[X]], 16
174 ; CHECK-NEXT:    [[SWAPHALF:%.*]] = or i32 [[SHL]], [[SHR]]
175 ; CHECK-NEXT:    [[T:%.*]] = shl i32 [[SWAPHALF]], 8
176 ; CHECK-NEXT:    [[BSWAP:%.*]] = call i32 @llvm.bswap.i32(i32 [[X]])
177 ; CHECK-NEXT:    call void @extra_use(i32 [[T]])
178 ; CHECK-NEXT:    ret i32 [[BSWAP]]
180   %shl = shl i32 %x, 16
181   %shr = lshr i32 %x, 16
182   %swaphalf = or i32 %shl, %shr
183   %t = shl i32 %swaphalf, 8
184   %tand = and i32 %t, -16711936
185   %b = lshr i32 %swaphalf, 8
186   %band = and i32 %b, 16711935
187   %bswap = or i32 %tand, %band
188   call void @extra_use(i32 %t)
189   ret i32 %bswap
192 define i16 @test8(i16 %a) {
193 ; CHECK-LABEL: @test8(
194 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])
195 ; CHECK-NEXT:    ret i16 [[REV]]
197   %conv = zext i16 %a to i32
198   %shr = lshr i16 %a, 8
199   %shl = shl i32 %conv, 8
200   %conv1 = zext i16 %shr to i32
201   %or = or i32 %conv1, %shl
202   %conv2 = trunc i32 %or to i16
203   ret i16 %conv2
206 define i16 @test9(i16 %a) {
207 ; CHECK-LABEL: @test9(
208 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[A:%.*]])
209 ; CHECK-NEXT:    ret i16 [[REV]]
211   %conv = zext i16 %a to i32
212   %shr = lshr i32 %conv, 8
213   %shl = shl i32 %conv, 8
214   %or = or i32 %shr, %shl
215   %conv2 = trunc i32 %or to i16
216   ret i16 %conv2
219 define i16 @test10(i32 %a) {
220 ; CHECK-LABEL: @test10(
221 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[A:%.*]] to i16
222 ; CHECK-NEXT:    [[REV:%.*]] = call i16 @llvm.bswap.i16(i16 [[TRUNC]])
223 ; CHECK-NEXT:    ret i16 [[REV]]
225   %shr1 = lshr i32 %a, 8
226   %and1 = and i32 %shr1, 255
227   %and2 = shl i32 %a, 8
228   %shl1 = and i32 %and2, 65280
229   %or = or i32 %and1, %shl1
230   %conv = trunc i32 %or to i16
231   ret i16 %conv
234 define i32 @shuf_4bytes(<4 x i8> %x) {
235 ; CHECK-LABEL: @shuf_4bytes(
236 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i8> [[X:%.*]] to i32
237 ; CHECK-NEXT:    [[CAST:%.*]] = call i32 @llvm.bswap.i32(i32 [[TMP1]])
238 ; CHECK-NEXT:    ret i32 [[CAST]]
240   %bswap = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
241   %cast = bitcast <4 x i8> %bswap to i32
242   ret i32 %cast
245 define i32 @shuf_load_4bytes(<4 x i8>* %p) {
246 ; CHECK-LABEL: @shuf_load_4bytes(
247 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i8>* [[P:%.*]] to i32*
248 ; CHECK-NEXT:    [[X1:%.*]] = load i32, i32* [[TMP1]], align 4
249 ; CHECK-NEXT:    [[CAST:%.*]] = call i32 @llvm.bswap.i32(i32 [[X1]])
250 ; CHECK-NEXT:    ret i32 [[CAST]]
252   %x = load <4 x i8>, <4 x i8>* %p
253   %bswap = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 undef, i32 0>
254   %cast = bitcast <4 x i8> %bswap to i32
255   ret i32 %cast
258 define i32 @shuf_bitcast_twice_4bytes(i32 %x) {
259 ; CHECK-LABEL: @shuf_bitcast_twice_4bytes(
260 ; CHECK-NEXT:    [[CAST2:%.*]] = call i32 @llvm.bswap.i32(i32 [[X:%.*]])
261 ; CHECK-NEXT:    ret i32 [[CAST2]]
263   %cast1 = bitcast i32 %x to <4 x i8>
264   %bswap = shufflevector <4 x i8> %cast1, <4 x i8> undef, <4 x i32> <i32 undef, i32 2, i32 1, i32 0>
265   %cast2 = bitcast <4 x i8> %bswap to i32
266   ret i32 %cast2
269 ; Negative test - extra use
270 declare void @use(<4 x i8>)
272 define i32 @shuf_4bytes_extra_use(<4 x i8> %x) {
273 ; CHECK-LABEL: @shuf_4bytes_extra_use(
274 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
275 ; CHECK-NEXT:    call void @use(<4 x i8> [[BSWAP]])
276 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
277 ; CHECK-NEXT:    ret i32 [[CAST]]
279   %bswap = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
280   call void @use(<4 x i8> %bswap)
281   %cast = bitcast <4 x i8> %bswap to i32
282   ret i32 %cast
285 ; Negative test - scalar type is not in the data layout
287 define i128 @shuf_16bytes(<16 x i8> %x) {
288 ; CHECK-LABEL: @shuf_16bytes(
289 ; 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>
290 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <16 x i8> [[BSWAP]] to i128
291 ; CHECK-NEXT:    ret i128 [[CAST]]
293   %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>
294   %cast = bitcast <16 x i8> %bswap to i128
295   ret i128 %cast
298 ; Negative test - don't touch widening shuffles (for now)
300 define i32 @shuf_2bytes_widening(<2 x i8> %x) {
301 ; CHECK-LABEL: @shuf_2bytes_widening(
302 ; CHECK-NEXT:    [[BSWAP:%.*]] = shufflevector <2 x i8> [[X:%.*]], <2 x i8> undef, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
303 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i8> [[BSWAP]] to i32
304 ; CHECK-NEXT:    ret i32 [[CAST]]
306   %bswap = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
307   %cast = bitcast <4 x i8> %bswap to i32
308   ret i32 %cast