263 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefixes=CHECK,CHECK-SSE3; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx | FileCheck %s --check-prefixes=CHECK,CHECK-AVX,CHECK-AVX14; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx512f,+avx512vl,+avx512bw | FileCheck %s --check-prefixes=CHECK,CHECK-AVX,CHECK-AVX5125 6define i32 @mul_and_to_neg_shl_and(i32 %x) {7; CHECK-LABEL: mul_and_to_neg_shl_and:8; CHECK: # %bb.0:9; CHECK-NEXT: # kill: def $edi killed $edi def $rdi10; CHECK-NEXT: negl %edi11; CHECK-NEXT: leal (,%rdi,8), %eax12; CHECK-NEXT: andl $56, %eax13; CHECK-NEXT: retq14 %mul = mul i32 %x, 5615 %and = and i32 %mul, 5616 ret i32 %and17}18 19define i32 @mul_and_to_neg_shl_and2(i32 %x) {20; CHECK-LABEL: mul_and_to_neg_shl_and2:21; CHECK: # %bb.0:22; CHECK-NEXT: # kill: def $edi killed $edi def $rdi23; CHECK-NEXT: negl %edi24; CHECK-NEXT: leal (,%rdi,8), %eax25; CHECK-NEXT: andl $48, %eax26; CHECK-NEXT: retq27 %mul = mul i32 %x, 5628 %and = and i32 %mul, 5129 ret i32 %and30}31 32define <4 x i32> @mul_and_to_neg_shl_and_vec(<4 x i32> %x) {33; CHECK-SSE-LABEL: mul_and_to_neg_shl_and_vec:34; CHECK-SSE: # %bb.0:35; CHECK-SSE-NEXT: pxor %xmm1, %xmm136; CHECK-SSE-NEXT: psubd %xmm0, %xmm137; CHECK-SSE-NEXT: pslld $3, %xmm138; CHECK-SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm139; CHECK-SSE-NEXT: movdqa %xmm1, %xmm040; CHECK-SSE-NEXT: retq41;42; CHECK-AVX1-LABEL: mul_and_to_neg_shl_and_vec:43; CHECK-AVX1: # %bb.0:44; CHECK-AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm145; CHECK-AVX1-NEXT: vpsubd %xmm0, %xmm1, %xmm046; CHECK-AVX1-NEXT: vpslld $3, %xmm0, %xmm047; CHECK-AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm048; CHECK-AVX1-NEXT: retq49;50; CHECK-AVX512-LABEL: mul_and_to_neg_shl_and_vec:51; CHECK-AVX512: # %bb.0:52; CHECK-AVX512-NEXT: vpxor %xmm1, %xmm1, %xmm153; CHECK-AVX512-NEXT: vpsubd %xmm0, %xmm1, %xmm054; CHECK-AVX512-NEXT: vpslld $3, %xmm0, %xmm055; CHECK-AVX512-NEXT: vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm056; CHECK-AVX512-NEXT: retq57 %mul = mul <4 x i32> %x, <i32 56, i32 56, i32 56, i32 56>58 %and = and <4 x i32> %mul, <i32 48, i32 48, i32 48, i32 48>59 ret <4 x i32> %and60}61 62define <4 x i32> @mul_and_to_neg_shl_and_vec_fail_no_splat(<4 x i32> %x) {63; CHECK-SSE-LABEL: mul_and_to_neg_shl_and_vec_fail_no_splat:64; CHECK-SSE: # %bb.0:65; CHECK-SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]66; CHECK-SSE-NEXT: pmuludq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [56,56,56,64]67; CHECK-SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]68; CHECK-SSE-NEXT: pmuludq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 # [56,u,64,u]69; CHECK-SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]70; CHECK-SSE-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]71; CHECK-SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm072; CHECK-SSE-NEXT: retq73;74; CHECK-AVX1-LABEL: mul_and_to_neg_shl_and_vec_fail_no_splat:75; CHECK-AVX1: # %bb.0:76; CHECK-AVX1-NEXT: vpmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [56,56,56,64]77; CHECK-AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm078; CHECK-AVX1-NEXT: retq79;80; CHECK-AVX512-LABEL: mul_and_to_neg_shl_and_vec_fail_no_splat:81; CHECK-AVX512: # %bb.0:82; CHECK-AVX512-NEXT: vpmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [56,56,56,64]83; CHECK-AVX512-NEXT: vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm084; CHECK-AVX512-NEXT: retq85 %mul = mul <4 x i32> %x, <i32 56, i32 56, i32 56, i32 64>86 %and = and <4 x i32> %mul, <i32 48, i32 48, i32 48, i32 48>87 ret <4 x i32> %and88}89 90;; todo_no_splat ones have the correct invariants for all elements.91define <4 x i32> @mul_and_to_neg_shl_and_vec_todo_no_splat1(<4 x i32> %x) {92; CHECK-SSE-LABEL: mul_and_to_neg_shl_and_vec_todo_no_splat1:93; CHECK-SSE: # %bb.0:94; CHECK-SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]95; CHECK-SSE-NEXT: pmuludq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [56,56,56,48]96; CHECK-SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]97; CHECK-SSE-NEXT: pmuludq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 # [56,u,48,u]98; CHECK-SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]99; CHECK-SSE-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]100; CHECK-SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0101; CHECK-SSE-NEXT: retq102;103; CHECK-AVX1-LABEL: mul_and_to_neg_shl_and_vec_todo_no_splat1:104; CHECK-AVX1: # %bb.0:105; CHECK-AVX1-NEXT: vpmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [56,56,56,48]106; CHECK-AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0107; CHECK-AVX1-NEXT: retq108;109; CHECK-AVX512-LABEL: mul_and_to_neg_shl_and_vec_todo_no_splat1:110; CHECK-AVX512: # %bb.0:111; CHECK-AVX512-NEXT: vpmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [56,56,56,48]112; CHECK-AVX512-NEXT: vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm0113; CHECK-AVX512-NEXT: retq114 %mul = mul <4 x i32> %x, <i32 56, i32 56, i32 56, i32 48>115 %and = and <4 x i32> %mul, <i32 48, i32 48, i32 48, i32 48>116 ret <4 x i32> %and117}118 119define <4 x i32> @mul_and_to_neg_shl_and_vec_todo_no_splat2(<4 x i32> %x) {120; CHECK-SSE-LABEL: mul_and_to_neg_shl_and_vec_todo_no_splat2:121; CHECK-SSE: # %bb.0:122; CHECK-SSE-NEXT: movdqa {{.*#+}} xmm1 = [56,56,56,56]123; CHECK-SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]124; CHECK-SSE-NEXT: pmuludq %xmm1, %xmm0125; CHECK-SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]126; CHECK-SSE-NEXT: pmuludq %xmm1, %xmm2127; CHECK-SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm2[0,2,2,3]128; CHECK-SSE-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]129; CHECK-SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0130; CHECK-SSE-NEXT: retq131;132; CHECK-AVX1-LABEL: mul_and_to_neg_shl_and_vec_todo_no_splat2:133; CHECK-AVX1: # %bb.0:134; CHECK-AVX1-NEXT: vpmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [56,56,56,56]135; CHECK-AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0136; CHECK-AVX1-NEXT: retq137;138; CHECK-AVX512-LABEL: mul_and_to_neg_shl_and_vec_todo_no_splat2:139; CHECK-AVX512: # %bb.0:140; CHECK-AVX512-NEXT: vpmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm0141; CHECK-AVX512-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0142; CHECK-AVX512-NEXT: retq143 %mul = mul <4 x i32> %x, <i32 56, i32 56, i32 56, i32 56>144 %and = and <4 x i32> %mul, <i32 48, i32 48, i32 48, i32 32>145 ret <4 x i32> %and146}147 148define <4 x i32> @mul_and_to_neg_shl_and_vec_with_undef_mul(<4 x i32> %x) {149; CHECK-SSE-LABEL: mul_and_to_neg_shl_and_vec_with_undef_mul:150; CHECK-SSE: # %bb.0:151; CHECK-SSE-NEXT: pxor %xmm1, %xmm1152; CHECK-SSE-NEXT: psubd %xmm0, %xmm1153; CHECK-SSE-NEXT: pslld $3, %xmm1154; CHECK-SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1155; CHECK-SSE-NEXT: movdqa %xmm1, %xmm0156; CHECK-SSE-NEXT: retq157;158; CHECK-AVX1-LABEL: mul_and_to_neg_shl_and_vec_with_undef_mul:159; CHECK-AVX1: # %bb.0:160; CHECK-AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1161; CHECK-AVX1-NEXT: vpsubd %xmm0, %xmm1, %xmm0162; CHECK-AVX1-NEXT: vpslld $3, %xmm0, %xmm0163; CHECK-AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0164; CHECK-AVX1-NEXT: retq165;166; CHECK-AVX512-LABEL: mul_and_to_neg_shl_and_vec_with_undef_mul:167; CHECK-AVX512: # %bb.0:168; CHECK-AVX512-NEXT: vpxor %xmm1, %xmm1, %xmm1169; CHECK-AVX512-NEXT: vpsubd %xmm0, %xmm1, %xmm0170; CHECK-AVX512-NEXT: vpslld $3, %xmm0, %xmm0171; CHECK-AVX512-NEXT: vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm0172; CHECK-AVX512-NEXT: retq173 %mul = mul <4 x i32> %x, <i32 56, i32 56, i32 56, i32 undef>174 %and = and <4 x i32> %mul, <i32 48, i32 48, i32 48, i32 48>175 ret <4 x i32> %and176}177 178define <4 x i32> @mul_and_to_neg_shl_and_vec_with_undef_and(<4 x i32> %x) {179; CHECK-SSE-LABEL: mul_and_to_neg_shl_and_vec_with_undef_and:180; CHECK-SSE: # %bb.0:181; CHECK-SSE-NEXT: pxor %xmm1, %xmm1182; CHECK-SSE-NEXT: psubd %xmm0, %xmm1183; CHECK-SSE-NEXT: pslld $3, %xmm1184; CHECK-SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1185; CHECK-SSE-NEXT: movdqa %xmm1, %xmm0186; CHECK-SSE-NEXT: retq187;188; CHECK-AVX1-LABEL: mul_and_to_neg_shl_and_vec_with_undef_and:189; CHECK-AVX1: # %bb.0:190; CHECK-AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1191; CHECK-AVX1-NEXT: vpsubd %xmm0, %xmm1, %xmm0192; CHECK-AVX1-NEXT: vpslld $3, %xmm0, %xmm0193; CHECK-AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0194; CHECK-AVX1-NEXT: retq195;196; CHECK-AVX512-LABEL: mul_and_to_neg_shl_and_vec_with_undef_and:197; CHECK-AVX512: # %bb.0:198; CHECK-AVX512-NEXT: vpxor %xmm1, %xmm1, %xmm1199; CHECK-AVX512-NEXT: vpsubd %xmm0, %xmm1, %xmm0200; CHECK-AVX512-NEXT: vpslld $3, %xmm0, %xmm0201; CHECK-AVX512-NEXT: vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm0202; CHECK-AVX512-NEXT: retq203 %mul = mul <4 x i32> %x, <i32 56, i32 56, i32 56, i32 56>204 %and = and <4 x i32> %mul, <i32 48, i32 48, i32 48, i32 undef>205 ret <4 x i32> %and206}207 208define <16 x i8> @mul_and_to_neg_shl_and_vec_with_undef_mul_and(<16 x i8> %x) {209; CHECK-SSE-LABEL: mul_and_to_neg_shl_and_vec_with_undef_mul_and:210; CHECK-SSE: # %bb.0:211; CHECK-SSE-NEXT: pxor %xmm1, %xmm1212; CHECK-SSE-NEXT: psubb %xmm0, %xmm1213; CHECK-SSE-NEXT: psllw $2, %xmm1214; CHECK-SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1215; CHECK-SSE-NEXT: movdqa %xmm1, %xmm0216; CHECK-SSE-NEXT: retq217;218; CHECK-AVX-LABEL: mul_and_to_neg_shl_and_vec_with_undef_mul_and:219; CHECK-AVX: # %bb.0:220; CHECK-AVX-NEXT: vpxor %xmm1, %xmm1, %xmm1221; CHECK-AVX-NEXT: vpsubb %xmm0, %xmm1, %xmm0222; CHECK-AVX-NEXT: vpsllw $2, %xmm0, %xmm0223; CHECK-AVX-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0224; CHECK-AVX-NEXT: retq225 %mul = mul <16 x i8> %x, <i8 12, i8 12, i8 12, i8 12, i8 undef, i8 12, i8 12, i8 12, i8 12, i8 12, i8 12, i8 12, i8 12, i8 12, i8 12, i8 12>226 %and = and <16 x i8> %mul, <i8 11, i8 undef, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11>227 ret <16 x i8> %and228}229 230define i32 @mul_and_to_neg_shl_and_fail_invalid_mul(i32 %x) {231; CHECK-LABEL: mul_and_to_neg_shl_and_fail_invalid_mul:232; CHECK: # %bb.0:233; CHECK-NEXT: imull $57, %edi, %eax234; CHECK-NEXT: andl $56, %eax235; CHECK-NEXT: retq236 %mul = mul i32 %x, 57237 %and = and i32 %mul, 56238 ret i32 %and239}240 241define i32 @mul_and_to_neg_shl_and_fail_mul_p2(i32 %x) {242; CHECK-LABEL: mul_and_to_neg_shl_and_fail_mul_p2:243; CHECK: # %bb.0:244; CHECK-NEXT: movl %edi, %eax245; CHECK-NEXT: shll $6, %eax246; CHECK-NEXT: andl $64, %eax247; CHECK-NEXT: retq248 %mul = mul i32 %x, 64249 %and = and i32 %mul, 64250 ret i32 %and251}252 253define i32 @mul_and_to_neg_shl_and_fail_mask_to_large(i32 %x) {254; CHECK-LABEL: mul_and_to_neg_shl_and_fail_mask_to_large:255; CHECK: # %bb.0:256; CHECK-NEXT: imull $56, %edi, %eax257; CHECK-NEXT: andl $120, %eax258; CHECK-NEXT: retq259 %mul = mul i32 %x, 56260 %and = and i32 %mul, 120261 ret i32 %and262}263