[PowerPC] Recommit r314244 with refactoring and off by default
[llvm-core.git] / test / CodeGen / X86 / rotate4.ll
blob242aaff441c7fd11c0380eff4001ac4c5234ccf9
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
4 ; Check that we recognize this idiom for rotation too:
5 ;    a << (b & (OpSize-1)) | a >> ((0 - b) & (OpSize-1))
7 define i32 @rotate_left_32(i32 %a, i32 %b) {
8 ; CHECK-LABEL: rotate_left_32:
9 ; CHECK:       # BB#0:
10 ; CHECK-NEXT:    movl %esi, %ecx
11 ; CHECK-NEXT:    roll %cl, %edi
12 ; CHECK-NEXT:    movl %edi, %eax
13 ; CHECK-NEXT:    retq
14   %and = and i32 %b, 31
15   %shl = shl i32 %a, %and
16   %t0 = sub i32 0, %b
17   %and3 = and i32 %t0, 31
18   %shr = lshr i32 %a, %and3
19   %or = or i32 %shl, %shr
20   ret i32 %or
23 define i32 @rotate_right_32(i32 %a, i32 %b) {
24 ; CHECK-LABEL: rotate_right_32:
25 ; CHECK:       # BB#0:
26 ; CHECK-NEXT:    movl %esi, %ecx
27 ; CHECK-NEXT:    rorl %cl, %edi
28 ; CHECK-NEXT:    movl %edi, %eax
29 ; CHECK-NEXT:    retq
30   %and = and i32 %b, 31
31   %shl = lshr i32 %a, %and
32   %t0 = sub i32 0, %b
33   %and3 = and i32 %t0, 31
34   %shr = shl i32 %a, %and3
35   %or = or i32 %shl, %shr
36   ret i32 %or
39 define i64 @rotate_left_64(i64 %a, i64 %b) {
40 ; CHECK-LABEL: rotate_left_64:
41 ; CHECK:       # BB#0:
42 ; CHECK-NEXT:    movl %esi, %ecx
43 ; CHECK-NEXT:    rolq %cl, %rdi
44 ; CHECK-NEXT:    movq %rdi, %rax
45 ; CHECK-NEXT:    retq
46   %and = and i64 %b, 63
47   %shl = shl i64 %a, %and
48   %t0 = sub i64 0, %b
49   %and3 = and i64 %t0, 63
50   %shr = lshr i64 %a, %and3
51   %or = or i64 %shl, %shr
52   ret i64 %or
55 define i64 @rotate_right_64(i64 %a, i64 %b) {
56 ; CHECK-LABEL: rotate_right_64:
57 ; CHECK:       # BB#0:
58 ; CHECK-NEXT:    movl %esi, %ecx
59 ; CHECK-NEXT:    rorq %cl, %rdi
60 ; CHECK-NEXT:    movq %rdi, %rax
61 ; CHECK-NEXT:    retq
62   %and = and i64 %b, 63
63   %shl = lshr i64 %a, %and
64   %t0 = sub i64 0, %b
65   %and3 = and i64 %t0, 63
66   %shr = shl i64 %a, %and3
67   %or = or i64 %shl, %shr
68   ret i64 %or
71 ; Also check mem operand.
73 define void @rotate_left_m32(i32 *%pa, i32 %b) {
74 ; CHECK-LABEL: rotate_left_m32:
75 ; CHECK:       # BB#0:
76 ; CHECK-NEXT:    movl %esi, %ecx
77 ; CHECK-NEXT:    roll %cl, (%rdi)
78 ; CHECK-NEXT:    retq
79   %a = load i32, i32* %pa, align 16
80   %and = and i32 %b, 31
81   %shl = shl i32 %a, %and
82   %t0 = sub i32 0, %b
83   %and3 = and i32 %t0, 31
84   %shr = lshr i32 %a, %and3
85   %or = or i32 %shl, %shr
86   store i32 %or, i32* %pa, align 32
87   ret void
90 define void @rotate_right_m32(i32 *%pa, i32 %b) {
91 ; CHECK-LABEL: rotate_right_m32:
92 ; CHECK:       # BB#0:
93 ; CHECK-NEXT:    movl %esi, %ecx
94 ; CHECK-NEXT:    rorl %cl, (%rdi)
95 ; CHECK-NEXT:    retq
96   %a = load i32, i32* %pa, align 16
97   %and = and i32 %b, 31
98   %shl = lshr i32 %a, %and
99   %t0 = sub i32 0, %b
100   %and3 = and i32 %t0, 31
101   %shr = shl i32 %a, %and3
102   %or = or i32 %shl, %shr
103   store i32 %or, i32* %pa, align 32
104   ret void
107 define void @rotate_left_m64(i64 *%pa, i64 %b) {
108 ; CHECK-LABEL: rotate_left_m64:
109 ; CHECK:       # BB#0:
110 ; CHECK-NEXT:    movl %esi, %ecx
111 ; CHECK-NEXT:    rolq %cl, (%rdi)
112 ; CHECK-NEXT:    retq
113   %a = load i64, i64* %pa, align 16
114   %and = and i64 %b, 63
115   %shl = shl i64 %a, %and
116   %t0 = sub i64 0, %b
117   %and3 = and i64 %t0, 63
118   %shr = lshr i64 %a, %and3
119   %or = or i64 %shl, %shr
120   store i64 %or, i64* %pa, align 64
121   ret void
124 define void @rotate_right_m64(i64 *%pa, i64 %b) {
125 ; CHECK-LABEL: rotate_right_m64:
126 ; CHECK:       # BB#0:
127 ; CHECK-NEXT:    movl %esi, %ecx
128 ; CHECK-NEXT:    rorq %cl, (%rdi)
129 ; CHECK-NEXT:    retq
130   %a = load i64, i64* %pa, align 16
131   %and = and i64 %b, 63
132   %shl = lshr i64 %a, %and
133   %t0 = sub i64 0, %b
134   %and3 = and i64 %t0, 63
135   %shr = shl i64 %a, %and3
136   %or = or i64 %shl, %shr
137   store i64 %or, i64* %pa, align 64
138   ret void
141 ; The next 8 tests include masks of the narrow width shift amounts that should be eliminated.
142 ; These patterns are produced by instcombine after r310509.
144 define i8 @rotate_left_8(i8 %x, i32 %amount) {
145 ; CHECK-LABEL: rotate_left_8:
146 ; CHECK:       # BB#0:
147 ; CHECK-NEXT:    movl %esi, %ecx
148 ; CHECK-NEXT:    rolb %cl, %dil
149 ; CHECK-NEXT:    movl %edi, %eax
150 ; CHECK-NEXT:    retq
151   %amt = trunc i32 %amount to i8
152   %sub = sub i8 0, %amt
153   %maskamt = and i8 %amt, 7
154   %masksub = and i8 %sub, 7
155   %shl = shl i8 %x, %maskamt
156   %shr = lshr i8 %x, %masksub
157   %or = or i8 %shl, %shr
158   ret i8 %or
161 define i8 @rotate_right_8(i8 %x, i32 %amount) {
162 ; CHECK-LABEL: rotate_right_8:
163 ; CHECK:       # BB#0:
164 ; CHECK-NEXT:    movl %esi, %ecx
165 ; CHECK-NEXT:    rorb %cl, %dil
166 ; CHECK-NEXT:    movl %edi, %eax
167 ; CHECK-NEXT:    retq
168   %amt = trunc i32 %amount to i8
169   %sub = sub i8 0, %amt
170   %maskamt = and i8 %amt, 7
171   %masksub = and i8 %sub, 7
172   %shr = lshr i8 %x, %maskamt
173   %shl = shl i8 %x, %masksub
174   %or = or i8 %shr, %shl
175   ret i8 %or
178 define i16 @rotate_left_16(i16 %x, i32 %amount) {
179 ; CHECK-LABEL: rotate_left_16:
180 ; CHECK:       # BB#0:
181 ; CHECK-NEXT:    movl %esi, %ecx
182 ; CHECK-NEXT:    rolw %cl, %di
183 ; CHECK-NEXT:    movl %edi, %eax
184 ; CHECK-NEXT:    retq
185   %amt = trunc i32 %amount to i16
186   %sub = sub i16 0, %amt
187   %maskamt = and i16 %amt, 15
188   %masksub = and i16 %sub, 15
189   %shl = shl i16 %x, %maskamt
190   %shr = lshr i16 %x, %masksub
191   %or = or i16 %shl, %shr
192   ret i16 %or
195 define i16 @rotate_right_16(i16 %x, i32 %amount) {
196 ; CHECK-LABEL: rotate_right_16:
197 ; CHECK:       # BB#0:
198 ; CHECK-NEXT:    movl %esi, %ecx
199 ; CHECK-NEXT:    rorw %cl, %di
200 ; CHECK-NEXT:    movl %edi, %eax
201 ; CHECK-NEXT:    retq
202   %amt = trunc i32 %amount to i16
203   %sub = sub i16 0, %amt
204   %maskamt = and i16 %amt, 15
205   %masksub = and i16 %sub, 15
206   %shr = lshr i16 %x, %maskamt
207   %shl = shl i16 %x, %masksub
208   %or = or i16 %shr, %shl
209   ret i16 %or
212 define void @rotate_left_m8(i8* %p, i32 %amount) {
213 ; CHECK-LABEL: rotate_left_m8:
214 ; CHECK:       # BB#0:
215 ; CHECK-NEXT:    movl %esi, %ecx
216 ; CHECK-NEXT:    rolb %cl, (%rdi)
217 ; CHECK-NEXT:    retq
218   %x = load i8, i8* %p, align 1
219   %amt = trunc i32 %amount to i8
220   %sub = sub i8 0, %amt
221   %maskamt = and i8 %amt, 7
222   %masksub = and i8 %sub, 7
223   %shl = shl i8 %x, %maskamt
224   %shr = lshr i8 %x, %masksub
225   %or = or i8 %shl, %shr
226   store i8 %or, i8* %p, align 1
227   ret void
230 define void @rotate_right_m8(i8* %p, i32 %amount) {
231 ; CHECK-LABEL: rotate_right_m8:
232 ; CHECK:       # BB#0:
233 ; CHECK-NEXT:    movl %esi, %ecx
234 ; CHECK-NEXT:    rorb %cl, (%rdi)
235 ; CHECK-NEXT:    retq
236   %x = load i8, i8* %p, align 1
237   %amt = trunc i32 %amount to i8
238   %sub = sub i8 0, %amt
239   %maskamt = and i8 %amt, 7
240   %masksub = and i8 %sub, 7
241   %shl = shl i8 %x, %masksub
242   %shr = lshr i8 %x, %maskamt
243   %or = or i8 %shl, %shr
244   store i8 %or, i8* %p, align 1
245   ret void
248 define void @rotate_left_m16(i16* %p, i32 %amount) {
249 ; CHECK-LABEL: rotate_left_m16:
250 ; CHECK:       # BB#0:
251 ; CHECK-NEXT:    movl %esi, %ecx
252 ; CHECK-NEXT:    rolw %cl, (%rdi)
253 ; CHECK-NEXT:    retq
254   %x = load i16, i16* %p, align 1
255   %amt = trunc i32 %amount to i16
256   %sub = sub i16 0, %amt
257   %maskamt = and i16 %amt, 15
258   %masksub = and i16 %sub, 15
259   %shl = shl i16 %x, %maskamt
260   %shr = lshr i16 %x, %masksub
261   %or = or i16 %shl, %shr
262   store i16 %or, i16* %p, align 1
263   ret void
266 define void @rotate_right_m16(i16* %p, i32 %amount) {
267 ; CHECK-LABEL: rotate_right_m16:
268 ; CHECK:       # BB#0:
269 ; CHECK-NEXT:    movl %esi, %ecx
270 ; CHECK-NEXT:    rorw %cl, (%rdi)
271 ; CHECK-NEXT:    retq
272   %x = load i16, i16* %p, align 1
273   %amt = trunc i32 %amount to i16
274   %sub = sub i16 0, %amt
275   %maskamt = and i16 %amt, 15
276   %masksub = and i16 %sub, 15
277   %shl = shl i16 %x, %masksub
278   %shr = lshr i16 %x, %maskamt
279   %or = or i16 %shl, %shr
280   store i16 %or, i16* %p, align 1
281   ret void