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: movl %edi, %ecx 29; CHECK64-NEXT: andl $16711680, %ecx # imm = 0xFF0000 30; CHECK64-NEXT: movl %edi, %edx 31; CHECK64-NEXT: orl $-16777216, %edx # imm = 0xFF000000 32; CHECK64-NEXT: shll $8, %ecx 33; CHECK64-NEXT: shrl $8, %edx 34; CHECK64-NEXT: orl %ecx, %edx 35; CHECK64-NEXT: bswapl %eax 36; CHECK64-NEXT: shrl $16, %eax 37; CHECK64-NEXT: orl %edx, %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) 59define 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: addl %ecx, %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 101define 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 (%esp) 107; CHECK-NEXT: movzwl (%esp), %eax 108; CHECK-NEXT: orl $3072, %eax # imm = 0xC00 109; CHECK-NEXT: movw %ax, {{[0-9]+}}(%esp) 110; CHECK-NEXT: fldcw {{[0-9]+}}(%esp) 111; CHECK-NEXT: fistpl {{[0-9]+}}(%esp) 112; CHECK-NEXT: fldcw (%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