Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / X86 / rot16.ll
blobc7c2d33d98922b01dff98bb9af9be1b1e86d038d
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686--                | FileCheck %s --check-prefixes=X86,X86-BASE
3 ; RUN: llc < %s -mtriple=i686--  -mattr=movbe  | FileCheck %s --check-prefixes=X86,X86-MOVBE
4 ; RUN: llc < %s -mtriple=x86_64--              | FileCheck %s --check-prefixes=X64,X64-BASE
5 ; RUN: llc < %s -mtriple=x86_64-- -mattr=movbe | FileCheck %s --check-prefixes=X64,X64-MOVBE
7 define i16 @foo(i16 %x, i16 %y, i16 %z) nounwind {
8 ; X86-LABEL: foo:
9 ; X86:       # %bb.0:
10 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
11 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
12 ; X86-NEXT:    rolw %cl, %ax
13 ; X86-NEXT:    retl
15 ; X64-LABEL: foo:
16 ; X64:       # %bb.0:
17 ; X64-NEXT:    movl %edx, %ecx
18 ; X64-NEXT:    movl %edi, %eax
19 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
20 ; X64-NEXT:    rolw %cl, %ax
21 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
22 ; X64-NEXT:    retq
23         %t0 = shl i16 %x, %z
24         %t1 = sub i16 16, %z
25         %t2 = lshr i16 %x, %t1
26         %t3 = or i16 %t2, %t0
27         ret i16 %t3
30 define i16 @bar(i16 %x, i16 %y, i16 %z) nounwind {
31 ; X86-LABEL: bar:
32 ; X86:       # %bb.0:
33 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
34 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
35 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
36 ; X86-NEXT:    andb $15, %cl
37 ; X86-NEXT:    shldw %cl, %dx, %ax
38 ; X86-NEXT:    retl
40 ; X64-LABEL: bar:
41 ; X64:       # %bb.0:
42 ; X64-NEXT:    movl %edx, %ecx
43 ; X64-NEXT:    movl %esi, %eax
44 ; X64-NEXT:    andb $15, %cl
45 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
46 ; X64-NEXT:    shldw %cl, %di, %ax
47 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
48 ; X64-NEXT:    retq
49         %t0 = shl i16 %y, %z
50         %t1 = sub i16 16, %z
51         %t2 = lshr i16 %x, %t1
52         %t3 = or i16 %t2, %t0
53         ret i16 %t3
56 define i16 @un(i16 %x, i16 %y, i16 %z) nounwind {
57 ; X86-LABEL: un:
58 ; X86:       # %bb.0:
59 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
60 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
61 ; X86-NEXT:    rorw %cl, %ax
62 ; X86-NEXT:    retl
64 ; X64-LABEL: un:
65 ; X64:       # %bb.0:
66 ; X64-NEXT:    movl %edx, %ecx
67 ; X64-NEXT:    movl %edi, %eax
68 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
69 ; X64-NEXT:    rorw %cl, %ax
70 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
71 ; X64-NEXT:    retq
72         %t0 = lshr i16 %x, %z
73         %t1 = sub i16 16, %z
74         %t2 = shl i16 %x, %t1
75         %t3 = or i16 %t2, %t0
76         ret i16 %t3
79 define i16 @bu(i16 %x, i16 %y, i16 %z) nounwind {
80 ; X86-LABEL: bu:
81 ; X86:       # %bb.0:
82 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
83 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
84 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
85 ; X86-NEXT:    andb $15, %cl
86 ; X86-NEXT:    shrdw %cl, %dx, %ax
87 ; X86-NEXT:    retl
89 ; X64-LABEL: bu:
90 ; X64:       # %bb.0:
91 ; X64-NEXT:    movl %edx, %ecx
92 ; X64-NEXT:    movl %esi, %eax
93 ; X64-NEXT:    andb $15, %cl
94 ; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
95 ; X64-NEXT:    shrdw %cl, %di, %ax
96 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
97 ; X64-NEXT:    retq
98         %t0 = lshr i16 %y, %z
99         %t1 = sub i16 16, %z
100         %t2 = shl i16 %x, %t1
101         %t3 = or i16 %t2, %t0
102         ret i16 %t3
105 define i16 @xfoo(i16 %x, i16 %y, i16 %z) nounwind {
106 ; X86-LABEL: xfoo:
107 ; X86:       # %bb.0:
108 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
109 ; X86-NEXT:    rolw $5, %ax
110 ; X86-NEXT:    retl
112 ; X64-LABEL: xfoo:
113 ; X64:       # %bb.0:
114 ; X64-NEXT:    movl %edi, %eax
115 ; X64-NEXT:    rolw $5, %ax
116 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
117 ; X64-NEXT:    retq
118         %t0 = lshr i16 %x, 11
119         %t1 = shl i16 %x, 5
120         %t2 = or i16 %t0, %t1
121         ret i16 %t2
124 define i16 @xbar(i16 %x, i16 %y, i16 %z) nounwind {
125 ; X86-LABEL: xbar:
126 ; X86:       # %bb.0:
127 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
128 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
129 ; X86-NEXT:    shldw $5, %cx, %ax
130 ; X86-NEXT:    retl
132 ; X64-LABEL: xbar:
133 ; X64:       # %bb.0:
134 ; X64-NEXT:    movl %esi, %eax
135 ; X64-NEXT:    shldw $5, %di, %ax
136 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
137 ; X64-NEXT:    retq
138         %t0 = shl i16 %y, 5
139         %t1 = lshr i16 %x, 11
140         %t2 = or i16 %t0, %t1
141         ret i16 %t2
144 define i16 @xun(i16 %x, i16 %y, i16 %z) nounwind {
145 ; X86-LABEL: xun:
146 ; X86:       # %bb.0:
147 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
148 ; X86-NEXT:    rolw $11, %ax
149 ; X86-NEXT:    retl
151 ; X64-LABEL: xun:
152 ; X64:       # %bb.0:
153 ; X64-NEXT:    movl %edi, %eax
154 ; X64-NEXT:    rolw $11, %ax
155 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
156 ; X64-NEXT:    retq
157         %t0 = lshr i16 %x, 5
158         %t1 = shl i16 %x, 11
159         %t2 = or i16 %t0, %t1
160         ret i16 %t2
163 define i16 @xbu(i16 %x, i16 %y, i16 %z) nounwind {
164 ; X86-LABEL: xbu:
165 ; X86:       # %bb.0:
166 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
167 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
168 ; X86-NEXT:    shldw $11, %cx, %ax
169 ; X86-NEXT:    retl
171 ; X64-LABEL: xbu:
172 ; X64:       # %bb.0:
173 ; X64-NEXT:    movl %edi, %eax
174 ; X64-NEXT:    shldw $11, %si, %ax
175 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
176 ; X64-NEXT:    retq
177         %t0 = lshr i16 %y, 5
178         %t1 = shl i16 %x, 11
179         %t2 = or i16 %t0, %t1
180         ret i16 %t2
183 define i32 @rot16_demandedbits(i32 %x, i32 %y) nounwind {
184 ; X86-LABEL: rot16_demandedbits:
185 ; X86:       # %bb.0:
186 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
187 ; X86-NEXT:    movl %eax, %ecx
188 ; X86-NEXT:    shrl $11, %ecx
189 ; X86-NEXT:    shll $5, %eax
190 ; X86-NEXT:    orl %ecx, %eax
191 ; X86-NEXT:    movzwl %ax, %eax
192 ; X86-NEXT:    retl
194 ; X64-LABEL: rot16_demandedbits:
195 ; X64:       # %bb.0:
196 ; X64-NEXT:    movl %edi, %eax
197 ; X64-NEXT:    shrl $11, %eax
198 ; X64-NEXT:    shll $5, %edi
199 ; X64-NEXT:    orl %eax, %edi
200 ; X64-NEXT:    movzwl %di, %eax
201 ; X64-NEXT:    retq
202         %t0 = lshr i32 %x, 11
203         %t1 = shl i32 %x, 5
204         %t2 = or i32 %t0, %t1
205         %t3 = and i32 %t2, 65535
206         ret i32 %t3
209 define i16 @rot16_trunc(i32 %x, i32 %y) nounwind {
210 ; X86-LABEL: rot16_trunc:
211 ; X86:       # %bb.0:
212 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
213 ; X86-NEXT:    movl %eax, %ecx
214 ; X86-NEXT:    shrl $11, %ecx
215 ; X86-NEXT:    shll $5, %eax
216 ; X86-NEXT:    orl %ecx, %eax
217 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
218 ; X86-NEXT:    retl
220 ; X64-LABEL: rot16_trunc:
221 ; X64:       # %bb.0:
222 ; X64-NEXT:    movl %edi, %eax
223 ; X64-NEXT:    shrl $11, %eax
224 ; X64-NEXT:    shll $5, %edi
225 ; X64-NEXT:    orl %edi, %eax
226 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
227 ; X64-NEXT:    retq
228         %t0 = lshr i32 %x, 11
229         %t1 = shl i32 %x, 5
230         %t2 = or i32 %t0, %t1
231         %t3 = trunc i32 %t2 to i16
232         ret i16 %t3
235 define i16 @rotate16(i16 %x) {
236 ; X86-BASE-LABEL: rotate16:
237 ; X86-BASE:       # %bb.0:
238 ; X86-BASE-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
239 ; X86-BASE-NEXT:    rolw $8, %ax
240 ; X86-BASE-NEXT:    retl
242 ; X86-MOVBE-LABEL: rotate16:
243 ; X86-MOVBE:       # %bb.0:
244 ; X86-MOVBE-NEXT:    movbew {{[0-9]+}}(%esp), %ax
245 ; X86-MOVBE-NEXT:    retl
247 ; X64-LABEL: rotate16:
248 ; X64:       # %bb.0:
249 ; X64-NEXT:    movl %edi, %eax
250 ; X64-NEXT:    rolw $8, %ax
251 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
252 ; X64-NEXT:    retq
253   %r = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 8)
254   ret i16 %r
257 ; TODO: Should this always be rolw with memory operand?
259 define void @rotate16_in_place_memory(ptr %p) {
260 ; X86-BASE-LABEL: rotate16_in_place_memory:
261 ; X86-BASE:       # %bb.0:
262 ; X86-BASE-NEXT:    movl {{[0-9]+}}(%esp), %eax
263 ; X86-BASE-NEXT:    rolw $8, (%eax)
264 ; X86-BASE-NEXT:    retl
266 ; X86-MOVBE-LABEL: rotate16_in_place_memory:
267 ; X86-MOVBE:       # %bb.0:
268 ; X86-MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %eax
269 ; X86-MOVBE-NEXT:    movzwl (%eax), %ecx
270 ; X86-MOVBE-NEXT:    movbew %cx, (%eax)
271 ; X86-MOVBE-NEXT:    retl
273 ; X64-BASE-LABEL: rotate16_in_place_memory:
274 ; X64-BASE:       # %bb.0:
275 ; X64-BASE-NEXT:    rolw $8, (%rdi)
276 ; X64-BASE-NEXT:    retq
278 ; X64-MOVBE-LABEL: rotate16_in_place_memory:
279 ; X64-MOVBE:       # %bb.0:
280 ; X64-MOVBE-NEXT:    movzwl (%rdi), %eax
281 ; X64-MOVBE-NEXT:    movbew %ax, (%rdi)
282 ; X64-MOVBE-NEXT:    retq
283   %p1 = getelementptr i8, ptr %p, i64 1
284   %i0 = load i8, ptr %p, align 1
285   %i1 = load i8, ptr %p1, align 1
286   store i8 %i1, ptr %p, align 1
287   store i8 %i0, ptr %p1, align 1
288   ret void
291 define void @rotate16_memory(ptr %p, ptr %q) {
292 ; X86-BASE-LABEL: rotate16_memory:
293 ; X86-BASE:       # %bb.0:
294 ; X86-BASE-NEXT:    movl {{[0-9]+}}(%esp), %eax
295 ; X86-BASE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
296 ; X86-BASE-NEXT:    movzwl (%ecx), %ecx
297 ; X86-BASE-NEXT:    rolw $8, %cx
298 ; X86-BASE-NEXT:    movw %cx, (%eax)
299 ; X86-BASE-NEXT:    retl
301 ; X86-MOVBE-LABEL: rotate16_memory:
302 ; X86-MOVBE:       # %bb.0:
303 ; X86-MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %eax
304 ; X86-MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
305 ; X86-MOVBE-NEXT:    movzwl (%ecx), %ecx
306 ; X86-MOVBE-NEXT:    movbew %cx, (%eax)
307 ; X86-MOVBE-NEXT:    retl
309 ; X64-BASE-LABEL: rotate16_memory:
310 ; X64-BASE:       # %bb.0:
311 ; X64-BASE-NEXT:    movzwl (%rdi), %eax
312 ; X64-BASE-NEXT:    rolw $8, %ax
313 ; X64-BASE-NEXT:    movw %ax, (%rsi)
314 ; X64-BASE-NEXT:    retq
316 ; X64-MOVBE-LABEL: rotate16_memory:
317 ; X64-MOVBE:       # %bb.0:
318 ; X64-MOVBE-NEXT:    movzwl (%rdi), %eax
319 ; X64-MOVBE-NEXT:    movbew %ax, (%rsi)
320 ; X64-MOVBE-NEXT:    retq
321   %p1 = getelementptr i8, ptr %p, i64 1
322   %q1 = getelementptr i8, ptr %q, i64 1
323   %i0 = load i8, ptr %p, align 1
324   %i1 = load i8, ptr %p1, align 1
325   store i8 %i1, ptr %q, align 1
326   store i8 %i0, ptr %q1, align 1
327   ret void
330 declare i16 @llvm.fshl.i16(i16, i16, i16)