brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.2 KiB · 81eac56 Raw
420 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; bswap should be constant folded when it is passed a constant argument3 4; RUN: llc < %s -mtriple=i686-- -mcpu=i686 | FileCheck %s5; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s --check-prefix=CHECK646 7declare i16 @llvm.bswap.i16(i16)8declare i32 @llvm.bswap.i32(i32)9declare i64 @llvm.bswap.i64(i64)10 11define i16 @W(i16 %A) {12; CHECK-LABEL: W:13; CHECK:       # %bb.0:14; CHECK-NEXT:    movzwl {{[0-9]+}}(%esp), %eax15; CHECK-NEXT:    rolw $8, %ax16; CHECK-NEXT:    retl17;18; CHECK64-LABEL: W:19; CHECK64:       # %bb.0:20; CHECK64-NEXT:    movl %edi, %eax21; CHECK64-NEXT:    rolw $8, %ax22; CHECK64-NEXT:    # kill: def $ax killed $ax killed $eax23; CHECK64-NEXT:    retq24        %Z = call i16 @llvm.bswap.i16( i16 %A )         ; <i16> [#uses=1]25        ret i16 %Z26}27 28define dso_local i32 @X(i32 %A) {29; CHECK-LABEL: X:30; CHECK:       # %bb.0:31; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax32; CHECK-NEXT:    bswapl %eax33; CHECK-NEXT:    retl34;35; CHECK64-LABEL: X:36; CHECK64:       # %bb.0:37; CHECK64-NEXT:    movl %edi, %eax38; CHECK64-NEXT:    bswapl %eax39; CHECK64-NEXT:    retq40        %Z = call i32 @llvm.bswap.i32( i32 %A )         ; <i32> [#uses=1]41        ret i32 %Z42}43 44define i64 @Y(i64 %A) {45; CHECK-LABEL: Y:46; CHECK:       # %bb.0:47; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edx48; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax49; CHECK-NEXT:    bswapl %eax50; CHECK-NEXT:    bswapl %edx51; CHECK-NEXT:    retl52;53; CHECK64-LABEL: Y:54; CHECK64:       # %bb.0:55; CHECK64-NEXT:    movq %rdi, %rax56; CHECK64-NEXT:    bswapq %rax57; CHECK64-NEXT:    retq58        %Z = call i64 @llvm.bswap.i64( i64 %A )         ; <i64> [#uses=1]59        ret i64 %Z60}61 62; This isn't really a bswap test, but the potential probem is63; easier to see with bswap vs. other ops. The transform in64; question starts with a bitwise logic op and tries to hoist65; those ahead of other ops. But that's not generally profitable66; when the other ops have other uses (and it might not be safe67; either due to unconstrained instruction count growth).68 69define dso_local i32 @bswap_multiuse(i32 %x, i32 %y, ptr %p1, ptr %p2) nounwind {70; CHECK-LABEL: bswap_multiuse:71; CHECK:       # %bb.0:72; CHECK-NEXT:    pushl %esi73; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx74; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edx75; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax76; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi77; CHECK-NEXT:    bswapl %esi78; CHECK-NEXT:    bswapl %eax79; CHECK-NEXT:    movl %esi, (%edx)80; CHECK-NEXT:    movl %eax, (%ecx)81; CHECK-NEXT:    orl %esi, %eax82; CHECK-NEXT:    popl %esi83; CHECK-NEXT:    retl84;85; CHECK64-LABEL: bswap_multiuse:86; CHECK64:       # %bb.0:87; CHECK64-NEXT:    movl %esi, %eax88; CHECK64-NEXT:    bswapl %edi89; CHECK64-NEXT:    bswapl %eax90; CHECK64-NEXT:    movl %edi, (%rdx)91; CHECK64-NEXT:    movl %eax, (%rcx)92; CHECK64-NEXT:    orl %edi, %eax93; CHECK64-NEXT:    retq94  %xt = call i32 @llvm.bswap.i32(i32 %x)95  %yt = call i32 @llvm.bswap.i32(i32 %y)96  store i32 %xt, ptr %p197  store i32 %yt, ptr %p298  %r = or i32 %xt, %yt99  ret i32 %r100}101 102; rdar://9164521103define dso_local i32 @test1(i32 %a) nounwind readnone {104; CHECK-LABEL: test1:105; CHECK:       # %bb.0:106; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax107; CHECK-NEXT:    bswapl %eax108; CHECK-NEXT:    shrl $16, %eax109; CHECK-NEXT:    retl110;111; CHECK64-LABEL: test1:112; CHECK64:       # %bb.0:113; CHECK64-NEXT:    movl %edi, %eax114; CHECK64-NEXT:    bswapl %eax115; CHECK64-NEXT:    shrl $16, %eax116; CHECK64-NEXT:    retq117  %and = lshr i32 %a, 8118  %shr3 = and i32 %and, 255119  %and2 = shl i32 %a, 8120  %shl = and i32 %and2, 65280121  %or = or i32 %shr3, %shl122  ret i32 %or123}124 125define dso_local i32 @test2(i32 %a) nounwind readnone {126; CHECK-LABEL: test2:127; CHECK:       # %bb.0:128; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax129; CHECK-NEXT:    bswapl %eax130; CHECK-NEXT:    sarl $16, %eax131; CHECK-NEXT:    retl132;133; CHECK64-LABEL: test2:134; CHECK64:       # %bb.0:135; CHECK64-NEXT:    movl %edi, %eax136; CHECK64-NEXT:    bswapl %eax137; CHECK64-NEXT:    sarl $16, %eax138; CHECK64-NEXT:    retq139  %and = lshr i32 %a, 8140  %shr4 = and i32 %and, 255141  %and2 = shl i32 %a, 8142  %or = or i32 %shr4, %and2143  %sext = shl i32 %or, 16144  %conv3 = ashr exact i32 %sext, 16145  ret i32 %conv3146}147 148@var8 = dso_local global i8 0149@var16 = dso_local global i16 0150 151; The "shl" below can move bits into the high parts of the value, so the152; operation is not a "bswap, shr" pair.153 154; rdar://problem/14814049155define i64 @not_bswap() {156; CHECK-LABEL: not_bswap:157; CHECK:       # %bb.0:158; CHECK-NEXT:    movzwl var16, %eax159; CHECK-NEXT:    movl %eax, %ecx160; CHECK-NEXT:    shrl $8, %ecx161; CHECK-NEXT:    shll $8, %eax162; CHECK-NEXT:    orl %ecx, %eax163; CHECK-NEXT:    xorl %edx, %edx164; CHECK-NEXT:    retl165;166; CHECK64-LABEL: not_bswap:167; CHECK64:       # %bb.0:168; CHECK64-NEXT:    movzwl var16(%rip), %eax169; CHECK64-NEXT:    movl %eax, %ecx170; CHECK64-NEXT:    shrl $8, %ecx171; CHECK64-NEXT:    shll $8, %eax172; CHECK64-NEXT:    orl %ecx, %eax173; CHECK64-NEXT:    retq174  %init = load i16, ptr @var16175  %big = zext i16 %init to i64176 177  %hishifted = lshr i64 %big, 8178  %loshifted = shl i64 %big, 8179 180  %notswapped = or i64 %hishifted, %loshifted181 182  ret i64 %notswapped183}184 185; This time, the lshr (and subsequent or) is completely useless. While it's186; technically correct to convert this into a "bswap, shr", it's suboptimal. A187; simple shl works better.188 189define i64 @not_useful_bswap() {190; CHECK-LABEL: not_useful_bswap:191; CHECK:       # %bb.0:192; CHECK-NEXT:    movzbl var8, %eax193; CHECK-NEXT:    shll $8, %eax194; CHECK-NEXT:    xorl %edx, %edx195; CHECK-NEXT:    retl196;197; CHECK64-LABEL: not_useful_bswap:198; CHECK64:       # %bb.0:199; CHECK64-NEXT:    movzbl var8(%rip), %eax200; CHECK64-NEXT:    shll $8, %eax201; CHECK64-NEXT:    retq202  %init = load i8, ptr @var8203  %big = zext i8 %init to i64204 205  %hishifted = lshr i64 %big, 8206  %loshifted = shl i64 %big, 8207 208  %notswapped = or i64 %hishifted, %loshifted209 210  ret i64 %notswapped211}212 213; Finally, it *is* OK to just mask off the shl if we know that the value is zero214; beyond 16 bits anyway. This is a legitimate bswap.215 216define i64 @finally_useful_bswap() {217; CHECK-LABEL: finally_useful_bswap:218; CHECK:       # %bb.0:219; CHECK-NEXT:    movzwl var16, %eax220; CHECK-NEXT:    bswapl %eax221; CHECK-NEXT:    shrl $16, %eax222; CHECK-NEXT:    xorl %edx, %edx223; CHECK-NEXT:    retl224;225; CHECK64-LABEL: finally_useful_bswap:226; CHECK64:       # %bb.0:227; CHECK64-NEXT:    movzwl var16(%rip), %eax228; CHECK64-NEXT:    bswapl %eax229; CHECK64-NEXT:    shrl $16, %eax230; CHECK64-NEXT:    retq231  %init = load i16, ptr @var16232  %big = zext i16 %init to i64233 234  %hishifted = lshr i64 %big, 8235  %lomasked = and i64 %big, 255236  %loshifted = shl i64 %lomasked, 8237 238  %swapped = or i64 %hishifted, %loshifted239 240  ret i64 %swapped241}242 243; Make sure we don't assert during type legalization promoting a large244; bswap due to the need for a large shift that won't fit in the i8 returned245; from getShiftAmountTy.246define i528 @large_promotion(i528 %A) nounwind {247; CHECK-LABEL: large_promotion:248; CHECK:       # %bb.0:249; CHECK-NEXT:    pushl %ebp250; CHECK-NEXT:    pushl %ebx251; CHECK-NEXT:    pushl %edi252; CHECK-NEXT:    pushl %esi253; CHECK-NEXT:    subl $44, %esp254; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ebp255; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ebx256; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edi257; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi258; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edx259; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx260; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax261; CHECK-NEXT:    bswapl %eax262; CHECK-NEXT:    bswapl %ecx263; CHECK-NEXT:    shrdl $16, %ecx, %eax264; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill265; CHECK-NEXT:    bswapl %edx266; CHECK-NEXT:    shrdl $16, %edx, %ecx267; CHECK-NEXT:    movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill268; CHECK-NEXT:    bswapl %esi269; CHECK-NEXT:    shrdl $16, %esi, %edx270; CHECK-NEXT:    movl %edx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill271; CHECK-NEXT:    bswapl %edi272; CHECK-NEXT:    shrdl $16, %edi, %esi273; CHECK-NEXT:    movl %esi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill274; CHECK-NEXT:    bswapl %ebx275; CHECK-NEXT:    shrdl $16, %ebx, %edi276; CHECK-NEXT:    movl %edi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill277; CHECK-NEXT:    bswapl %ebp278; CHECK-NEXT:    shrdl $16, %ebp, %ebx279; CHECK-NEXT:    movl %ebx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill280; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax281; CHECK-NEXT:    bswapl %eax282; CHECK-NEXT:    shrdl $16, %eax, %ebp283; CHECK-NEXT:    movl %ebp, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill284; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx285; CHECK-NEXT:    bswapl %ecx286; CHECK-NEXT:    shrdl $16, %ecx, %eax287; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill288; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax289; CHECK-NEXT:    bswapl %eax290; CHECK-NEXT:    shrdl $16, %eax, %ecx291; CHECK-NEXT:    movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill292; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx293; CHECK-NEXT:    bswapl %ecx294; CHECK-NEXT:    shrdl $16, %ecx, %eax295; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill296; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ebp297; CHECK-NEXT:    bswapl %ebp298; CHECK-NEXT:    shrdl $16, %ebp, %ecx299; CHECK-NEXT:    movl %ecx, (%esp) # 4-byte Spill300; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ebx301; CHECK-NEXT:    bswapl %ebx302; CHECK-NEXT:    shrdl $16, %ebx, %ebp303; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi304; CHECK-NEXT:    bswapl %esi305; CHECK-NEXT:    shrdl $16, %esi, %ebx306; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edx307; CHECK-NEXT:    bswapl %edx308; CHECK-NEXT:    shrdl $16, %edx, %esi309; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx310; CHECK-NEXT:    bswapl %ecx311; CHECK-NEXT:    shrdl $16, %ecx, %edx312; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edi313; CHECK-NEXT:    bswapl %edi314; CHECK-NEXT:    shrdl $16, %edi, %ecx315; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax316; CHECK-NEXT:    movl %ecx, 60(%eax)317; CHECK-NEXT:    movl %edx, 56(%eax)318; CHECK-NEXT:    movl %esi, 52(%eax)319; CHECK-NEXT:    movl %ebx, 48(%eax)320; CHECK-NEXT:    movl %ebp, 44(%eax)321; CHECK-NEXT:    movl (%esp), %ecx # 4-byte Reload322; CHECK-NEXT:    movl %ecx, 40(%eax)323; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload324; CHECK-NEXT:    movl %ecx, 36(%eax)325; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload326; CHECK-NEXT:    movl %ecx, 32(%eax)327; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload328; CHECK-NEXT:    movl %ecx, 28(%eax)329; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload330; CHECK-NEXT:    movl %ecx, 24(%eax)331; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload332; CHECK-NEXT:    movl %ecx, 20(%eax)333; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload334; CHECK-NEXT:    movl %ecx, 16(%eax)335; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload336; CHECK-NEXT:    movl %ecx, 12(%eax)337; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload338; CHECK-NEXT:    movl %ecx, 8(%eax)339; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload340; CHECK-NEXT:    movl %ecx, 4(%eax)341; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload342; CHECK-NEXT:    movl %ecx, (%eax)343; CHECK-NEXT:    shrl $16, %edi344; CHECK-NEXT:    movw %di, 64(%eax)345; CHECK-NEXT:    addl $44, %esp346; CHECK-NEXT:    popl %esi347; CHECK-NEXT:    popl %edi348; CHECK-NEXT:    popl %ebx349; CHECK-NEXT:    popl %ebp350; CHECK-NEXT:    retl $4351;352; CHECK64-LABEL: large_promotion:353; CHECK64:       # %bb.0:354; CHECK64-NEXT:    pushq %rbx355; CHECK64-NEXT:    movq %rdi, %rax356; CHECK64-NEXT:    movq {{[0-9]+}}(%rsp), %rbx357; CHECK64-NEXT:    movq {{[0-9]+}}(%rsp), %r11358; CHECK64-NEXT:    movq {{[0-9]+}}(%rsp), %r10359; CHECK64-NEXT:    movq {{[0-9]+}}(%rsp), %rdi360; CHECK64-NEXT:    bswapq %rdi361; CHECK64-NEXT:    bswapq %r10362; CHECK64-NEXT:    shrdq $48, %r10, %rdi363; CHECK64-NEXT:    bswapq %r11364; CHECK64-NEXT:    shrdq $48, %r11, %r10365; CHECK64-NEXT:    bswapq %rbx366; CHECK64-NEXT:    shrdq $48, %rbx, %r11367; CHECK64-NEXT:    bswapq %r9368; CHECK64-NEXT:    shrdq $48, %r9, %rbx369; CHECK64-NEXT:    bswapq %r8370; CHECK64-NEXT:    shrdq $48, %r8, %r9371; CHECK64-NEXT:    bswapq %rcx372; CHECK64-NEXT:    shrdq $48, %rcx, %r8373; CHECK64-NEXT:    bswapq %rdx374; CHECK64-NEXT:    shrdq $48, %rdx, %rcx375; CHECK64-NEXT:    bswapq %rsi376; CHECK64-NEXT:    shrdq $48, %rsi, %rdx377; CHECK64-NEXT:    shrq $48, %rsi378; CHECK64-NEXT:    movq %rdx, 56(%rax)379; CHECK64-NEXT:    movq %rcx, 48(%rax)380; CHECK64-NEXT:    movq %r8, 40(%rax)381; CHECK64-NEXT:    movq %r9, 32(%rax)382; CHECK64-NEXT:    movq %rbx, 24(%rax)383; CHECK64-NEXT:    movq %r11, 16(%rax)384; CHECK64-NEXT:    movq %r10, 8(%rax)385; CHECK64-NEXT:    movq %rdi, (%rax)386; CHECK64-NEXT:    movw %si, 64(%rax)387; CHECK64-NEXT:    popq %rbx388; CHECK64-NEXT:    retq389  %Z = call i528 @llvm.bswap.i528(i528 %A)390  ret i528 %Z391}392declare i528 @llvm.bswap.i528(i528)393 394define i32 @pr55484(i32 %0) {395; CHECK-LABEL: pr55484:396; CHECK:       # %bb.0:397; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax398; CHECK-NEXT:    movl %eax, %ecx399; CHECK-NEXT:    shrl $8, %ecx400; CHECK-NEXT:    shll $8, %eax401; CHECK-NEXT:    orl %ecx, %eax402; CHECK-NEXT:    cwtl403; CHECK-NEXT:    retl404;405; CHECK64-LABEL: pr55484:406; CHECK64:       # %bb.0:407; CHECK64-NEXT:    movl %edi, %eax408; CHECK64-NEXT:    shrl $8, %eax409; CHECK64-NEXT:    shll $8, %edi410; CHECK64-NEXT:    orl %eax, %edi411; CHECK64-NEXT:    movswl %di, %eax412; CHECK64-NEXT:    retq413  %2 = lshr i32 %0, 8414  %3 = shl i32 %0, 8415  %4 = or i32 %2, %3416  %5 = trunc i32 %4 to i16417  %6 = sext i16 %5 to i32418  ret i32 %6419}420