1 ; RUN: llc < %s -mattr=-bmi -mtriple=x86_64-linux | FileCheck %s -check-prefix=X86-64 2 ; RUN: llc < %s -mattr=-bmi -mtriple=x86_64-linux-gnux32 | FileCheck %s -check-prefix=X86-64 3 ; RUN: llc < %s -mattr=-bmi -mtriple=x86_64-win32 | FileCheck %s -check-prefix=WIN64 4 ; RUN: llc < %s -mattr=-bmi -march=x86 | FileCheck %s -check-prefix=X86-32 5 6 ; Use h registers. On x86-64, codegen doesn't support general allocation 7 ; of h registers yet, due to x86 encoding complications. 8 9 define void @bar64(i64 inreg %x, i8* inreg %p) nounwind { 10 ; X86-64-LABEL: bar64: 11 ; X86-64: shrq $8, %rdi 12 ; X86-64: incb %dil 13 14 ; See FIXME: on regclass GR8. 15 ; It could be optimally transformed like; incb %ch; movb %ch, (%rdx) 16 ; WIN64-LABEL: bar64: 17 ; WIN64: shrq $8, %rcx 18 ; WIN64: incb %cl 19 20 ; X86-32-LABEL: bar64: 21 ; X86-32: incb %ah 22 %t0 = lshr i64 %x, 8 23 %t1 = trunc i64 %t0 to i8 24 %t2 = add i8 %t1, 1 25 store i8 %t2, i8* %p 26 ret void 27 } 28 29 define void @bar32(i32 inreg %x, i8* inreg %p) nounwind { 30 ; X86-64-LABEL: bar32: 31 ; X86-64: shrl $8, %edi 32 ; X86-64: incb %dil 33 34 ; WIN64-LABEL: bar32: 35 ; WIN64: shrl $8, %ecx 36 ; WIN64: incb %cl 37 38 ; X86-32-LABEL: bar32: 39 ; X86-32: incb %ah 40 %t0 = lshr i32 %x, 8 41 %t1 = trunc i32 %t0 to i8 42 %t2 = add i8 %t1, 1 43 store i8 %t2, i8* %p 44 ret void 45 } 46 47 define void @bar16(i16 inreg %x, i8* inreg %p) nounwind { 48 ; X86-64-LABEL: bar16: 49 ; X86-64: shrl $8, %edi 50 ; X86-64: incb %dil 51 52 ; WIN64-LABEL: bar16: 53 ; WIN64: shrl $8, %ecx 54 ; WIN64: incb %cl 55 56 ; X86-32-LABEL: bar16: 57 ; X86-32: incb %ah 58 %t0 = lshr i16 %x, 8 59 %t1 = trunc i16 %t0 to i8 60 %t2 = add i8 %t1, 1 61 store i8 %t2, i8* %p 62 ret void 63 } 64 65 define i64 @qux64(i64 inreg %x) nounwind { 66 ; X86-64-LABEL: qux64: 67 ; X86-64: movq %rdi, %rax 68 ; X86-64: movzbl %ah, %eax 69 70 ; WIN64-LABEL: qux64: 71 ; WIN64: movzbl %ch, %eax 72 73 ; X86-32-LABEL: qux64: 74 ; X86-32: movzbl %ah, %eax 75 %t0 = lshr i64 %x, 8 76 %t1 = and i64 %t0, 255 77 ret i64 %t1 78 } 79 80 define i32 @qux32(i32 inreg %x) nounwind { 81 ; X86-64-LABEL: qux32: 82 ; X86-64: movl %edi, %eax 83 ; X86-64: movzbl %ah, %eax 84 85 ; WIN64-LABEL: qux32: 86 ; WIN64: movzbl %ch, %eax 87 88 ; X86-32-LABEL: qux32: 89 ; X86-32: movzbl %ah, %eax 90 %t0 = lshr i32 %x, 8 91 %t1 = and i32 %t0, 255 92 ret i32 %t1 93 } 94 95 define i16 @qux16(i16 inreg %x) nounwind { 96 ; X86-64-LABEL: qux16: 97 ; X86-64: movl %edi, %eax 98 ; X86-64: movzbl %ah, %eax 99 100 ; WIN64-LABEL: qux16: 101 ; WIN64: movzbl %ch, %eax 102 103 ; X86-32-LABEL: qux16: 104 ; X86-32: movzbl %ah, %eax 105 %t0 = lshr i16 %x, 8 106 ret i16 %t0 107 } 108