xref: /llvm-project/llvm/test/Transforms/InstCombine/bitreverse.ll (revision 68c5d46b6ec46c59afa052d2b2945ca7b22f58d6)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
5
6declare i16 @llvm.bitreverse.i16(i16)
7declare i32 @llvm.bitreverse.i32(i32)
8declare i64 @llvm.bitreverse.i64(i64)
9declare <2 x i8> @llvm.bitreverse.v2i8(<2 x i8>)
10declare <2 x i32> @llvm.bitreverse.v2i32(<2 x i32>)
11declare void @use_i32(i32)
12declare void @use_i64(i64)
13
14;pairwise reverse
15;template <typename T>
16;T reverse(T v) {
17;  T s = sizeof(v) * 8;
18;  T mask = ~(T)0;
19;  while ((s >>= 1) > 0) {
20;    mask ^= (mask << s);
21;    v = ((v >> s) & mask) | ((v << s) & ~mask);
22;  }
23;  return v;
24;}
25define i8 @rev8(i8 %v) {
26; CHECK-LABEL: @rev8(
27; CHECK-NEXT:  entry:
28; CHECK-NEXT:    [[OR_2:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[V:%.*]])
29; CHECK-NEXT:    ret i8 [[OR_2]]
30;
31entry:
32  %shr4 = lshr i8 %v, 4
33  %shl7 = shl i8 %v, 4
34  %or = or i8 %shr4, %shl7
35  %shr4.1 = lshr i8 %or, 2
36  %and.1 = and i8 %shr4.1, 51
37  %shl7.1 = shl i8 %or, 2
38  %and9.1 = and i8 %shl7.1, -52
39  %or.1 = or i8 %and.1, %and9.1
40  %shr4.2 = lshr i8 %or.1, 1
41  %and.2 = and i8 %shr4.2, 85
42  %shl7.2 = shl i8 %or.1, 1
43  %and9.2 = and i8 %shl7.2, -86
44  %or.2 = or i8 %and.2, %and9.2
45  ret i8 %or.2
46}
47
48define i16 @rev16(i16 %v) {
49; CHECK-LABEL: @rev16(
50; CHECK-NEXT:  entry:
51; CHECK-NEXT:    [[OR_3:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[V:%.*]])
52; CHECK-NEXT:    ret i16 [[OR_3]]
53;
54entry:
55  %shr4 = lshr i16 %v, 8
56  %shl7 = shl i16 %v, 8
57  %or = or i16 %shr4, %shl7
58  %shr4.1 = lshr i16 %or, 4
59  %and.1 = and i16 %shr4.1, 3855
60  %shl7.1 = shl i16 %or, 4
61  %and9.1 = and i16 %shl7.1, -3856
62  %or.1 = or i16 %and.1, %and9.1
63  %shr4.2 = lshr i16 %or.1, 2
64  %and.2 = and i16 %shr4.2, 13107
65  %shl7.2 = shl i16 %or.1, 2
66  %and9.2 = and i16 %shl7.2, -13108
67  %or.2 = or i16 %and.2, %and9.2
68  %shr4.3 = lshr i16 %or.2, 1
69  %and.3 = and i16 %shr4.3, 21845
70  %shl7.3 = shl i16 %or.2, 1
71  %and9.3 = and i16 %shl7.3, -21846
72  %or.3 = or i16 %and.3, %and9.3
73  ret i16 %or.3
74}
75
76define i32 @rev32(i32 %v) {
77; CHECK-LABEL: @rev32(
78; CHECK-NEXT:  entry:
79; CHECK-NEXT:    [[OR_4:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[V:%.*]])
80; CHECK-NEXT:    ret i32 [[OR_4]]
81;
82entry:
83  %shr1 = lshr i32 %v, 16
84  %shl2 = shl i32 %v, 16
85  %or = or i32 %shr1, %shl2
86  %shr1.1 = lshr i32 %or, 8
87  %and.1 = and i32 %shr1.1, 16711935
88  %shl2.1 = shl i32 %or, 8
89  %and3.1 = and i32 %shl2.1, -16711936
90  %or.1 = or i32 %and.1, %and3.1
91  %shr1.2 = lshr i32 %or.1, 4
92  %and.2 = and i32 %shr1.2, 252645135
93  %shl2.2 = shl i32 %or.1, 4
94  %and3.2 = and i32 %shl2.2, -252645136
95  %or.2 = or i32 %and.2, %and3.2
96  %shr1.3 = lshr i32 %or.2, 2
97  %and.3 = and i32 %shr1.3, 858993459
98  %shl2.3 = shl i32 %or.2, 2
99  %and3.3 = and i32 %shl2.3, -858993460
100  %or.3 = or i32 %and.3, %and3.3
101  %shr1.4 = lshr i32 %or.3, 1
102  %and.4 = and i32 %shr1.4, 1431655765
103  %shl2.4 = shl i32 %or.3, 1
104  %and3.4 = and i32 %shl2.4, -1431655766
105  %or.4 = or i32 %and.4, %and3.4
106  ret i32 %or.4
107}
108
109define i64 @rev64(i64 %v) {
110; CHECK-LABEL: @rev64(
111; CHECK-NEXT:  entry:
112; CHECK-NEXT:    [[OR_5:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[V:%.*]])
113; CHECK-NEXT:    ret i64 [[OR_5]]
114;
115entry:
116  %shr2 = lshr i64 %v, 32
117  %shl4 = shl i64 %v, 32
118  %or = or i64 %shr2, %shl4
119  %shr2.1 = lshr i64 %or, 16
120  %and.1 = and i64 %shr2.1, 281470681808895
121  %shl4.1 = shl i64 %or, 16
122  %and5.1 = and i64 %shl4.1, -281470681808896
123  %or.1 = or i64 %and.1, %and5.1
124  %shr2.2 = lshr i64 %or.1, 8
125  %and.2 = and i64 %shr2.2, 71777214294589695
126  %shl4.2 = shl i64 %or.1, 8
127  %and5.2 = and i64 %shl4.2, -71777214294589696
128  %or.2 = or i64 %and.2, %and5.2
129  %shr2.3 = lshr i64 %or.2, 4
130  %and.3 = and i64 %shr2.3, 1085102592571150095
131  %shl4.3 = shl i64 %or.2, 4
132  %and5.3 = and i64 %shl4.3, -1085102592571150096
133  %or.3 = or i64 %and.3, %and5.3
134  %shr2.4 = lshr i64 %or.3, 2
135  %and.4 = and i64 %shr2.4, 3689348814741910323
136  %shl4.4 = shl i64 %or.3, 2
137  %and5.4 = and i64 %shl4.4, -3689348814741910324
138  %or.4 = or i64 %and.4, %and5.4
139  %shr2.5 = lshr i64 %or.4, 1
140  %and.5 = and i64 %shr2.5, 6148914691236517205
141  %shl4.5 = shl i64 %or.4, 1
142  %and5.5 = and i64 %shl4.5, -6148914691236517206
143  %or.5 = or i64 %and.5, %and5.5
144  ret i64 %or.5
145}
146
147;unsigned char rev8_xor(unsigned char x) {
148;  unsigned char y;
149;  y = x&0x55; x ^= y; x |= (y<<2)|(y>>6);
150;  y = x&0x66; x ^= y; x |= (y<<4)|(y>>4);
151;  return (x<<1)|(x>>7);
152;}
153
154define i8 @rev8_xor(i8 %0) {
155; CHECK-LABEL: @rev8_xor(
156; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TMP0:%.*]])
157; CHECK-NEXT:    ret i8 [[TMP2]]
158;
159  %2 = and i8 %0, 85
160  %3 = xor i8 %0, %2
161  %4 = shl i8 %2, 2
162  %5 = lshr i8 %2, 6
163  %6 = or i8 %5, %3
164  %7 = or i8 %6, %4
165  %8 = and i8 %7, 102
166  %9 = xor i8 %7, %8
167  %10 = lshr i8 %8, 4
168  %11 = or i8 %10, %9
169  %12 = shl i8 %8, 5
170  %13 = shl i8 %11, 1
171  %14 = or i8 %12, %13
172  %15 = lshr i8 %0, 7
173  %16 = or i8 %14, %15
174  ret i8 %16
175}
176
177define <2 x i8> @rev8_xor_vector(<2 x i8> %0) {
178; CHECK-LABEL: @rev8_xor_vector(
179; CHECK-NEXT:    [[TMP2:%.*]] = call <2 x i8> @llvm.bitreverse.v2i8(<2 x i8> [[TMP0:%.*]])
180; CHECK-NEXT:    ret <2 x i8> [[TMP2]]
181;
182  %2 = and <2 x i8> %0, <i8 85, i8 85>
183  %3 = xor <2 x i8> %0, %2
184  %4 = shl <2 x i8> %2, <i8 2, i8 2>
185  %5 = lshr <2 x i8> %2, <i8 6, i8 6>
186  %6 = or <2 x i8> %5, %3
187  %7 = or <2 x i8> %6, %4
188  %8 = and <2 x i8> %7, <i8 102, i8 102>
189  %9 = xor <2 x i8> %7, %8
190  %10 = lshr <2 x i8> %8, <i8 4, i8 4>
191  %11 = or <2 x i8> %10, %9
192  %12 = shl <2 x i8> %8, <i8 5, i8 5>
193  %13 = shl <2 x i8> %11, <i8 1, i8 1>
194  %14 = or <2 x i8> %12, %13
195  %15 = lshr <2 x i8> %0, <i8 7, i8 7>
196  %16 = or <2 x i8> %14, %15
197  ret <2 x i8> %16
198}
199
200; bitreverse8(x) = ((x * 0x0202020202ULL) & 0x010884422010ULL) % 1023
201define i8 @rev8_mul_and_urem(i8 %0) {
202; CHECK-LABEL: @rev8_mul_and_urem(
203; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[TMP0:%.*]] to i64
204; CHECK-NEXT:    [[TMP3:%.*]] = mul nuw nsw i64 [[TMP2]], 8623620610
205; CHECK-NEXT:    [[TMP4:%.*]] = and i64 [[TMP3]], 1136090292240
206; CHECK-NEXT:    [[TMP5:%.*]] = urem i64 [[TMP4]], 1023
207; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
208; CHECK-NEXT:    ret i8 [[TMP6]]
209;
210  %2 = zext i8 %0 to i64
211  %3 = mul nuw nsw i64 %2, 8623620610
212  %4 = and i64 %3, 1136090292240
213  %5 = urem i64 %4, 1023
214  %6 = trunc i64 %5 to i8
215  ret i8 %6
216}
217
218; bitreverse8(x) = ((x * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32
219define i8 @rev8_mul_and_mul(i8 %0) {
220; CHECK-LABEL: @rev8_mul_and_mul(
221; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[TMP0:%.*]] to i64
222; CHECK-NEXT:    [[TMP3:%.*]] = mul nuw nsw i64 [[TMP2]], 2149582850
223; CHECK-NEXT:    [[TMP4:%.*]] = and i64 [[TMP3]], 36578664720
224; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 4311810305
225; CHECK-NEXT:    [[TMP6:%.*]] = lshr i64 [[TMP5]], 32
226; CHECK-NEXT:    [[TMP7:%.*]] = trunc i64 [[TMP6]] to i8
227; CHECK-NEXT:    ret i8 [[TMP7]]
228;
229  %2 = zext i8 %0 to i64
230  %3 = mul nuw nsw i64 %2, 2149582850
231  %4 = and i64 %3, 36578664720
232  %5 = mul i64 %4, 4311810305
233  %6 = lshr i64 %5, 32
234  %7 = trunc i64 %6 to i8
235  ret i8 %7
236}
237
238; bitreverse8(x) = (((x * 0x0802LU) & 0x22110LU) | ((x * 0x8020LU) & 0x88440LU)) * 0x10101LU >> 16
239define i8 @rev8_mul_and_lshr(i8 %0) {
240; CHECK-LABEL: @rev8_mul_and_lshr(
241; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[TMP0:%.*]] to i64
242; CHECK-NEXT:    [[TMP3:%.*]] = mul nuw nsw i64 [[TMP2]], 2050
243; CHECK-NEXT:    [[TMP4:%.*]] = and i64 [[TMP3]], 139536
244; CHECK-NEXT:    [[TMP5:%.*]] = mul nuw nsw i64 [[TMP2]], 32800
245; CHECK-NEXT:    [[TMP6:%.*]] = and i64 [[TMP5]], 558144
246; CHECK-NEXT:    [[TMP7:%.*]] = or i64 [[TMP4]], [[TMP6]]
247; CHECK-NEXT:    [[TMP8:%.*]] = mul nuw nsw i64 [[TMP7]], 65793
248; CHECK-NEXT:    [[TMP9:%.*]] = lshr i64 [[TMP8]], 16
249; CHECK-NEXT:    [[TMP10:%.*]] = trunc i64 [[TMP9]] to i8
250; CHECK-NEXT:    ret i8 [[TMP10]]
251;
252  %2 = zext i8 %0 to i64
253  %3 = mul nuw nsw i64 %2, 2050
254  %4 = and i64 %3, 139536
255  %5 = mul nuw nsw i64 %2, 32800
256  %6 = and i64 %5, 558144
257  %7 = or i64 %4, %6
258  %8 = mul nuw nsw i64 %7, 65793
259  %9 = lshr i64 %8, 16
260  %10 = trunc i64 %9 to i8
261  ret i8 %10
262}
263
264define i4 @shuf_4bits(<4 x i1> %x) {
265; CHECK-LABEL: @shuf_4bits(
266; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4
267; CHECK-NEXT:    [[CAST:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[TMP1]])
268; CHECK-NEXT:    ret i4 [[CAST]]
269;
270  %bitreverse = shufflevector <4 x i1> %x, <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
271  %cast = bitcast <4 x i1> %bitreverse to i4
272  ret i4 %cast
273}
274
275define i4 @shuf_load_4bits(ptr %p) {
276; CHECK-LABEL: @shuf_load_4bits(
277; CHECK-NEXT:    [[X1:%.*]] = load i4, ptr [[P:%.*]], align 1
278; CHECK-NEXT:    [[CAST:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[X1]])
279; CHECK-NEXT:    ret i4 [[CAST]]
280;
281  %x = load <4 x i1>, ptr %p
282  %bitreverse = shufflevector <4 x i1> %x, <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
283  %cast = bitcast <4 x i1> %bitreverse to i4
284  ret i4 %cast
285}
286
287define i4 @shuf_bitcast_twice_4bits(i4 %x) {
288; CHECK-LABEL: @shuf_bitcast_twice_4bits(
289; CHECK-NEXT:    [[CAST2:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[X:%.*]])
290; CHECK-NEXT:    ret i4 [[CAST2]]
291;
292  %cast1 = bitcast i4 %x to <4 x i1>
293  %bitreverse = shufflevector <4 x i1> %cast1, <4 x i1> undef, <4 x i32> <i32 poison, i32 2, i32 1, i32 0>
294  %cast2 = bitcast <4 x i1> %bitreverse to i4
295  ret i4 %cast2
296}
297
298; Negative tests - not reverse
299define i4 @shuf_4bits_not_reverse(<4 x i1> %x) {
300; CHECK-LABEL: @shuf_4bits_not_reverse(
301; CHECK-NEXT:    [[BITREVERSE:%.*]] = shufflevector <4 x i1> [[X:%.*]], <4 x i1> undef, <4 x i32> <i32 3, i32 1, i32 2, i32 0>
302; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i1> [[BITREVERSE]] to i4
303; CHECK-NEXT:    ret i4 [[CAST]]
304;
305  %bitreverse = shufflevector <4 x i1> %x, <4 x i1> undef, <4 x i32> <i32 3, i32 1, i32 2, i32 0>
306  %cast = bitcast <4 x i1> %bitreverse to i4
307  ret i4 %cast
308}
309
310; Negative test - extra use
311declare void @use(<4 x i1>)
312
313define i4 @shuf_4bits_extra_use(<4 x i1> %x) {
314; CHECK-LABEL: @shuf_4bits_extra_use(
315; CHECK-NEXT:    [[BITREVERSE:%.*]] = shufflevector <4 x i1> [[X:%.*]], <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
316; CHECK-NEXT:    call void @use(<4 x i1> [[BITREVERSE]])
317; CHECK-NEXT:    [[CAST:%.*]] = bitcast <4 x i1> [[BITREVERSE]] to i4
318; CHECK-NEXT:    ret i4 [[CAST]]
319;
320  %bitreverse = shufflevector <4 x i1> %x, <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
321  call void @use(<4 x i1> %bitreverse)
322  %cast = bitcast <4 x i1> %bitreverse to i4
323  ret i4 %cast
324}
325
326define i32 @rev_i1(i1 %x) {
327; CHECK-LABEL: @rev_i1(
328; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[X:%.*]] to i32
329; CHECK-NEXT:    call void @use_i32(i32 [[Z]])
330; CHECK-NEXT:    [[R:%.*]] = select i1 [[X]], i32 -2147483648, i32 0
331; CHECK-NEXT:    ret i32 [[R]]
332;
333  %z = zext i1 %x to i32
334  call void @use_i32(i32 %z)
335  %r = call i32 @llvm.bitreverse.i32(i32 %z)
336  ret i32 %r
337}
338
339define <2 x i8> @rev_v2i1(<2 x i1> %x) {
340; CHECK-LABEL: @rev_v2i1(
341; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[X:%.*]], <2 x i8> <i8 -128, i8 -128>, <2 x i8> zeroinitializer
342; CHECK-NEXT:    ret <2 x i8> [[R]]
343;
344  %z = zext <2 x i1> %x to <2 x i8>
345  %r = call <2 x i8> @llvm.bitreverse.v2i8(<2 x i8> %z)
346  ret <2 x i8> %r
347}
348
349define i32 @rev_i2(i2 %x) {
350; CHECK-LABEL: @rev_i2(
351; CHECK-NEXT:    [[Z:%.*]] = zext i2 [[X:%.*]] to i32
352; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[Z]])
353; CHECK-NEXT:    ret i32 [[R]]
354;
355  %z = zext i2 %x to i32
356  %r = call i32 @llvm.bitreverse.i32(i32 %z)
357  ret i32 %r
358}
359
360; This used to infinite loop.
361
362define i64 @PR59897(i1 %X1_2) {
363; CHECK-LABEL: @PR59897(
364; CHECK-NEXT:    [[NOT_X1_2:%.*]] = xor i1 [[X1_2:%.*]], true
365; CHECK-NEXT:    [[X0_3X2X5X0:%.*]] = zext i1 [[NOT_X1_2]] to i64
366; CHECK-NEXT:    ret i64 [[X0_3X2X5X0]]
367;
368  %X1_3 = zext i1 %X1_2 to i32
369  %X8_3x2x2x0 = call i32 @llvm.bitreverse.i32(i32 %X1_3)
370  %X8_4x2x3x0 = xor i32 %X8_3x2x2x0, -1
371  %X0_3x2x4x0 = lshr i32 %X8_4x2x3x0, 31
372  %X0_3x2x5x0 = zext i32 %X0_3x2x4x0 to i64
373  ret i64 %X0_3x2x5x0
374}
375
376; Issue#62236
377; Fold: BITREVERSE( OP( BITREVERSE(x), y ) ) -> OP( x, BITREVERSE(y) )
378
379define i16 @rev_xor_lhs_rev16(i16 %a, i16 %b) #0 {
380; CHECK-LABEL: @rev_xor_lhs_rev16(
381; CHECK-NEXT:    [[TMP1:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[B:%.*]])
382; CHECK-NEXT:    [[TMP2:%.*]] = xor i16 [[TMP1]], [[A:%.*]]
383; CHECK-NEXT:    ret i16 [[TMP2]]
384;
385  %1 = tail call i16 @llvm.bitreverse.i16(i16 %a)
386  %2 = xor i16 %1, %b
387  %3 = tail call i16 @llvm.bitreverse.i16(i16 %2)
388  ret i16 %3
389}
390
391define i32 @rev_and_rhs_rev32(i32 %a, i32 %b) #0 {
392; CHECK-LABEL: @rev_and_rhs_rev32(
393; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A:%.*]])
394; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]]
395; CHECK-NEXT:    ret i32 [[TMP2]]
396;
397  %1 = tail call i32 @llvm.bitreverse.i32(i32 %b)
398  %2 = and i32 %a, %1
399  %3 = tail call i32 @llvm.bitreverse.i32(i32 %2)
400  ret i32 %3
401}
402
403define i32 @rev_or_rhs_rev32(i32 %a, i32 %b) #0 {
404; CHECK-LABEL: @rev_or_rhs_rev32(
405; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A:%.*]])
406; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[B:%.*]]
407; CHECK-NEXT:    ret i32 [[TMP2]]
408;
409  %1 = tail call i32 @llvm.bitreverse.i32(i32 %b)
410  %2 = or i32 %a, %1
411  %3 = tail call i32 @llvm.bitreverse.i32(i32 %2)
412  ret i32 %3
413}
414
415define i64 @rev_or_rhs_rev64(i64 %a, i64 %b) #0 {
416; CHECK-LABEL: @rev_or_rhs_rev64(
417; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
418; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], [[B:%.*]]
419; CHECK-NEXT:    ret i64 [[TMP2]]
420;
421  %1 = tail call i64 @llvm.bitreverse.i64(i64 %b)
422  %2 = or i64 %a, %1
423  %3 = tail call i64 @llvm.bitreverse.i64(i64 %2)
424  ret i64 %3
425}
426
427define i64 @rev_xor_rhs_rev64(i64 %a, i64 %b) #0 {
428; CHECK-LABEL: @rev_xor_rhs_rev64(
429; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
430; CHECK-NEXT:    [[TMP2:%.*]] = xor i64 [[TMP1]], [[B:%.*]]
431; CHECK-NEXT:    ret i64 [[TMP2]]
432;
433  %1 = tail call i64 @llvm.bitreverse.i64(i64 %b)
434  %2 = xor i64 %a, %1
435  %3 = tail call i64 @llvm.bitreverse.i64(i64 %2)
436  ret i64 %3
437}
438
439define <2 x i32> @rev_xor_rhs_i32vec(<2 x i32> %a, <2 x i32> %b) #0 {
440; CHECK-LABEL: @rev_xor_rhs_i32vec(
441; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> [[A:%.*]])
442; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], [[B:%.*]]
443; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
444;
445  %1 = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %b)
446  %2 = xor <2 x i32> %a, %1
447  %3 = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %2)
448  ret <2 x i32> %3
449}
450
451define i64 @rev_and_rhs_rev64_multiuse1(i64 %a, i64 %b) #0 {
452; CHECK-LABEL: @rev_and_rhs_rev64_multiuse1(
453; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
454; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP1]], [[A:%.*]]
455; CHECK-NEXT:    [[TMP3:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP2]])
456; CHECK-NEXT:    [[TMP4:%.*]] = mul i64 [[TMP2]], [[TMP3]]
457; CHECK-NEXT:    ret i64 [[TMP4]]
458;
459  %1 = tail call i64 @llvm.bitreverse.i64(i64 %b)
460  %2 = and i64 %a, %1
461  %3 = tail call i64 @llvm.bitreverse.i64(i64 %2)
462  %4 = mul i64 %2, %3 ;increase use of logical op
463  ret i64 %4
464}
465
466define i64 @rev_and_rhs_rev64_multiuse2(i64 %a, i64 %b) #0 {
467; CHECK-LABEL: @rev_and_rhs_rev64_multiuse2(
468; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
469; CHECK-NEXT:    [[TMP2:%.*]] = and i64 [[TMP1]], [[A:%.*]]
470; CHECK-NEXT:    [[TMP3:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP2]])
471; CHECK-NEXT:    [[TMP4:%.*]] = mul i64 [[TMP1]], [[TMP3]]
472; CHECK-NEXT:    ret i64 [[TMP4]]
473;
474  %1 = tail call i64 @llvm.bitreverse.i64(i64 %b)
475  %2 = and i64 %a, %1
476  %3 = tail call i64 @llvm.bitreverse.i64(i64 %2)
477  %4 = mul i64 %1, %3 ;increase use of inner bitreverse
478  ret i64 %4
479}
480
481define i64 @rev_all_operand64(i64 %a, i64 %b) #0 {
482; CHECK-LABEL: @rev_all_operand64(
483; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[A:%.*]], [[B:%.*]]
484; CHECK-NEXT:    ret i64 [[TMP1]]
485;
486  %1 = tail call i64 @llvm.bitreverse.i64(i64 %a)
487  %2 = tail call i64 @llvm.bitreverse.i64(i64 %b)
488  %3 = and i64 %1, %2
489  %4 = tail call i64 @llvm.bitreverse.i64(i64 %3)
490  ret i64 %4
491}
492
493define i64 @rev_all_operand64_multiuse_both(i64 %a, i64 %b) #0 {
494; CHECK-LABEL: @rev_all_operand64_multiuse_both(
495; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[A:%.*]])
496; CHECK-NEXT:    [[TMP2:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]])
497; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[A]], [[B]]
498; CHECK-NEXT:    call void @use_i64(i64 [[TMP1]])
499; CHECK-NEXT:    call void @use_i64(i64 [[TMP2]])
500; CHECK-NEXT:    ret i64 [[TMP3]]
501;
502  %1 = tail call i64 @llvm.bitreverse.i64(i64 %a)
503  %2 = tail call i64 @llvm.bitreverse.i64(i64 %b)
504  %3 = and i64 %1, %2
505  %4 = tail call i64 @llvm.bitreverse.i64(i64 %3)
506
507  call void @use_i64(i64 %1)
508  call void @use_i64(i64 %2)
509  ret i64 %4
510}
511