453 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE23; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE414; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX6 7; 0'th element insertion into an SSE register.8 9define <4 x float> @insert_f32_firstelt(<4 x float> %x, ptr %s.addr) {10; SSE-LABEL: insert_f32_firstelt:11; SSE: # %bb.0:12; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero13; SSE-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]14; SSE-NEXT: retq15;16; AVX-LABEL: insert_f32_firstelt:17; AVX: # %bb.0:18; AVX-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero19; AVX-NEXT: vmovss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]20; AVX-NEXT: retq21 %s = load float, ptr %s.addr22 %i0 = insertelement <4 x float> %x, float %s, i32 023 ret <4 x float> %i024}25 26define <2 x double> @insert_f64_firstelt(<2 x double> %x, ptr %s.addr) {27; SSE-LABEL: insert_f64_firstelt:28; SSE: # %bb.0:29; SSE-NEXT: movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]30; SSE-NEXT: retq31;32; AVX-LABEL: insert_f64_firstelt:33; AVX: # %bb.0:34; AVX-NEXT: vmovlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]35; AVX-NEXT: retq36 %s = load double, ptr %s.addr37 %i0 = insertelement <2 x double> %x, double %s, i32 038 ret <2 x double> %i039}40 41define <16 x i8> @insert_i8_firstelt(<16 x i8> %x, ptr %s.addr) {42; SSE2-LABEL: insert_i8_firstelt:43; SSE2: # %bb.0:44; SSE2-NEXT: movdqa {{.*#+}} xmm1 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]45; SSE2-NEXT: pand %xmm1, %xmm046; SSE2-NEXT: movzbl (%rdi), %eax47; SSE2-NEXT: movd %eax, %xmm248; SSE2-NEXT: pandn %xmm2, %xmm149; SSE2-NEXT: por %xmm1, %xmm050; SSE2-NEXT: retq51;52; SSE41-LABEL: insert_i8_firstelt:53; SSE41: # %bb.0:54; SSE41-NEXT: pinsrb $0, (%rdi), %xmm055; SSE41-NEXT: retq56;57; AVX-LABEL: insert_i8_firstelt:58; AVX: # %bb.0:59; AVX-NEXT: vpinsrb $0, (%rdi), %xmm0, %xmm060; AVX-NEXT: retq61 %s = load i8, ptr %s.addr62 %i0 = insertelement <16 x i8> %x, i8 %s, i32 063 ret <16 x i8> %i064}65 66define <8 x i16> @insert_i16_firstelt(<8 x i16> %x, ptr %s.addr) {67; SSE-LABEL: insert_i16_firstelt:68; SSE: # %bb.0:69; SSE-NEXT: pinsrw $0, (%rdi), %xmm070; SSE-NEXT: retq71;72; AVX-LABEL: insert_i16_firstelt:73; AVX: # %bb.0:74; AVX-NEXT: vpinsrw $0, (%rdi), %xmm0, %xmm075; AVX-NEXT: retq76 %s = load i16, ptr %s.addr77 %i0 = insertelement <8 x i16> %x, i16 %s, i32 078 ret <8 x i16> %i079}80 81define <4 x i32> @insert_i32_firstelt(<4 x i32> %x, ptr %s.addr) {82; SSE2-LABEL: insert_i32_firstelt:83; SSE2: # %bb.0:84; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero85; SSE2-NEXT: movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]86; SSE2-NEXT: retq87;88; SSE41-LABEL: insert_i32_firstelt:89; SSE41: # %bb.0:90; SSE41-NEXT: pinsrd $0, (%rdi), %xmm091; SSE41-NEXT: retq92;93; AVX-LABEL: insert_i32_firstelt:94; AVX: # %bb.0:95; AVX-NEXT: vpinsrd $0, (%rdi), %xmm0, %xmm096; AVX-NEXT: retq97 %s = load i32, ptr %s.addr98 %i0 = insertelement <4 x i32> %x, i32 %s, i32 099 ret <4 x i32> %i0100}101 102define <2 x i64> @insert_i64_firstelt(<2 x i64> %x, ptr %s.addr) {103; SSE2-LABEL: insert_i64_firstelt:104; SSE2: # %bb.0:105; SSE2-NEXT: movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]106; SSE2-NEXT: retq107;108; SSE41-LABEL: insert_i64_firstelt:109; SSE41: # %bb.0:110; SSE41-NEXT: pinsrq $0, (%rdi), %xmm0111; SSE41-NEXT: retq112;113; AVX-LABEL: insert_i64_firstelt:114; AVX: # %bb.0:115; AVX-NEXT: vpinsrq $0, (%rdi), %xmm0, %xmm0116; AVX-NEXT: retq117 %s = load i64, ptr %s.addr118 %i0 = insertelement <2 x i64> %x, i64 %s, i32 0119 ret <2 x i64> %i0120}121 122; 1'th element insertion.123 124define <4 x float> @insert_f32_secondelt(<4 x float> %x, ptr %s.addr) {125; SSE2-LABEL: insert_f32_secondelt:126; SSE2: # %bb.0:127; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero128; SSE2-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]129; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]130; SSE2-NEXT: movaps %xmm1, %xmm0131; SSE2-NEXT: retq132;133; SSE41-LABEL: insert_f32_secondelt:134; SSE41: # %bb.0:135; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3]136; SSE41-NEXT: retq137;138; AVX-LABEL: insert_f32_secondelt:139; AVX: # %bb.0:140; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3]141; AVX-NEXT: retq142 %s = load float, ptr %s.addr143 %i0 = insertelement <4 x float> %x, float %s, i32 1144 ret <4 x float> %i0145}146 147define <2 x double> @insert_f64_secondelt(<2 x double> %x, ptr %s.addr) {148; SSE-LABEL: insert_f64_secondelt:149; SSE: # %bb.0:150; SSE-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]151; SSE-NEXT: retq152;153; AVX-LABEL: insert_f64_secondelt:154; AVX: # %bb.0:155; AVX-NEXT: vmovhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]156; AVX-NEXT: retq157 %s = load double, ptr %s.addr158 %i0 = insertelement <2 x double> %x, double %s, i32 1159 ret <2 x double> %i0160}161 162define <16 x i8> @insert_i8_secondelt(<16 x i8> %x, ptr %s.addr) {163; SSE2-LABEL: insert_i8_secondelt:164; SSE2: # %bb.0:165; SSE2-NEXT: movdqa {{.*#+}} xmm1 = [255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255]166; SSE2-NEXT: pand %xmm1, %xmm0167; SSE2-NEXT: movzbl (%rdi), %eax168; SSE2-NEXT: movd %eax, %xmm2169; SSE2-NEXT: psllw $8, %xmm2170; SSE2-NEXT: pandn %xmm2, %xmm1171; SSE2-NEXT: por %xmm1, %xmm0172; SSE2-NEXT: retq173;174; SSE41-LABEL: insert_i8_secondelt:175; SSE41: # %bb.0:176; SSE41-NEXT: pinsrb $1, (%rdi), %xmm0177; SSE41-NEXT: retq178;179; AVX-LABEL: insert_i8_secondelt:180; AVX: # %bb.0:181; AVX-NEXT: vpinsrb $1, (%rdi), %xmm0, %xmm0182; AVX-NEXT: retq183 %s = load i8, ptr %s.addr184 %i0 = insertelement <16 x i8> %x, i8 %s, i32 1185 ret <16 x i8> %i0186}187 188define <8 x i16> @insert_i16_secondelt(<8 x i16> %x, ptr %s.addr) {189; SSE-LABEL: insert_i16_secondelt:190; SSE: # %bb.0:191; SSE-NEXT: pinsrw $1, (%rdi), %xmm0192; SSE-NEXT: retq193;194; AVX-LABEL: insert_i16_secondelt:195; AVX: # %bb.0:196; AVX-NEXT: vpinsrw $1, (%rdi), %xmm0, %xmm0197; AVX-NEXT: retq198 %s = load i16, ptr %s.addr199 %i0 = insertelement <8 x i16> %x, i16 %s, i32 1200 ret <8 x i16> %i0201}202 203define <4 x i32> @insert_i32_secondelt(<4 x i32> %x, ptr %s.addr) {204; SSE2-LABEL: insert_i32_secondelt:205; SSE2: # %bb.0:206; SSE2-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero207; SSE2-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]208; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]209; SSE2-NEXT: movaps %xmm1, %xmm0210; SSE2-NEXT: retq211;212; SSE41-LABEL: insert_i32_secondelt:213; SSE41: # %bb.0:214; SSE41-NEXT: pinsrd $1, (%rdi), %xmm0215; SSE41-NEXT: retq216;217; AVX-LABEL: insert_i32_secondelt:218; AVX: # %bb.0:219; AVX-NEXT: vpinsrd $1, (%rdi), %xmm0, %xmm0220; AVX-NEXT: retq221 %s = load i32, ptr %s.addr222 %i0 = insertelement <4 x i32> %x, i32 %s, i32 1223 ret <4 x i32> %i0224}225 226define <2 x i64> @insert_i64_secondelt(<2 x i64> %x, ptr %s.addr) {227; SSE2-LABEL: insert_i64_secondelt:228; SSE2: # %bb.0:229; SSE2-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero230; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]231; SSE2-NEXT: retq232;233; SSE41-LABEL: insert_i64_secondelt:234; SSE41: # %bb.0:235; SSE41-NEXT: pinsrq $1, (%rdi), %xmm0236; SSE41-NEXT: retq237;238; AVX-LABEL: insert_i64_secondelt:239; AVX: # %bb.0:240; AVX-NEXT: vpinsrq $1, (%rdi), %xmm0, %xmm0241; AVX-NEXT: retq242 %s = load i64, ptr %s.addr243 %i0 = insertelement <2 x i64> %x, i64 %s, i32 1244 ret <2 x i64> %i0245}246 247; element insertion into two elements248 249define <4 x float> @insert_f32_two_elts(<4 x float> %x, ptr %s.addr) {250; SSE-LABEL: insert_f32_two_elts:251; SSE: # %bb.0:252; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero253; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3]254; SSE-NEXT: movaps %xmm1, %xmm0255; SSE-NEXT: retq256;257; AVX-LABEL: insert_f32_two_elts:258; AVX: # %bb.0:259; AVX-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero260; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,0],xmm0[2,3]261; AVX-NEXT: retq262 %s = load float, ptr %s.addr263 %i0 = insertelement <4 x float> %x, float %s, i32 0264 %i1 = insertelement <4 x float> %i0, float %s, i32 1265 ret <4 x float> %i1266}267 268define <2 x double> @insert_f64_two_elts(<2 x double> %x, ptr %s.addr) {269; SSE2-LABEL: insert_f64_two_elts:270; SSE2: # %bb.0:271; SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero272; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0]273; SSE2-NEXT: retq274;275; SSE41-LABEL: insert_f64_two_elts:276; SSE41: # %bb.0:277; SSE41-NEXT: movddup {{.*#+}} xmm0 = mem[0,0]278; SSE41-NEXT: retq279;280; AVX-LABEL: insert_f64_two_elts:281; AVX: # %bb.0:282; AVX-NEXT: vmovddup {{.*#+}} xmm0 = mem[0,0]283; AVX-NEXT: retq284 %s = load double, ptr %s.addr285 %i0 = insertelement <2 x double> %x, double %s, i32 0286 %i1 = insertelement <2 x double> %i0, double %s, i32 1287 ret <2 x double> %i1288}289 290define <16 x i8> @insert_i8_two_elts(<16 x i8> %x, ptr %s.addr) {291; SSE2-LABEL: insert_i8_two_elts:292; SSE2: # %bb.0:293; SSE2-NEXT: movdqa {{.*#+}} xmm1 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]294; SSE2-NEXT: pand %xmm1, %xmm0295; SSE2-NEXT: movzbl (%rdi), %eax296; SSE2-NEXT: movd %eax, %xmm2297; SSE2-NEXT: pandn %xmm2, %xmm1298; SSE2-NEXT: por %xmm1, %xmm0299; SSE2-NEXT: movdqa {{.*#+}} xmm1 = [255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255]300; SSE2-NEXT: pand %xmm1, %xmm0301; SSE2-NEXT: psllw $8, %xmm2302; SSE2-NEXT: pandn %xmm2, %xmm1303; SSE2-NEXT: por %xmm1, %xmm0304; SSE2-NEXT: retq305;306; SSE41-LABEL: insert_i8_two_elts:307; SSE41: # %bb.0:308; SSE41-NEXT: movzbl (%rdi), %eax309; SSE41-NEXT: pinsrb $0, %eax, %xmm0310; SSE41-NEXT: pinsrb $1, %eax, %xmm0311; SSE41-NEXT: retq312;313; AVX-LABEL: insert_i8_two_elts:314; AVX: # %bb.0:315; AVX-NEXT: movzbl (%rdi), %eax316; AVX-NEXT: vpinsrb $0, %eax, %xmm0, %xmm0317; AVX-NEXT: vpinsrb $1, %eax, %xmm0, %xmm0318; AVX-NEXT: retq319 %s = load i8, ptr %s.addr320 %i0 = insertelement <16 x i8> %x, i8 %s, i32 0321 %i1 = insertelement <16 x i8> %i0, i8 %s, i32 1322 ret <16 x i8> %i1323}324 325define <8 x i16> @insert_i16_two_elts(<8 x i16> %x, ptr %s.addr) {326; SSE-LABEL: insert_i16_two_elts:327; SSE: # %bb.0:328; SSE-NEXT: movzwl (%rdi), %eax329; SSE-NEXT: pinsrw $0, %eax, %xmm0330; SSE-NEXT: pinsrw $1, %eax, %xmm0331; SSE-NEXT: retq332;333; AVX-LABEL: insert_i16_two_elts:334; AVX: # %bb.0:335; AVX-NEXT: movzwl (%rdi), %eax336; AVX-NEXT: vpinsrw $0, %eax, %xmm0, %xmm0337; AVX-NEXT: vpinsrw $1, %eax, %xmm0, %xmm0338; AVX-NEXT: retq339 %s = load i16, ptr %s.addr340 %i0 = insertelement <8 x i16> %x, i16 %s, i32 0341 %i1 = insertelement <8 x i16> %i0, i16 %s, i32 1342 ret <8 x i16> %i1343}344 345define <4 x i32> @insert_i32_two_elts(<4 x i32> %x, ptr %s.addr) {346; SSE2-LABEL: insert_i32_two_elts:347; SSE2: # %bb.0:348; SSE2-NEXT: movl (%rdi), %eax349; SSE2-NEXT: movd %eax, %xmm2350; SSE2-NEXT: movd %eax, %xmm1351; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]352; SSE2-NEXT: shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]353; SSE2-NEXT: movaps %xmm1, %xmm0354; SSE2-NEXT: retq355;356; SSE41-LABEL: insert_i32_two_elts:357; SSE41: # %bb.0:358; SSE41-NEXT: movl (%rdi), %eax359; SSE41-NEXT: pinsrd $0, %eax, %xmm0360; SSE41-NEXT: pinsrd $1, %eax, %xmm0361; SSE41-NEXT: retq362;363; AVX-LABEL: insert_i32_two_elts:364; AVX: # %bb.0:365; AVX-NEXT: movl (%rdi), %eax366; AVX-NEXT: vpinsrd $0, %eax, %xmm0, %xmm0367; AVX-NEXT: vpinsrd $1, %eax, %xmm0, %xmm0368; AVX-NEXT: retq369 %s = load i32, ptr %s.addr370 %i0 = insertelement <4 x i32> %x, i32 %s, i32 0371 %i1 = insertelement <4 x i32> %i0, i32 %s, i32 1372 ret <4 x i32> %i1373}374 375define <2 x i64> @insert_i64_two_elts(<2 x i64> %x, ptr %s.addr) {376; SSE-LABEL: insert_i64_two_elts:377; SSE: # %bb.0:378; SSE-NEXT: movq {{.*#+}} xmm0 = mem[0],zero379; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]380; SSE-NEXT: retq381;382; AVX-LABEL: insert_i64_two_elts:383; AVX: # %bb.0:384; AVX-NEXT: vmovddup {{.*#+}} xmm0 = mem[0,0]385; AVX-NEXT: retq386 %s = load i64, ptr %s.addr387 %i0 = insertelement <2 x i64> %x, i64 %s, i32 0388 %i1 = insertelement <2 x i64> %i0, i64 %s, i32 1389 ret <2 x i64> %i1390}391 392; Special tests393 394define void @insert_i32_two_elts_into_different_vectors(<4 x i32> %x, <4 x i32> %y, ptr %s.addr, ptr %x.out.addr, ptr %y.out.addr) {395; SSE2-LABEL: insert_i32_two_elts_into_different_vectors:396; SSE2: # %bb.0:397; SSE2-NEXT: movl (%rdi), %eax398; SSE2-NEXT: movd %eax, %xmm2399; SSE2-NEXT: movss {{.*#+}} xmm0 = xmm2[0],xmm0[1,2,3]400; SSE2-NEXT: movd %eax, %xmm2401; SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]402; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[2,0],xmm1[2,3]403; SSE2-NEXT: movaps %xmm0, (%rsi)404; SSE2-NEXT: movaps %xmm2, (%rdx)405; SSE2-NEXT: retq406;407; SSE41-LABEL: insert_i32_two_elts_into_different_vectors:408; SSE41: # %bb.0:409; SSE41-NEXT: movl (%rdi), %eax410; SSE41-NEXT: pinsrd $0, %eax, %xmm0411; SSE41-NEXT: pinsrd $1, %eax, %xmm1412; SSE41-NEXT: movdqa %xmm0, (%rsi)413; SSE41-NEXT: movdqa %xmm1, (%rdx)414; SSE41-NEXT: retq415;416; AVX-LABEL: insert_i32_two_elts_into_different_vectors:417; AVX: # %bb.0:418; AVX-NEXT: movl (%rdi), %eax419; AVX-NEXT: vpinsrd $0, %eax, %xmm0, %xmm0420; AVX-NEXT: vpinsrd $1, %eax, %xmm1, %xmm1421; AVX-NEXT: vmovdqa %xmm0, (%rsi)422; AVX-NEXT: vmovdqa %xmm1, (%rdx)423; AVX-NEXT: retq424 %s = load i32, ptr %s.addr425 %i0 = insertelement <4 x i32> %x, i32 %s, i32 0426 %i1 = insertelement <4 x i32> %y, i32 %s, i32 1427 store <4 x i32> %i0, ptr %x.out.addr428 store <4 x i32> %i1, ptr %y.out.addr429 ret void430}431 432define <4 x float> @insert_f32_two_elts_extrause_of_scalar(<4 x float> %x, ptr %s.addr, ptr %s.out) {433; SSE-LABEL: insert_f32_two_elts_extrause_of_scalar:434; SSE: # %bb.0:435; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero436; SSE-NEXT: movss %xmm1, (%rsi)437; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,3]438; SSE-NEXT: movaps %xmm1, %xmm0439; SSE-NEXT: retq440;441; AVX-LABEL: insert_f32_two_elts_extrause_of_scalar:442; AVX: # %bb.0:443; AVX-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero444; AVX-NEXT: vmovss %xmm1, (%rsi)445; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,0],xmm0[2,3]446; AVX-NEXT: retq447 %s = load float, ptr %s.addr448 store float %s, ptr %s.out449 %i0 = insertelement <4 x float> %x, float %s, i32 0450 %i1 = insertelement <4 x float> %i0, float %s, i32 1451 ret <4 x float> %i1452}453