433 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi < %s | FileCheck %s --check-prefix=CHECK-NOBMI3; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi < %s | FileCheck %s --check-prefix=CHECK-BMI4 5; https://bugs.llvm.org/show_bug.cgi?id=371046 7; X: [byte1][byte0]8; Y: [byte3][byte2]9 10define i8 @out8_constmask(i8 %x, i8 %y) {11; CHECK-NOBMI-LABEL: out8_constmask:12; CHECK-NOBMI: # %bb.0:13; CHECK-NOBMI-NEXT: # kill: def $esi killed $esi def $rsi14; CHECK-NOBMI-NEXT: # kill: def $edi killed $edi def $rdi15; CHECK-NOBMI-NEXT: andb $15, %dil16; CHECK-NOBMI-NEXT: andb $-16, %sil17; CHECK-NOBMI-NEXT: leal (%rsi,%rdi), %eax18; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax19; CHECK-NOBMI-NEXT: retq20;21; CHECK-BMI-LABEL: out8_constmask:22; CHECK-BMI: # %bb.0:23; CHECK-BMI-NEXT: # kill: def $esi killed $esi def $rsi24; CHECK-BMI-NEXT: # kill: def $edi killed $edi def $rdi25; CHECK-BMI-NEXT: andb $15, %dil26; CHECK-BMI-NEXT: andb $-16, %sil27; CHECK-BMI-NEXT: leal (%rsi,%rdi), %eax28; CHECK-BMI-NEXT: # kill: def $al killed $al killed $eax29; CHECK-BMI-NEXT: retq30 %mx = and i8 %x, 1531 %my = and i8 %y, -1632 %r = or i8 %mx, %my33 ret i8 %r34}35 36define i16 @out16_constmask(i16 %x, i16 %y) {37; CHECK-NOBMI-LABEL: out16_constmask:38; CHECK-NOBMI: # %bb.0:39; CHECK-NOBMI-NEXT: movzbl %dil, %eax40; CHECK-NOBMI-NEXT: andl $-256, %esi41; CHECK-NOBMI-NEXT: orl %esi, %eax42; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax43; CHECK-NOBMI-NEXT: retq44;45; CHECK-BMI-LABEL: out16_constmask:46; CHECK-BMI: # %bb.0:47; CHECK-BMI-NEXT: movzbl %dil, %eax48; CHECK-BMI-NEXT: andl $-256, %esi49; CHECK-BMI-NEXT: orl %esi, %eax50; CHECK-BMI-NEXT: # kill: def $ax killed $ax killed $eax51; CHECK-BMI-NEXT: retq52 %mx = and i16 %x, 25553 %my = and i16 %y, -25654 %r = or i16 %mx, %my55 ret i16 %r56}57 58define i32 @out32_constmask(i32 %x, i32 %y) {59; CHECK-NOBMI-LABEL: out32_constmask:60; CHECK-NOBMI: # %bb.0:61; CHECK-NOBMI-NEXT: movzwl %di, %eax62; CHECK-NOBMI-NEXT: andl $-65536, %esi # imm = 0xFFFF000063; CHECK-NOBMI-NEXT: orl %esi, %eax64; CHECK-NOBMI-NEXT: retq65;66; CHECK-BMI-LABEL: out32_constmask:67; CHECK-BMI: # %bb.0:68; CHECK-BMI-NEXT: movzwl %di, %eax69; CHECK-BMI-NEXT: andl $-65536, %esi # imm = 0xFFFF000070; CHECK-BMI-NEXT: orl %esi, %eax71; CHECK-BMI-NEXT: retq72 %mx = and i32 %x, 6553573 %my = and i32 %y, -6553674 %r = or i32 %mx, %my75 ret i32 %r76}77 78define i64 @out64_constmask(i64 %x, i64 %y) {79; CHECK-NOBMI-LABEL: out64_constmask:80; CHECK-NOBMI: # %bb.0:81; CHECK-NOBMI-NEXT: movl %edi, %ecx82; CHECK-NOBMI-NEXT: movabsq $-4294967296, %rax # imm = 0xFFFFFFFF0000000083; CHECK-NOBMI-NEXT: andq %rsi, %rax84; CHECK-NOBMI-NEXT: orq %rcx, %rax85; CHECK-NOBMI-NEXT: retq86;87; CHECK-BMI-LABEL: out64_constmask:88; CHECK-BMI: # %bb.0:89; CHECK-BMI-NEXT: movl %edi, %ecx90; CHECK-BMI-NEXT: movabsq $-4294967296, %rax # imm = 0xFFFFFFFF0000000091; CHECK-BMI-NEXT: andq %rsi, %rax92; CHECK-BMI-NEXT: orq %rcx, %rax93; CHECK-BMI-NEXT: retq94 %mx = and i64 %x, 429496729595 %my = and i64 %y, -429496729696 %r = or i64 %mx, %my97 ret i64 %r98}99 100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101; Should be the same as the previous one.102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103 104define i8 @in8_constmask(i8 %x, i8 %y) {105; CHECK-NOBMI-LABEL: in8_constmask:106; CHECK-NOBMI: # %bb.0:107; CHECK-NOBMI-NEXT: movl %esi, %eax108; CHECK-NOBMI-NEXT: xorl %esi, %edi109; CHECK-NOBMI-NEXT: andb $15, %dil110; CHECK-NOBMI-NEXT: xorb %dil, %al111; CHECK-NOBMI-NEXT: # kill: def $al killed $al killed $eax112; CHECK-NOBMI-NEXT: retq113;114; CHECK-BMI-LABEL: in8_constmask:115; CHECK-BMI: # %bb.0:116; CHECK-BMI-NEXT: movl %esi, %eax117; CHECK-BMI-NEXT: xorl %esi, %edi118; CHECK-BMI-NEXT: andb $15, %dil119; CHECK-BMI-NEXT: xorb %dil, %al120; CHECK-BMI-NEXT: # kill: def $al killed $al killed $eax121; CHECK-BMI-NEXT: retq122 %n0 = xor i8 %x, %y123 %n1 = and i8 %n0, 15124 %r = xor i8 %n1, %y125 ret i8 %r126}127 128define i16 @in16_constmask(i16 %x, i16 %y) {129; CHECK-NOBMI-LABEL: in16_constmask:130; CHECK-NOBMI: # %bb.0:131; CHECK-NOBMI-NEXT: xorl %esi, %edi132; CHECK-NOBMI-NEXT: movzbl %dil, %eax133; CHECK-NOBMI-NEXT: xorl %esi, %eax134; CHECK-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax135; CHECK-NOBMI-NEXT: retq136;137; CHECK-BMI-LABEL: in16_constmask:138; CHECK-BMI: # %bb.0:139; CHECK-BMI-NEXT: xorl %esi, %edi140; CHECK-BMI-NEXT: movzbl %dil, %eax141; CHECK-BMI-NEXT: xorl %esi, %eax142; CHECK-BMI-NEXT: # kill: def $ax killed $ax killed $eax143; CHECK-BMI-NEXT: retq144 %n0 = xor i16 %x, %y145 %n1 = and i16 %n0, 255146 %r = xor i16 %n1, %y147 ret i16 %r148}149 150define i32 @in32_constmask(i32 %x, i32 %y) {151; CHECK-NOBMI-LABEL: in32_constmask:152; CHECK-NOBMI: # %bb.0:153; CHECK-NOBMI-NEXT: xorl %esi, %edi154; CHECK-NOBMI-NEXT: movzwl %di, %eax155; CHECK-NOBMI-NEXT: xorl %esi, %eax156; CHECK-NOBMI-NEXT: retq157;158; CHECK-BMI-LABEL: in32_constmask:159; CHECK-BMI: # %bb.0:160; CHECK-BMI-NEXT: xorl %esi, %edi161; CHECK-BMI-NEXT: movzwl %di, %eax162; CHECK-BMI-NEXT: xorl %esi, %eax163; CHECK-BMI-NEXT: retq164 %n0 = xor i32 %x, %y165 %n1 = and i32 %n0, 65535166 %r = xor i32 %n1, %y167 ret i32 %r168}169 170define i64 @in64_constmask(i64 %x, i64 %y) {171; CHECK-NOBMI-LABEL: in64_constmask:172; CHECK-NOBMI: # %bb.0:173; CHECK-NOBMI-NEXT: movl %esi, %eax174; CHECK-NOBMI-NEXT: xorl %edi, %eax175; CHECK-NOBMI-NEXT: xorq %rsi, %rax176; CHECK-NOBMI-NEXT: retq177;178; CHECK-BMI-LABEL: in64_constmask:179; CHECK-BMI: # %bb.0:180; CHECK-BMI-NEXT: movl %esi, %eax181; CHECK-BMI-NEXT: xorl %edi, %eax182; CHECK-BMI-NEXT: xorq %rsi, %rax183; CHECK-BMI-NEXT: retq184 %n0 = xor i64 %x, %y185 %n1 = and i64 %n0, 4294967295186 %r = xor i64 %n1, %y187 ret i64 %r188}189 190; ============================================================================ ;191; Constant Commutativity tests.192; ============================================================================ ;193 194define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {195; CHECK-NOBMI-LABEL: in_constmask_commutativity_0_1:196; CHECK-NOBMI: # %bb.0:197; CHECK-NOBMI-NEXT: xorl %esi, %edi198; CHECK-NOBMI-NEXT: movzwl %di, %eax199; CHECK-NOBMI-NEXT: xorl %esi, %eax200; CHECK-NOBMI-NEXT: retq201;202; CHECK-BMI-LABEL: in_constmask_commutativity_0_1:203; CHECK-BMI: # %bb.0:204; CHECK-BMI-NEXT: xorl %esi, %edi205; CHECK-BMI-NEXT: movzwl %di, %eax206; CHECK-BMI-NEXT: xorl %esi, %eax207; CHECK-BMI-NEXT: retq208 %n0 = xor i32 %x, %y209 %n1 = and i32 %n0, 65535210 %r = xor i32 %y, %n1 ; swapped211 ret i32 %r212}213 214define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {215; CHECK-NOBMI-LABEL: in_constmask_commutativity_1_0:216; CHECK-NOBMI: # %bb.0:217; CHECK-NOBMI-NEXT: xorl %edi, %esi218; CHECK-NOBMI-NEXT: movzwl %si, %eax219; CHECK-NOBMI-NEXT: xorl %edi, %eax220; CHECK-NOBMI-NEXT: retq221;222; CHECK-BMI-LABEL: in_constmask_commutativity_1_0:223; CHECK-BMI: # %bb.0:224; CHECK-BMI-NEXT: xorl %edi, %esi225; CHECK-BMI-NEXT: movzwl %si, %eax226; CHECK-BMI-NEXT: xorl %edi, %eax227; CHECK-BMI-NEXT: retq228 %n0 = xor i32 %x, %y229 %n1 = and i32 %n0, 65535230 %r = xor i32 %n1, %x ; %x instead of %y231 ret i32 %r232}233 234define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {235; CHECK-NOBMI-LABEL: in_constmask_commutativity_1_1:236; CHECK-NOBMI: # %bb.0:237; CHECK-NOBMI-NEXT: xorl %edi, %esi238; CHECK-NOBMI-NEXT: movzwl %si, %eax239; CHECK-NOBMI-NEXT: xorl %edi, %eax240; CHECK-NOBMI-NEXT: retq241;242; CHECK-BMI-LABEL: in_constmask_commutativity_1_1:243; CHECK-BMI: # %bb.0:244; CHECK-BMI-NEXT: xorl %edi, %esi245; CHECK-BMI-NEXT: movzwl %si, %eax246; CHECK-BMI-NEXT: xorl %edi, %eax247; CHECK-BMI-NEXT: retq248 %n0 = xor i32 %x, %y249 %n1 = and i32 %n0, 65535250 %r = xor i32 %x, %n1 ; swapped, %x instead of %y251 ret i32 %r252}253 254; ============================================================================ ;255; Y is an 'and' too.256; ============================================================================ ;257 258define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {259; CHECK-NOBMI-LABEL: in_complex_y0_constmask:260; CHECK-NOBMI: # %bb.0:261; CHECK-NOBMI-NEXT: andl %edx, %esi262; CHECK-NOBMI-NEXT: xorl %esi, %edi263; CHECK-NOBMI-NEXT: movzwl %di, %eax264; CHECK-NOBMI-NEXT: xorl %esi, %eax265; CHECK-NOBMI-NEXT: retq266;267; CHECK-BMI-LABEL: in_complex_y0_constmask:268; CHECK-BMI: # %bb.0:269; CHECK-BMI-NEXT: andl %edx, %esi270; CHECK-BMI-NEXT: xorl %esi, %edi271; CHECK-BMI-NEXT: movzwl %di, %eax272; CHECK-BMI-NEXT: xorl %esi, %eax273; CHECK-BMI-NEXT: retq274 %y = and i32 %y_hi, %y_low275 %n0 = xor i32 %x, %y276 %n1 = and i32 %n0, 65535277 %r = xor i32 %n1, %y278 ret i32 %r279}280 281define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {282; CHECK-NOBMI-LABEL: in_complex_y1_constmask:283; CHECK-NOBMI: # %bb.0:284; CHECK-NOBMI-NEXT: andl %edx, %esi285; CHECK-NOBMI-NEXT: xorl %esi, %edi286; CHECK-NOBMI-NEXT: movzwl %di, %eax287; CHECK-NOBMI-NEXT: xorl %esi, %eax288; CHECK-NOBMI-NEXT: retq289;290; CHECK-BMI-LABEL: in_complex_y1_constmask:291; CHECK-BMI: # %bb.0:292; CHECK-BMI-NEXT: andl %edx, %esi293; CHECK-BMI-NEXT: xorl %esi, %edi294; CHECK-BMI-NEXT: movzwl %di, %eax295; CHECK-BMI-NEXT: xorl %esi, %eax296; CHECK-BMI-NEXT: retq297 %y = and i32 %y_hi, %y_low298 %n0 = xor i32 %x, %y299 %n1 = and i32 %n0, 65535300 %r = xor i32 %y, %n1301 ret i32 %r302}303 304; ============================================================================ ;305; Negative tests. Should not be folded.306; ============================================================================ ;307 308; Multi-use tests.309 310declare void @use32(i32) nounwind311 312define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {313; CHECK-NOBMI-LABEL: in_multiuse_A_constmask:314; CHECK-NOBMI: # %bb.0:315; CHECK-NOBMI-NEXT: pushq %rbp316; CHECK-NOBMI-NEXT: pushq %rbx317; CHECK-NOBMI-NEXT: pushq %rax318; CHECK-NOBMI-NEXT: movl %esi, %ebx319; CHECK-NOBMI-NEXT: xorl %esi, %edi320; CHECK-NOBMI-NEXT: movzwl %di, %ebp321; CHECK-NOBMI-NEXT: movl %ebp, %edi322; CHECK-NOBMI-NEXT: callq use32@PLT323; CHECK-NOBMI-NEXT: xorl %ebx, %ebp324; CHECK-NOBMI-NEXT: movl %ebp, %eax325; CHECK-NOBMI-NEXT: addq $8, %rsp326; CHECK-NOBMI-NEXT: popq %rbx327; CHECK-NOBMI-NEXT: popq %rbp328; CHECK-NOBMI-NEXT: retq329;330; CHECK-BMI-LABEL: in_multiuse_A_constmask:331; CHECK-BMI: # %bb.0:332; CHECK-BMI-NEXT: pushq %rbp333; CHECK-BMI-NEXT: pushq %rbx334; CHECK-BMI-NEXT: pushq %rax335; CHECK-BMI-NEXT: movl %esi, %ebx336; CHECK-BMI-NEXT: xorl %esi, %edi337; CHECK-BMI-NEXT: movzwl %di, %ebp338; CHECK-BMI-NEXT: movl %ebp, %edi339; CHECK-BMI-NEXT: callq use32@PLT340; CHECK-BMI-NEXT: xorl %ebx, %ebp341; CHECK-BMI-NEXT: movl %ebp, %eax342; CHECK-BMI-NEXT: addq $8, %rsp343; CHECK-BMI-NEXT: popq %rbx344; CHECK-BMI-NEXT: popq %rbp345; CHECK-BMI-NEXT: retq346 %n0 = xor i32 %x, %y347 %n1 = and i32 %n0, 65535348 call void @use32(i32 %n1)349 %r = xor i32 %n1, %y350 ret i32 %r351}352 353define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {354; CHECK-NOBMI-LABEL: in_multiuse_B_constmask:355; CHECK-NOBMI: # %bb.0:356; CHECK-NOBMI-NEXT: pushq %rbp357; CHECK-NOBMI-NEXT: pushq %rbx358; CHECK-NOBMI-NEXT: pushq %rax359; CHECK-NOBMI-NEXT: movl %esi, %ebx360; CHECK-NOBMI-NEXT: xorl %esi, %edi361; CHECK-NOBMI-NEXT: movzwl %di, %ebp362; CHECK-NOBMI-NEXT: callq use32@PLT363; CHECK-NOBMI-NEXT: xorl %ebx, %ebp364; CHECK-NOBMI-NEXT: movl %ebp, %eax365; CHECK-NOBMI-NEXT: addq $8, %rsp366; CHECK-NOBMI-NEXT: popq %rbx367; CHECK-NOBMI-NEXT: popq %rbp368; CHECK-NOBMI-NEXT: retq369;370; CHECK-BMI-LABEL: in_multiuse_B_constmask:371; CHECK-BMI: # %bb.0:372; CHECK-BMI-NEXT: pushq %rbp373; CHECK-BMI-NEXT: pushq %rbx374; CHECK-BMI-NEXT: pushq %rax375; CHECK-BMI-NEXT: movl %esi, %ebx376; CHECK-BMI-NEXT: xorl %esi, %edi377; CHECK-BMI-NEXT: movzwl %di, %ebp378; CHECK-BMI-NEXT: callq use32@PLT379; CHECK-BMI-NEXT: xorl %ebx, %ebp380; CHECK-BMI-NEXT: movl %ebp, %eax381; CHECK-BMI-NEXT: addq $8, %rsp382; CHECK-BMI-NEXT: popq %rbx383; CHECK-BMI-NEXT: popq %rbp384; CHECK-BMI-NEXT: retq385 %n0 = xor i32 %x, %y386 %n1 = and i32 %n0, 65535387 call void @use32(i32 %n0)388 %r = xor i32 %n1, %y389 ret i32 %r390}391 392; Various bad variants393 394define i32 @n0_badconstmask(i32 %x, i32 %y) {395; CHECK-NOBMI-LABEL: n0_badconstmask:396; CHECK-NOBMI: # %bb.0:397; CHECK-NOBMI-NEXT: movzwl %di, %eax398; CHECK-NOBMI-NEXT: andl $-65535, %esi # imm = 0xFFFF0001399; CHECK-NOBMI-NEXT: orl %esi, %eax400; CHECK-NOBMI-NEXT: retq401;402; CHECK-BMI-LABEL: n0_badconstmask:403; CHECK-BMI: # %bb.0:404; CHECK-BMI-NEXT: movzwl %di, %eax405; CHECK-BMI-NEXT: andl $-65535, %esi # imm = 0xFFFF0001406; CHECK-BMI-NEXT: orl %esi, %eax407; CHECK-BMI-NEXT: retq408 %mx = and i32 %x, 65535409 %my = and i32 %y, -65535 ; instead of -65536410 %r = or i32 %mx, %my411 ret i32 %r412}413 414define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {415; CHECK-NOBMI-LABEL: n1_thirdvar_constmask:416; CHECK-NOBMI: # %bb.0:417; CHECK-NOBMI-NEXT: xorl %esi, %edi418; CHECK-NOBMI-NEXT: movzwl %di, %eax419; CHECK-NOBMI-NEXT: xorl %edx, %eax420; CHECK-NOBMI-NEXT: retq421;422; CHECK-BMI-LABEL: n1_thirdvar_constmask:423; CHECK-BMI: # %bb.0:424; CHECK-BMI-NEXT: xorl %esi, %edi425; CHECK-BMI-NEXT: movzwl %di, %eax426; CHECK-BMI-NEXT: xorl %edx, %eax427; CHECK-BMI-NEXT: retq428 %n0 = xor i32 %x, %y429 %n1 = and i32 %n0, 65535430 %r = xor i32 %n1, %z ; instead of %y431 ret i32 %r432}433