brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.8 KiB · 26e6886 Raw
320 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X863; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X644 5; Check that under certain conditions we can factor out a rotate6; from the following idioms:7;   (a*c0) >> s1 | (a*c1)8;   (a/c0) << s1 | (a/c1)9; This targets cases where instcombine has folded a shl/srl/mul/udiv10; with one of the shifts from the rotate idiom11 12define i64 @rolq_extract_shl(i64 %i) nounwind {13; X86-LABEL: rolq_extract_shl:14; X86:       # %bb.0:15; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx16; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax17; X86-NEXT:    movl %eax, %ecx18; X86-NEXT:    shldl $3, %edx, %ecx19; X86-NEXT:    shll $3, %eax20; X86-NEXT:    shll $3, %edx21; X86-NEXT:    shrdl $25, %edx, %eax22; X86-NEXT:    shrdl $25, %ecx, %edx23; X86-NEXT:    retl24;25; X64-LABEL: rolq_extract_shl:26; X64:       # %bb.0:27; X64-NEXT:    leaq (,%rdi,8), %rax28; X64-NEXT:    rolq $7, %rax29; X64-NEXT:    retq30  %lhs_mul = shl i64 %i, 331  %rhs_mul = shl i64 %i, 1032  %lhs_shift = lshr i64 %lhs_mul, 5733  %out = or i64 %lhs_shift, %rhs_mul34  ret i64 %out35}36 37define i16 @rolw_extract_shrl(i16 %i) nounwind {38; X86-LABEL: rolw_extract_shrl:39; X86:       # %bb.0:40; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax41; X86-NEXT:    shrl $3, %eax42; X86-NEXT:    rolw $12, %ax43; X86-NEXT:    # kill: def $ax killed $ax killed $eax44; X86-NEXT:    retl45;46; X64-LABEL: rolw_extract_shrl:47; X64:       # %bb.0:48; X64-NEXT:    movzwl %di, %eax49; X64-NEXT:    shrl $3, %eax50; X64-NEXT:    rolw $12, %ax51; X64-NEXT:    # kill: def $ax killed $ax killed $eax52; X64-NEXT:    retq53  %lhs_div = lshr i16 %i, 754  %rhs_div = lshr i16 %i, 355  %rhs_shift = shl i16 %rhs_div, 1256  %out = or i16 %lhs_div, %rhs_shift57  ret i16 %out58}59 60define i32 @roll_extract_mul(i32 %i) nounwind {61; X86-LABEL: roll_extract_mul:62; X86:       # %bb.0:63; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax64; X86-NEXT:    leal (%eax,%eax,8), %eax65; X86-NEXT:    roll $7, %eax66; X86-NEXT:    retl67;68; X64-LABEL: roll_extract_mul:69; X64:       # %bb.0:70; X64-NEXT:    # kill: def $edi killed $edi def $rdi71; X64-NEXT:    leal (%rdi,%rdi,8), %eax72; X64-NEXT:    roll $7, %eax73; X64-NEXT:    retq74  %lhs_mul = mul i32 %i, 975  %rhs_mul = mul i32 %i, 115276  %lhs_shift = lshr i32 %lhs_mul, 2577  %out = or i32 %lhs_shift, %rhs_mul78  ret i32 %out79}80 81define i8 @rolb_extract_udiv(i8 %i) nounwind {82; X86-LABEL: rolb_extract_udiv:83; X86:       # %bb.0:84; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax85; X86-NEXT:    imull $171, %eax, %eax86; X86-NEXT:    shrl $9, %eax87; X86-NEXT:    rolb $4, %al88; X86-NEXT:    # kill: def $al killed $al killed $eax89; X86-NEXT:    retl90;91; X64-LABEL: rolb_extract_udiv:92; X64:       # %bb.0:93; X64-NEXT:    movzbl %dil, %eax94; X64-NEXT:    imull $171, %eax, %eax95; X64-NEXT:    shrl $9, %eax96; X64-NEXT:    rolb $4, %al97; X64-NEXT:    # kill: def $al killed $al killed $eax98; X64-NEXT:    retq99  %lhs_div = udiv i8 %i, 3100  %rhs_div = udiv i8 %i, 48101  %lhs_shift = shl i8 %lhs_div, 4102  %out = or i8 %lhs_shift, %rhs_div103  ret i8 %out104}105 106define i64 @rolq_extract_mul_with_mask(i64 %i) nounwind {107; X86-LABEL: rolq_extract_mul_with_mask:108; X86:       # %bb.0:109; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax110; X86-NEXT:    leal (%eax,%eax,8), %ecx111; X86-NEXT:    movl $9, %eax112; X86-NEXT:    mull {{[0-9]+}}(%esp)113; X86-NEXT:    addl %ecx, %edx114; X86-NEXT:    shrdl $25, %eax, %edx115; X86-NEXT:    movzbl %dl, %eax116; X86-NEXT:    xorl %edx, %edx117; X86-NEXT:    retl118;119; X64-LABEL: rolq_extract_mul_with_mask:120; X64:       # %bb.0:121; X64-NEXT:    leaq (%rdi,%rdi,8), %rax122; X64-NEXT:    rolq $7, %rax123; X64-NEXT:    movzbl %al, %eax124; X64-NEXT:    retq125  %lhs_mul = mul i64 %i, 1152126  %rhs_mul = mul i64 %i, 9127  %lhs_and = and i64 %lhs_mul, 160128  %rhs_shift = lshr i64 %rhs_mul, 57129  %out = or i64 %lhs_and, %rhs_shift130  ret i64 %out131}132 133; Result would undershift134define i64 @no_extract_shl(i64 %i) nounwind {135; X86-LABEL: no_extract_shl:136; X86:       # %bb.0:137; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx138; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax139; X86-NEXT:    movl %eax, %edx140; X86-NEXT:    shldl $10, %ecx, %edx141; X86-NEXT:    shll $10, %ecx142; X86-NEXT:    shrl $20, %eax143; X86-NEXT:    andl $127, %eax144; X86-NEXT:    orl %ecx, %eax145; X86-NEXT:    retl146;147; X64-LABEL: no_extract_shl:148; X64:       # %bb.0:149; X64-NEXT:    movq %rdi, %rax150; X64-NEXT:    shlq $10, %rax151; X64-NEXT:    shrq $52, %rdi152; X64-NEXT:    andl $127, %edi153; X64-NEXT:    orq %rdi, %rax154; X64-NEXT:    retq155  %lhs_mul = shl i64 %i, 5156  %rhs_mul = shl i64 %i, 10157  %lhs_shift = lshr i64 %lhs_mul, 57158  %out = or i64 %lhs_shift, %rhs_mul159  ret i64 %out160}161 162; Result would overshift163define i32 @no_extract_shrl(i32 %i) nounwind {164; X86-LABEL: no_extract_shrl:165; X86:       # %bb.0:166; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax167; X86-NEXT:    movl %eax, %ecx168; X86-NEXT:    shrl $9, %ecx169; X86-NEXT:    andl $-8, %eax170; X86-NEXT:    shll $25, %eax171; X86-NEXT:    orl %ecx, %eax172; X86-NEXT:    retl173;174; X64-LABEL: no_extract_shrl:175; X64:       # %bb.0:176; X64-NEXT:    movl %edi, %eax177; X64-NEXT:    shrl $9, %eax178; X64-NEXT:    andl $-8, %edi179; X64-NEXT:    shll $25, %edi180; X64-NEXT:    orl %edi, %eax181; X64-NEXT:    retq182  %lhs_div = lshr i32 %i, 3183  %rhs_div = lshr i32 %i, 9184  %lhs_shift = shl i32 %lhs_div, 28185  %out = or i32 %lhs_shift, %rhs_div186  ret i32 %out187}188 189; Can factor 128 from 2304, but result is 18 instead of 9190define i16 @no_extract_mul(i16 %i) nounwind {191; X86-LABEL: no_extract_mul:192; X86:       # %bb.0:193; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax194; X86-NEXT:    leal (%eax,%eax,8), %ecx195; X86-NEXT:    shll $8, %eax196; X86-NEXT:    leal (%eax,%eax,8), %edx197; X86-NEXT:    movzwl %cx, %eax198; X86-NEXT:    shrl $9, %eax199; X86-NEXT:    orl %edx, %eax200; X86-NEXT:    # kill: def $ax killed $ax killed $eax201; X86-NEXT:    retl202;203; X64-LABEL: no_extract_mul:204; X64:       # %bb.0:205; X64-NEXT:    # kill: def $edi killed $edi def $rdi206; X64-NEXT:    movl %edi, %eax207; X64-NEXT:    shll $8, %edi208; X64-NEXT:    leal (%rdi,%rdi,8), %ecx209; X64-NEXT:    leal (%rax,%rax,8), %eax210; X64-NEXT:    movzwl %ax, %eax211; X64-NEXT:    shrl $9, %eax212; X64-NEXT:    orl %ecx, %eax213; X64-NEXT:    # kill: def $ax killed $ax killed $eax214; X64-NEXT:    retq215  %lhs_mul = mul i16 %i, 2304216  %rhs_mul = mul i16 %i, 9217  %rhs_shift = lshr i16 %rhs_mul, 9218  %out = or i16 %lhs_mul, %rhs_shift219  ret i16 %out220}221 222; Can't evenly factor 16 from 49223define i8 @no_extract_udiv(i8 %i) nounwind {224; X86-LABEL: no_extract_udiv:225; X86:       # %bb.0:226; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax227; X86-NEXT:    imull $171, %eax, %ecx228; X86-NEXT:    imull $79, %eax, %edx229; X86-NEXT:    subb %dh, %al230; X86-NEXT:    shrb %al231; X86-NEXT:    addb %dh, %al232; X86-NEXT:    shrb $5, %al233; X86-NEXT:    shlb $3, %ch234; X86-NEXT:    orb %al, %ch235; X86-NEXT:    andb $-9, %ch236; X86-NEXT:    movb %ch, %al237; X86-NEXT:    retl238;239; X64-LABEL: no_extract_udiv:240; X64:       # %bb.0:241; X64-NEXT:    movzbl %dil, %ecx242; X64-NEXT:    imull $171, %ecx, %eax243; X64-NEXT:    shrl $8, %eax244; X64-NEXT:    imull $79, %ecx, %edx245; X64-NEXT:    shrl $8, %edx246; X64-NEXT:    subb %dl, %cl247; X64-NEXT:    shrb %cl248; X64-NEXT:    addb %dl, %cl249; X64-NEXT:    shrb $5, %cl250; X64-NEXT:    shlb $3, %al251; X64-NEXT:    orb %cl, %al252; X64-NEXT:    andb $-9, %al253; X64-NEXT:    # kill: def $al killed $al killed $eax254; X64-NEXT:    retq255  %lhs_div = udiv i8 %i, 3256  %rhs_div = udiv i8 %i, 49257  %lhs_shift = shl i8 %lhs_div,4258  %out = or i8 %lhs_shift, %rhs_div259  ret i8 %out260}261 262; DAGCombiner transforms shl X, 1 into add X, X.263define i32 @extract_add_1(i32 %i) nounwind {264; X86-LABEL: extract_add_1:265; X86:       # %bb.0:266; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax267; X86-NEXT:    roll %eax268; X86-NEXT:    retl269;270; X64-LABEL: extract_add_1:271; X64:       # %bb.0:272; X64-NEXT:    movl %edi, %eax273; X64-NEXT:    roll %eax274; X64-NEXT:    retq275  %ii = add i32 %i, %i276  %rhs = lshr i32 %i, 31277  %out = or i32 %ii, %rhs278  ret i32 %out279}280 281define i32 @extract_add_1_comut(i32 %i) nounwind {282; X86-LABEL: extract_add_1_comut:283; X86:       # %bb.0:284; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax285; X86-NEXT:    roll %eax286; X86-NEXT:    retl287;288; X64-LABEL: extract_add_1_comut:289; X64:       # %bb.0:290; X64-NEXT:    movl %edi, %eax291; X64-NEXT:    roll %eax292; X64-NEXT:    retq293  %ii = add i32 %i, %i294  %lhs = lshr i32 %i, 31295  %out = or i32 %lhs, %ii296  ret i32 %out297}298 299define i32 @no_extract_add_1(i32 %i) nounwind {300; X86-LABEL: no_extract_add_1:301; X86:       # %bb.0:302; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax303; X86-NEXT:    leal (%eax,%eax), %ecx304; X86-NEXT:    shrl $27, %eax305; X86-NEXT:    orl %ecx, %eax306; X86-NEXT:    retl307;308; X64-LABEL: no_extract_add_1:309; X64:       # %bb.0:310; X64-NEXT:    # kill: def $edi killed $edi def $rdi311; X64-NEXT:    leal (%rdi,%rdi), %eax312; X64-NEXT:    shrl $27, %edi313; X64-NEXT:    orl %edi, %eax314; X64-NEXT:    retq315  %ii = add i32 %i, %i316  %rhs = lshr i32 %i, 27317  %out = or i32 %ii, %rhs318  ret i32 %out319}320