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 reconstructing bswap from shifted masks and tree of ORs 6 7; Match a 32-bit packed halfword bswap. That is 8; ((x & 0x000000ff) << 8) | 9; ((x & 0x0000ff00) >> 8) | 10; ((x & 0x00ff0000) << 8) | 11; ((x & 0xff000000) >> 8) 12; => (rotl (bswap x), 16) 13define i32 @test1(i32 %x) nounwind { 14; CHECK-LABEL: test1: 15; CHECK: # %bb.0: 16; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 17; CHECK-NEXT: bswapl %eax 18; CHECK-NEXT: roll $16, %eax 19; CHECK-NEXT: retl 20; 21; CHECK64-LABEL: test1: 22; CHECK64: # %bb.0: 23; CHECK64-NEXT: movl %edi, %eax 24; CHECK64-NEXT: bswapl %eax 25; CHECK64-NEXT: roll $16, %eax 26; CHECK64-NEXT: retq 27 %byte0 = and i32 %x, 255 ; 0x000000ff 28 %byte1 = and i32 %x, 65280 ; 0x0000ff00 29 %byte2 = and i32 %x, 16711680 ; 0x00ff0000 30 %byte3 = and i32 %x, 4278190080 ; 0xff000000 31 %tmp0 = shl i32 %byte0, 8 32 %tmp1 = lshr i32 %byte1, 8 33 %tmp2 = shl i32 %byte2, 8 34 %tmp3 = lshr i32 %byte3, 8 35 %or0 = or i32 %tmp0, %tmp1 36 %or1 = or i32 %tmp2, %tmp3 37 %result = or i32 %or0, %or1 38 ret i32 %result 39} 40 41; the same as test1, just shifts before the "and" 42; ((x << 8) & 0x0000ff00) | 43; ((x >> 8) & 0x000000ff) | 44; ((x << 8) & 0xff000000) | 45; ((x >> 8) & 0x00ff0000) 46define i32 @test2(i32 %x) nounwind { 47; CHECK-LABEL: test2: 48; CHECK: # %bb.0: 49; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 50; CHECK-NEXT: bswapl %eax 51; CHECK-NEXT: roll $16, %eax 52; CHECK-NEXT: retl 53; 54; CHECK64-LABEL: test2: 55; CHECK64: # %bb.0: 56; CHECK64-NEXT: movl %edi, %eax 57; CHECK64-NEXT: bswapl %eax 58; CHECK64-NEXT: roll $16, %eax 59; CHECK64-NEXT: retq 60 %byte1 = shl i32 %x, 8 61 %byte0 = lshr i32 %x, 8 62 %byte3 = shl i32 %x, 8 63 %byte2 = lshr i32 %x, 8 64 %tmp1 = and i32 %byte1, 65280 ; 0x0000ff00 65 %tmp0 = and i32 %byte0, 255 ; 0x000000ff 66 %tmp3 = and i32 %byte3, 4278190080 ; 0xff000000 67 %tmp2 = and i32 %byte2, 16711680 ; 0x00ff0000 68 %or0 = or i32 %tmp0, %tmp1 69 %or1 = or i32 %tmp2, %tmp3 70 %result = or i32 %or0, %or1 71 ret i32 %result 72} 73 74declare i32 @llvm.bswap.i32(i32) 75 76; Match a 32-bit packed halfword bswap, with some subtree 77; already converted to a bswap. 78define i32 @test3(i32 %x) nounwind { 79; CHECK-LABEL: test3: 80; CHECK: # %bb.0: 81; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 82; CHECK-NEXT: bswapl %eax 83; CHECK-NEXT: roll $16, %eax 84; CHECK-NEXT: retl 85; 86; CHECK64-LABEL: test3: 87; CHECK64: # %bb.0: 88; CHECK64-NEXT: movl %edi, %eax 89; CHECK64-NEXT: bswapl %eax 90; CHECK64-NEXT: roll $16, %eax 91; CHECK64-NEXT: retq 92 %byte2 = and i32 %x, 16711680 ; 0x00ff0000 93 %byte3 = and i32 %x, 4278190080 ; 0xff000000 94 %1 = shl i32 %byte2, 8 95 %2 = lshr i32 %byte3, 8 96 %or = or i32 %1, %2 97 %bswap = call i32 @llvm.bswap.i32(i32 %x) 98 %3 = lshr i32 %bswap, 16 99 %result = or i32 %or, %3 100 ret i32 %result 101} 102