1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s 3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=CHECK64 4 5 ; Check a few invalid patterns for halfword bswap pattern matching 6 7 ; Don't match a near-miss 32-bit packed halfword bswap 8 ; (with only half of the swap tree valid). 9 define i32 @test1(i32 %x) nounwind { 10 ; CHECK-LABEL: test1: 11 ; CHECK: # %bb.0: 12 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 13 ; CHECK-NEXT: movl %eax, %ecx 14 ; CHECK-NEXT: andl $16711680, %ecx # imm = 0xFF0000 15 ; CHECK-NEXT: movl %eax, %edx 16 ; CHECK-NEXT: orl $-16777216, %edx # imm = 0xFF000000 17 ; CHECK-NEXT: shll $8, %ecx 18 ; CHECK-NEXT: shrl $8, %edx 19 ; CHECK-NEXT: orl %ecx, %edx 20 ; CHECK-NEXT: bswapl %eax 21 ; CHECK-NEXT: shrl $16, %eax 22 ; CHECK-NEXT: orl %edx, %eax 23 ; CHECK-NEXT: retl 24 ; 25 ; CHECK64-LABEL: test1: 26 ; CHECK64: # %bb.0: 27 ; CHECK64-NEXT: movl %edi, %eax 28 ; CHECK64-NEXT: andl $16711680, %eax # imm = 0xFF0000 29 ; CHECK64-NEXT: movl %edi, %ecx 30 ; CHECK64-NEXT: orl $-16777216, %ecx # imm = 0xFF000000 31 ; CHECK64-NEXT: shll $8, %eax 32 ; CHECK64-NEXT: shrl $8, %ecx 33 ; CHECK64-NEXT: orl %eax, %ecx 34 ; CHECK64-NEXT: bswapl %edi 35 ; CHECK64-NEXT: shrl $16, %edi 36 ; CHECK64-NEXT: orl %ecx, %edi 37 ; CHECK64-NEXT: movl %edi, %eax 38 ; CHECK64-NEXT: retq 39 %byte0 = and i32 %x, 255 ; 0x000000ff 40 %byte1 = and i32 %x, 65280 ; 0x0000ff00 41 %byte2 = and i32 %x, 16711680 ; 0x00ff0000 42 %byte3 = or i32 %x, 4278190080 ; 0xff000000 43 %tmp0 = shl i32 %byte0, 8 44 %tmp1 = lshr i32 %byte1, 8 45 %tmp2 = shl i32 %byte2, 8 46 %tmp3 = lshr i32 %byte3, 8 47 %or0 = or i32 %tmp0, %tmp1 48 %or1 = or i32 %tmp2, %tmp3 49 %result = or i32 %or0, %or1 50 ret i32 %result 51 } 52 53 ; Don't match a near-miss 32-bit packed halfword bswap 54 ; (with swapped lshr/shl) 55 ; ((x >> 8) & 0x0000ff00) | 56 ; ((x << 8) & 0x000000ff) | 57 ; ((x << 8) & 0xff000000) | 58 ; ((x >> 8) & 0x00ff0000) 59 define i32 @test2(i32 %x) nounwind { 60 ; CHECK-LABEL: test2: 61 ; CHECK: # %bb.0: 62 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 63 ; CHECK-NEXT: movl %ecx, %eax 64 ; CHECK-NEXT: shrl $8, %eax 65 ; CHECK-NEXT: shll $8, %ecx 66 ; CHECK-NEXT: movl %eax, %edx 67 ; CHECK-NEXT: andl $65280, %edx # imm = 0xFF00 68 ; CHECK-NEXT: andl $-16777216, %ecx # imm = 0xFF000000 69 ; CHECK-NEXT: andl $16711680, %eax # imm = 0xFF0000 70 ; CHECK-NEXT: orl %ecx, %eax 71 ; CHECK-NEXT: orl %edx, %eax 72 ; CHECK-NEXT: retl 73 ; 74 ; CHECK64-LABEL: test2: 75 ; CHECK64: # %bb.0: 76 ; CHECK64-NEXT: movl %edi, %eax 77 ; CHECK64-NEXT: shrl $8, %eax 78 ; CHECK64-NEXT: shll $8, %edi 79 ; CHECK64-NEXT: movl %eax, %ecx 80 ; CHECK64-NEXT: andl $65280, %ecx # imm = 0xFF00 81 ; CHECK64-NEXT: andl $-16777216, %edi # imm = 0xFF000000 82 ; CHECK64-NEXT: andl $16711680, %eax # imm = 0xFF0000 83 ; CHECK64-NEXT: orl %edi, %eax 84 ; CHECK64-NEXT: leal (%rax,%rcx), %eax 85 ; CHECK64-NEXT: retq 86 %byte1 = lshr i32 %x, 8 87 %byte0 = shl i32 %x, 8 88 %byte3 = shl i32 %x, 8 89 %byte2 = lshr i32 %x, 8 90 %tmp1 = and i32 %byte1, 65280 ; 0x0000ff00 91 %tmp0 = and i32 %byte0, 255 ; 0x000000ff 92 %tmp3 = and i32 %byte3, 4278190080 ; 0xff000000 93 %tmp2 = and i32 %byte2, 16711680 ; 0x00ff0000 94 %or0 = or i32 %tmp0, %tmp1 95 %or1 = or i32 %tmp2, %tmp3 96 %result = or i32 %or0, %or1 97 ret i32 %result 98 } 99 100 ; Invalid pattern involving a unary op 101 define i32 @test3(float %x) nounwind { 102 ; CHECK-LABEL: test3: 103 ; CHECK: # %bb.0: 104 ; CHECK-NEXT: subl $8, %esp 105 ; CHECK-NEXT: flds {{[0-9]+}}(%esp) 106 ; CHECK-NEXT: fnstcw {{[0-9]+}}(%esp) 107 ; CHECK-NEXT: movzwl {{[0-9]+}}(%esp), %eax 108 ; CHECK-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F 109 ; CHECK-NEXT: fldcw {{[0-9]+}}(%esp) 110 ; CHECK-NEXT: movw %ax, {{[0-9]+}}(%esp) 111 ; CHECK-NEXT: fistpl {{[0-9]+}}(%esp) 112 ; CHECK-NEXT: fldcw {{[0-9]+}}(%esp) 113 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 114 ; CHECK-NEXT: movl %ecx, %edx 115 ; CHECK-NEXT: shll $8, %edx 116 ; CHECK-NEXT: movl %ecx, %eax 117 ; CHECK-NEXT: shrl $8, %eax 118 ; CHECK-NEXT: andl $65280, %ecx # imm = 0xFF00 119 ; CHECK-NEXT: andl $-16777216, %edx # imm = 0xFF000000 120 ; CHECK-NEXT: andl $16711680, %eax # imm = 0xFF0000 121 ; CHECK-NEXT: orl %edx, %eax 122 ; CHECK-NEXT: orl %ecx, %eax 123 ; CHECK-NEXT: addl $8, %esp 124 ; CHECK-NEXT: retl 125 ; 126 ; CHECK64-LABEL: test3: 127 ; CHECK64: # %bb.0: 128 ; CHECK64-NEXT: cvttss2si %xmm0, %ecx 129 ; CHECK64-NEXT: movl %ecx, %edx 130 ; CHECK64-NEXT: shll $8, %edx 131 ; CHECK64-NEXT: movl %ecx, %eax 132 ; CHECK64-NEXT: shrl $8, %eax 133 ; CHECK64-NEXT: andl $65280, %ecx # imm = 0xFF00 134 ; CHECK64-NEXT: andl $-16777216, %edx # imm = 0xFF000000 135 ; CHECK64-NEXT: andl $16711680, %eax # imm = 0xFF0000 136 ; CHECK64-NEXT: orl %edx, %eax 137 ; CHECK64-NEXT: orl %ecx, %eax 138 ; CHECK64-NEXT: retq 139 %integer = fptosi float %x to i32 140 %byte0 = shl i32 %integer, 8 141 %byte3 = shl i32 %integer, 8 142 %byte2 = lshr i32 %integer, 8 143 %tmp1 = and i32 %integer, 65280 ; 0x0000ff00 144 %tmp0 = and i32 %byte0, 255 ; 0x000000ff 145 %tmp3 = and i32 %byte3, 4278190080 ; 0xff000000 146 %tmp2 = and i32 %byte2, 16711680 ; 0x00ff0000 147 %or0 = or i32 %tmp0, %tmp1 148 %or1 = or i32 %tmp2, %tmp3 149 %result = or i32 %or0, %or1 150 ret i32 %result 151 } 152