1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mattr=-bmi -mtriple=x86_64-linux | FileCheck %s -check-prefix=X86-64 -check-prefix=X64
3 ; RUN: llc < %s -mattr=-bmi -mtriple=x86_64-linux-gnux32 | FileCheck %s -check-prefix=X86-64 -check-prefix=X32
4 ; RUN: llc < %s -mattr=-bmi -mtriple=x86_64-win32 | FileCheck %s -check-prefix=WIN64
5 ; RUN: llc < %s -mattr=-bmi -mtriple=i686-- | FileCheck %s -check-prefix=X86-32
7 ; Use h registers. On x86-64, codegen doesn't support general allocation
8 ; of h registers yet, due to x86 encoding complications.
10 define void @bar64(i64 inreg %x, ptr inreg %p) nounwind {
13 ; X64-NEXT: shrl $8, %edi
15 ; X64-NEXT: movb %dil, (%rsi)
20 ; X32-NEXT: shrl $8, %edi
22 ; X32-NEXT: movb %dil, (%esi)
27 ; WIN64-NEXT: shrl $8, %ecx
28 ; WIN64-NEXT: incb %cl
29 ; WIN64-NEXT: movb %cl, (%rdx)
32 ; X86-32-LABEL: bar64:
34 ; X86-32-NEXT: incb %ah
35 ; X86-32-NEXT: movb %ah, (%ecx)
38 ; See FIXME: on regclass GR8.
39 ; It could be optimally transformed like; incb %ch; movb %ch, (%rdx)
42 %t1 = trunc i64 %t0 to i8
48 define void @bar32(i32 inreg %x, ptr inreg %p) nounwind {
51 ; X64-NEXT: shrl $8, %edi
53 ; X64-NEXT: movb %dil, (%rsi)
58 ; X32-NEXT: shrl $8, %edi
60 ; X32-NEXT: movb %dil, (%esi)
65 ; WIN64-NEXT: shrl $8, %ecx
66 ; WIN64-NEXT: incb %cl
67 ; WIN64-NEXT: movb %cl, (%rdx)
70 ; X86-32-LABEL: bar32:
72 ; X86-32-NEXT: incb %ah
73 ; X86-32-NEXT: movb %ah, (%edx)
78 %t1 = trunc i32 %t0 to i8
84 define void @bar16(i16 inreg %x, ptr inreg %p) nounwind {
87 ; X64-NEXT: shrl $8, %edi
89 ; X64-NEXT: movb %dil, (%rsi)
94 ; X32-NEXT: shrl $8, %edi
96 ; X32-NEXT: movb %dil, (%esi)
101 ; WIN64-NEXT: # kill: def $cx killed $cx def $ecx
102 ; WIN64-NEXT: shrl $8, %ecx
103 ; WIN64-NEXT: incb %cl
104 ; WIN64-NEXT: movb %cl, (%rdx)
107 ; X86-32-LABEL: bar16:
109 ; X86-32-NEXT: incb %ah
110 ; X86-32-NEXT: movb %ah, (%edx)
115 %t1 = trunc i16 %t0 to i8
121 define i64 @qux64(i64 inreg %x) nounwind {
122 ; X86-64-LABEL: qux64:
124 ; X86-64-NEXT: movq %rdi, %rax
125 ; X86-64-NEXT: movzbl %ah, %eax
128 ; WIN64-LABEL: qux64:
130 ; WIN64-NEXT: movzbl %ch, %eax
133 ; X86-32-LABEL: qux64:
135 ; X86-32-NEXT: movzbl %ah, %eax
136 ; X86-32-NEXT: xorl %edx, %edx
141 %t1 = and i64 %t0, 255
145 define i32 @qux32(i32 inreg %x) nounwind {
146 ; X86-64-LABEL: qux32:
148 ; X86-64-NEXT: movl %edi, %eax
149 ; X86-64-NEXT: movzbl %ah, %eax
152 ; WIN64-LABEL: qux32:
154 ; WIN64-NEXT: movzbl %ch, %eax
157 ; X86-32-LABEL: qux32:
159 ; X86-32-NEXT: movzbl %ah, %eax
164 %t1 = and i32 %t0, 255
168 define i16 @qux16(i16 inreg %x) nounwind {
169 ; X86-64-LABEL: qux16:
171 ; X86-64-NEXT: movl %edi, %eax
172 ; X86-64-NEXT: movzbl %ah, %eax
173 ; X86-64-NEXT: # kill: def $ax killed $ax killed $eax
176 ; WIN64-LABEL: qux16:
178 ; WIN64-NEXT: movzwl %cx, %eax
179 ; WIN64-NEXT: shrl $8, %eax
180 ; WIN64-NEXT: # kill: def $ax killed $ax killed $eax
183 ; X86-32-LABEL: qux16:
185 ; X86-32-NEXT: movzbl %ah, %eax
186 ; X86-32-NEXT: # kill: def $ax killed $ax killed $eax