662 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+sse3 | FileCheck %s --check-prefix=SSE3; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX14; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx512f | FileCheck %s --check-prefix=AVX --check-prefix=AVX5125 6; Verify that we correctly generate 'addsub' instructions from7; a sequence of vector extracts + float add/sub + vector inserts.8 9define <4 x float> @test1(<4 x float> %A, <4 x float> %B) {10; SSE-LABEL: test1:11; SSE: # %bb.0:12; SSE-NEXT: addsubps %xmm1, %xmm013; SSE-NEXT: retq14;15; AVX-LABEL: test1:16; AVX: # %bb.0:17; AVX-NEXT: vaddsubps %xmm1, %xmm0, %xmm018; AVX-NEXT: retq19 %1 = extractelement <4 x float> %A, i32 020 %2 = extractelement <4 x float> %B, i32 021 %sub = fsub float %1, %222 %3 = extractelement <4 x float> %A, i32 223 %4 = extractelement <4 x float> %B, i32 224 %sub2 = fsub float %3, %425 %5 = extractelement <4 x float> %A, i32 126 %6 = extractelement <4 x float> %B, i32 127 %add = fadd float %5, %628 %7 = extractelement <4 x float> %A, i32 329 %8 = extractelement <4 x float> %B, i32 330 %add2 = fadd float %7, %831 %vecinsert1 = insertelement <4 x float> undef, float %add, i32 132 %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 333 %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 034 %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 235 ret <4 x float> %vecinsert436}37 38define <4 x float> @test2(<4 x float> %A, <4 x float> %B) {39; SSE-LABEL: test2:40; SSE: # %bb.0:41; SSE-NEXT: addsubps %xmm1, %xmm042; SSE-NEXT: retq43;44; AVX-LABEL: test2:45; AVX: # %bb.0:46; AVX-NEXT: vaddsubps %xmm1, %xmm0, %xmm047; AVX-NEXT: retq48 %1 = extractelement <4 x float> %A, i32 249 %2 = extractelement <4 x float> %B, i32 250 %sub2 = fsub float %1, %251 %3 = extractelement <4 x float> %A, i32 352 %4 = extractelement <4 x float> %B, i32 353 %add2 = fadd float %3, %454 %vecinsert1 = insertelement <4 x float> undef, float %sub2, i32 255 %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 356 ret <4 x float> %vecinsert257}58 59define <4 x float> @test3(<4 x float> %A, <4 x float> %B) {60; SSE-LABEL: test3:61; SSE: # %bb.0:62; SSE-NEXT: addsubps %xmm1, %xmm063; SSE-NEXT: retq64;65; AVX-LABEL: test3:66; AVX: # %bb.0:67; AVX-NEXT: vaddsubps %xmm1, %xmm0, %xmm068; AVX-NEXT: retq69 %1 = extractelement <4 x float> %A, i32 070 %2 = extractelement <4 x float> %B, i32 071 %sub = fsub float %1, %272 %3 = extractelement <4 x float> %A, i32 373 %4 = extractelement <4 x float> %B, i32 374 %add = fadd float %4, %375 %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 076 %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 377 ret <4 x float> %vecinsert278}79 80define <4 x float> @test4(<4 x float> %A, <4 x float> %B) {81; SSE-LABEL: test4:82; SSE: # %bb.0:83; SSE-NEXT: addsubps %xmm1, %xmm084; SSE-NEXT: retq85;86; AVX-LABEL: test4:87; AVX: # %bb.0:88; AVX-NEXT: vaddsubps %xmm1, %xmm0, %xmm089; AVX-NEXT: retq90 %1 = extractelement <4 x float> %A, i32 291 %2 = extractelement <4 x float> %B, i32 292 %sub = fsub float %1, %293 %3 = extractelement <4 x float> %A, i32 194 %4 = extractelement <4 x float> %B, i32 195 %add = fadd float %3, %496 %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 297 %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 198 ret <4 x float> %vecinsert299}100 101define <4 x float> @test5(<4 x float> %A, <4 x float> %B) {102; SSE-LABEL: test5:103; SSE: # %bb.0:104; SSE-NEXT: addsubps %xmm1, %xmm0105; SSE-NEXT: retq106;107; AVX-LABEL: test5:108; AVX: # %bb.0:109; AVX-NEXT: vaddsubps %xmm1, %xmm0, %xmm0110; AVX-NEXT: retq111 %1 = extractelement <4 x float> %A, i32 0112 %2 = extractelement <4 x float> %B, i32 0113 %sub2 = fsub float %1, %2114 %3 = extractelement <4 x float> %A, i32 1115 %4 = extractelement <4 x float> %B, i32 1116 %add2 = fadd float %3, %4117 %vecinsert1 = insertelement <4 x float> undef, float %sub2, i32 0118 %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 1119 ret <4 x float> %vecinsert2120}121 122define <4 x float> @test6(<4 x float> %A, <4 x float> %B) {123; SSE-LABEL: test6:124; SSE: # %bb.0:125; SSE-NEXT: addsubps %xmm1, %xmm0126; SSE-NEXT: retq127;128; AVX-LABEL: test6:129; AVX: # %bb.0:130; AVX-NEXT: vaddsubps %xmm1, %xmm0, %xmm0131; AVX-NEXT: retq132 %1 = extractelement <4 x float> %A, i32 0133 %2 = extractelement <4 x float> %B, i32 0134 %sub = fsub float %1, %2135 %3 = extractelement <4 x float> %A, i32 2136 %4 = extractelement <4 x float> %B, i32 2137 %sub2 = fsub float %3, %4138 %5 = extractelement <4 x float> %A, i32 1139 %6 = extractelement <4 x float> %B, i32 1140 %add = fadd float %5, %6141 %7 = extractelement <4 x float> %A, i32 3142 %8 = extractelement <4 x float> %B, i32 3143 %add2 = fadd float %7, %8144 %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1145 %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3146 %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0147 %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2148 ret <4 x float> %vecinsert4149}150 151define <4 x double> @test7(<4 x double> %A, <4 x double> %B) {152; SSE-LABEL: test7:153; SSE: # %bb.0:154; SSE-NEXT: addsubpd %xmm2, %xmm0155; SSE-NEXT: addsubpd %xmm3, %xmm1156; SSE-NEXT: retq157;158; AVX-LABEL: test7:159; AVX: # %bb.0:160; AVX-NEXT: vaddsubpd %ymm1, %ymm0, %ymm0161; AVX-NEXT: retq162 %1 = extractelement <4 x double> %A, i32 0163 %2 = extractelement <4 x double> %B, i32 0164 %sub = fsub double %1, %2165 %3 = extractelement <4 x double> %A, i32 2166 %4 = extractelement <4 x double> %B, i32 2167 %sub2 = fsub double %3, %4168 %5 = extractelement <4 x double> %A, i32 1169 %6 = extractelement <4 x double> %B, i32 1170 %add = fadd double %5, %6171 %7 = extractelement <4 x double> %A, i32 3172 %8 = extractelement <4 x double> %B, i32 3173 %add2 = fadd double %7, %8174 %vecinsert1 = insertelement <4 x double> undef, double %add, i32 1175 %vecinsert2 = insertelement <4 x double> %vecinsert1, double %add2, i32 3176 %vecinsert3 = insertelement <4 x double> %vecinsert2, double %sub, i32 0177 %vecinsert4 = insertelement <4 x double> %vecinsert3, double %sub2, i32 2178 ret <4 x double> %vecinsert4179}180 181define <2 x double> @test8(<2 x double> %A, <2 x double> %B) {182; SSE-LABEL: test8:183; SSE: # %bb.0:184; SSE-NEXT: addsubpd %xmm1, %xmm0185; SSE-NEXT: retq186;187; AVX-LABEL: test8:188; AVX: # %bb.0:189; AVX-NEXT: vaddsubpd %xmm1, %xmm0, %xmm0190; AVX-NEXT: retq191 %1 = extractelement <2 x double> %A, i32 0192 %2 = extractelement <2 x double> %B, i32 0193 %sub = fsub double %1, %2194 %3 = extractelement <2 x double> %A, i32 1195 %4 = extractelement <2 x double> %B, i32 1196 %add = fadd double %3, %4197 %vecinsert1 = insertelement <2 x double> undef, double %sub, i32 0198 %vecinsert2 = insertelement <2 x double> %vecinsert1, double %add, i32 1199 ret <2 x double> %vecinsert2200}201 202define <8 x float> @test9(<8 x float> %A, <8 x float> %B) {203; SSE-LABEL: test9:204; SSE: # %bb.0:205; SSE-NEXT: addsubps %xmm2, %xmm0206; SSE-NEXT: addsubps %xmm3, %xmm1207; SSE-NEXT: retq208;209; AVX-LABEL: test9:210; AVX: # %bb.0:211; AVX-NEXT: vaddsubps %ymm1, %ymm0, %ymm0212; AVX-NEXT: retq213 %1 = extractelement <8 x float> %A, i32 0214 %2 = extractelement <8 x float> %B, i32 0215 %sub = fsub float %1, %2216 %3 = extractelement <8 x float> %A, i32 2217 %4 = extractelement <8 x float> %B, i32 2218 %sub2 = fsub float %3, %4219 %5 = extractelement <8 x float> %A, i32 1220 %6 = extractelement <8 x float> %B, i32 1221 %add = fadd float %5, %6222 %7 = extractelement <8 x float> %A, i32 3223 %8 = extractelement <8 x float> %B, i32 3224 %add2 = fadd float %7, %8225 %9 = extractelement <8 x float> %A, i32 4226 %10 = extractelement <8 x float> %B, i32 4227 %sub3 = fsub float %9, %10228 %11 = extractelement <8 x float> %A, i32 6229 %12 = extractelement <8 x float> %B, i32 6230 %sub4 = fsub float %11, %12231 %13 = extractelement <8 x float> %A, i32 5232 %14 = extractelement <8 x float> %B, i32 5233 %add3 = fadd float %13, %14234 %15 = extractelement <8 x float> %A, i32 7235 %16 = extractelement <8 x float> %B, i32 7236 %add4 = fadd float %15, %16237 %vecinsert1 = insertelement <8 x float> undef, float %add, i32 1238 %vecinsert2 = insertelement <8 x float> %vecinsert1, float %add2, i32 3239 %vecinsert3 = insertelement <8 x float> %vecinsert2, float %sub, i32 0240 %vecinsert4 = insertelement <8 x float> %vecinsert3, float %sub2, i32 2241 %vecinsert5 = insertelement <8 x float> %vecinsert4, float %add3, i32 5242 %vecinsert6 = insertelement <8 x float> %vecinsert5, float %add4, i32 7243 %vecinsert7 = insertelement <8 x float> %vecinsert6, float %sub3, i32 4244 %vecinsert8 = insertelement <8 x float> %vecinsert7, float %sub4, i32 6245 ret <8 x float> %vecinsert8246}247 248; Verify that we don't generate addsub instruction for the following249; functions.250 251define <4 x float> @test10(<4 x float> %A, <4 x float> %B) {252; SSE-LABEL: test10:253; SSE: # %bb.0:254; SSE-NEXT: subss %xmm1, %xmm0255; SSE-NEXT: retq256;257; AVX-LABEL: test10:258; AVX: # %bb.0:259; AVX-NEXT: vsubss %xmm1, %xmm0, %xmm0260; AVX-NEXT: retq261 %1 = extractelement <4 x float> %A, i32 0262 %2 = extractelement <4 x float> %B, i32 0263 %sub = fsub float %1, %2264 %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 0265 ret <4 x float> %vecinsert1266}267 268define <4 x float> @test11(<4 x float> %A, <4 x float> %B) {269; SSE-LABEL: test11:270; SSE: # %bb.0:271; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1]272; SSE-NEXT: movhlps {{.*#+}} xmm1 = xmm1[1,1]273; SSE-NEXT: subss %xmm1, %xmm0274; SSE-NEXT: movddup {{.*#+}} xmm0 = xmm0[0,0]275; SSE-NEXT: retq276;277; AVX1-LABEL: test11:278; AVX1: # %bb.0:279; AVX1-NEXT: vshufpd {{.*#+}} xmm0 = xmm0[1,0]280; AVX1-NEXT: vshufpd {{.*#+}} xmm1 = xmm1[1,0]281; AVX1-NEXT: vsubss %xmm1, %xmm0, %xmm0282; AVX1-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0]283; AVX1-NEXT: retq284;285; AVX512-LABEL: test11:286; AVX512: # %bb.0:287; AVX512-NEXT: vshufpd {{.*#+}} xmm0 = xmm0[1,0]288; AVX512-NEXT: vshufpd {{.*#+}} xmm1 = xmm1[1,0]289; AVX512-NEXT: vsubss %xmm1, %xmm0, %xmm0290; AVX512-NEXT: vbroadcastss %xmm0, %xmm0291; AVX512-NEXT: retq292 %1 = extractelement <4 x float> %A, i32 2293 %2 = extractelement <4 x float> %B, i32 2294 %sub = fsub float %1, %2295 %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 2296 ret <4 x float> %vecinsert1297}298 299define <4 x float> @test12(<4 x float> %A, <4 x float> %B) {300; SSE-LABEL: test12:301; SSE: # %bb.0:302; SSE-NEXT: movshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]303; SSE-NEXT: movshdup {{.*#+}} xmm1 = xmm1[1,1,3,3]304; SSE-NEXT: addss %xmm0, %xmm1305; SSE-NEXT: movsldup {{.*#+}} xmm0 = xmm1[0,0,2,2]306; SSE-NEXT: retq307;308; AVX1-LABEL: test12:309; AVX1: # %bb.0:310; AVX1-NEXT: vmovshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]311; AVX1-NEXT: vmovshdup {{.*#+}} xmm1 = xmm1[1,1,3,3]312; AVX1-NEXT: vaddss %xmm1, %xmm0, %xmm0313; AVX1-NEXT: vmovsldup {{.*#+}} xmm0 = xmm0[0,0,2,2]314; AVX1-NEXT: retq315;316; AVX512-LABEL: test12:317; AVX512: # %bb.0:318; AVX512-NEXT: vmovshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]319; AVX512-NEXT: vmovshdup {{.*#+}} xmm1 = xmm1[1,1,3,3]320; AVX512-NEXT: vaddss %xmm1, %xmm0, %xmm0321; AVX512-NEXT: vbroadcastss %xmm0, %xmm0322; AVX512-NEXT: retq323 %1 = extractelement <4 x float> %A, i32 1324 %2 = extractelement <4 x float> %B, i32 1325 %add = fadd float %1, %2326 %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1327 ret <4 x float> %vecinsert1328}329 330define <4 x float> @test13(<4 x float> %A, <4 x float> %B) {331; SSE-LABEL: test13:332; SSE: # %bb.0:333; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]334; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[3,3,3,3]335; SSE-NEXT: addss %xmm1, %xmm0336; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,0,0,0]337; SSE-NEXT: retq338;339; AVX1-LABEL: test13:340; AVX1: # %bb.0:341; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]342; AVX1-NEXT: vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]343; AVX1-NEXT: vaddss %xmm1, %xmm0, %xmm0344; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,0,0,0]345; AVX1-NEXT: retq346;347; AVX512-LABEL: test13:348; AVX512: # %bb.0:349; AVX512-NEXT: vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]350; AVX512-NEXT: vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]351; AVX512-NEXT: vaddss %xmm1, %xmm0, %xmm0352; AVX512-NEXT: vbroadcastss %xmm0, %xmm0353; AVX512-NEXT: retq354 %1 = extractelement <4 x float> %A, i32 3355 %2 = extractelement <4 x float> %B, i32 3356 %add = fadd float %1, %2357 %vecinsert1 = insertelement <4 x float> undef, float %add, i32 3358 ret <4 x float> %vecinsert1359}360 361define <4 x float> @test14(<4 x float> %A, <4 x float> %B) {362; SSE-LABEL: test14:363; SSE: # %bb.0:364; SSE-NEXT: movaps %xmm0, %xmm2365; SSE-NEXT: subss %xmm1, %xmm2366; SSE-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1]367; SSE-NEXT: movhlps {{.*#+}} xmm1 = xmm1[1,1]368; SSE-NEXT: subss %xmm1, %xmm0369; SSE-NEXT: movlhps {{.*#+}} xmm2 = xmm2[0],xmm0[0]370; SSE-NEXT: movaps %xmm2, %xmm0371; SSE-NEXT: retq372;373; AVX-LABEL: test14:374; AVX: # %bb.0:375; AVX-NEXT: vsubss %xmm1, %xmm0, %xmm2376; AVX-NEXT: vshufpd {{.*#+}} xmm0 = xmm0[1,0]377; AVX-NEXT: vshufpd {{.*#+}} xmm1 = xmm1[1,0]378; AVX-NEXT: vsubss %xmm1, %xmm0, %xmm0379; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm2[0,1],xmm0[0],xmm2[3]380; AVX-NEXT: retq381 %1 = extractelement <4 x float> %A, i32 0382 %2 = extractelement <4 x float> %B, i32 0383 %sub = fsub float %1, %2384 %3 = extractelement <4 x float> %A, i32 2385 %4 = extractelement <4 x float> %B, i32 2386 %sub2 = fsub float %3, %4387 %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 0388 %vecinsert2 = insertelement <4 x float> %vecinsert1, float %sub2, i32 2389 ret <4 x float> %vecinsert2390}391 392define <4 x float> @test15(<4 x float> %A, <4 x float> %B) {393; SSE-LABEL: test15:394; SSE: # %bb.0:395; SSE-NEXT: movshdup {{.*#+}} xmm3 = xmm0[1,1,3,3]396; SSE-NEXT: movshdup {{.*#+}} xmm2 = xmm1[1,1,3,3]397; SSE-NEXT: addss %xmm3, %xmm2398; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]399; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[3,3,3,3]400; SSE-NEXT: addss %xmm0, %xmm1401; SSE-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,0],xmm1[0,0]402; SSE-NEXT: movaps %xmm2, %xmm0403; SSE-NEXT: retq404;405; AVX1-LABEL: test15:406; AVX1: # %bb.0:407; AVX1-NEXT: vmovshdup {{.*#+}} xmm2 = xmm0[1,1,3,3]408; AVX1-NEXT: vmovshdup {{.*#+}} xmm3 = xmm1[1,1,3,3]409; AVX1-NEXT: vaddss %xmm3, %xmm2, %xmm2410; AVX1-NEXT: vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]411; AVX1-NEXT: vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]412; AVX1-NEXT: vaddss %xmm1, %xmm0, %xmm0413; AVX1-NEXT: vmovsldup {{.*#+}} xmm1 = xmm2[0,0,2,2]414; AVX1-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0]415; AVX1-NEXT: retq416;417; AVX512-LABEL: test15:418; AVX512: # %bb.0:419; AVX512-NEXT: vmovshdup {{.*#+}} xmm2 = xmm0[1,1,3,3]420; AVX512-NEXT: vmovshdup {{.*#+}} xmm3 = xmm1[1,1,3,3]421; AVX512-NEXT: vaddss %xmm3, %xmm2, %xmm2422; AVX512-NEXT: vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]423; AVX512-NEXT: vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]424; AVX512-NEXT: vaddss %xmm1, %xmm0, %xmm0425; AVX512-NEXT: vbroadcastss %xmm2, %xmm1426; AVX512-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0]427; AVX512-NEXT: retq428 %1 = extractelement <4 x float> %A, i32 1429 %2 = extractelement <4 x float> %B, i32 1430 %add = fadd float %1, %2431 %3 = extractelement <4 x float> %A, i32 3432 %4 = extractelement <4 x float> %B, i32 3433 %add2 = fadd float %3, %4434 %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1435 %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3436 ret <4 x float> %vecinsert2437}438 439define <4 x float> @test16(<4 x float> %A, <4 x float> %B) {440; SSE-LABEL: test16:441; SSE: # %bb.0:442; SSE-NEXT: movss {{.*#+}} xmm3 = [4.2E+1,0.0E+0,0.0E+0,0.0E+0]443; SSE-NEXT: movaps %xmm0, %xmm2444; SSE-NEXT: subss %xmm3, %xmm2445; SSE-NEXT: movaps %xmm0, %xmm4446; SSE-NEXT: unpckhpd {{.*#+}} xmm4 = xmm4[1],xmm0[1]447; SSE-NEXT: movaps %xmm1, %xmm5448; SSE-NEXT: unpckhpd {{.*#+}} xmm5 = xmm5[1],xmm1[1]449; SSE-NEXT: subss %xmm5, %xmm4450; SSE-NEXT: movshdup {{.*#+}} xmm5 = xmm0[1,1,3,3]451; SSE-NEXT: addss %xmm3, %xmm5452; SSE-NEXT: unpcklps {{.*#+}} xmm2 = xmm2[0],xmm5[0],xmm2[1],xmm5[1]453; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]454; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[3,3,3,3]455; SSE-NEXT: addss %xmm0, %xmm1456; SSE-NEXT: unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]457; SSE-NEXT: movlhps {{.*#+}} xmm2 = xmm2[0],xmm4[0]458; SSE-NEXT: movaps %xmm2, %xmm0459; SSE-NEXT: retq460;461; AVX-LABEL: test16:462; AVX: # %bb.0:463; AVX-NEXT: vmovss {{.*#+}} xmm2 = [4.2E+1,0.0E+0,0.0E+0,0.0E+0]464; AVX-NEXT: vsubss %xmm2, %xmm0, %xmm3465; AVX-NEXT: vshufpd {{.*#+}} xmm4 = xmm0[1,0]466; AVX-NEXT: vshufpd {{.*#+}} xmm5 = xmm1[1,0]467; AVX-NEXT: vsubss %xmm5, %xmm4, %xmm4468; AVX-NEXT: vmovshdup {{.*#+}} xmm5 = xmm0[1,1,3,3]469; AVX-NEXT: vaddss %xmm2, %xmm5, %xmm2470; AVX-NEXT: vinsertps {{.*#+}} xmm2 = xmm3[0],xmm2[0],xmm3[2,3]471; AVX-NEXT: vinsertps {{.*#+}} xmm2 = xmm2[0,1],xmm4[0],xmm2[3]472; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]473; AVX-NEXT: vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]474; AVX-NEXT: vaddss %xmm1, %xmm0, %xmm0475; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[0]476; AVX-NEXT: retq477 %1 = extractelement <4 x float> %A, i32 0478 %2 = extractelement <4 x float> %B, i32 0479 %sub = fsub float %1, 42.0480 %3 = extractelement <4 x float> %A, i32 2481 %4 = extractelement <4 x float> %B, i32 2482 %sub2 = fsub float %3, %4483 %5 = extractelement <4 x float> %A, i32 1484 %6 = extractelement <4 x float> %B, i32 1485 %add = fadd float %5, 42.0486 %7 = extractelement <4 x float> %A, i32 3487 %8 = extractelement <4 x float> %B, i32 3488 %add2 = fadd float %7, %8489 %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1490 %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3491 %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0492 %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2493 ret <4 x float> %vecinsert4494}495 496define <2 x float> @test_v2f32(<2 x float> %v0, <2 x float> %v1) {497; SSE-LABEL: test_v2f32:498; SSE: # %bb.0:499; SSE-NEXT: addsubps %xmm1, %xmm0500; SSE-NEXT: retq501;502; AVX-LABEL: test_v2f32:503; AVX: # %bb.0:504; AVX-NEXT: vaddsubps %xmm1, %xmm0, %xmm0505; AVX-NEXT: retq506 %v2 = extractelement <2 x float> %v0, i32 0507 %v3 = extractelement <2 x float> %v1, i32 0508 %v4 = extractelement <2 x float> %v0, i32 1509 %v5 = extractelement <2 x float> %v1, i32 1510 %sub = fsub float %v2, %v3511 %add = fadd float %v5, %v4512 %res0 = insertelement <2 x float> undef, float %sub, i32 0513 %res1 = insertelement <2 x float> %res0, float %add, i32 1514 ret <2 x float> %res1515}516 517define <16 x float> @test17(<16 x float> %A, <16 x float> %B) {518; SSE-LABEL: test17:519; SSE: # %bb.0:520; SSE-NEXT: addsubps %xmm4, %xmm0521; SSE-NEXT: addsubps %xmm5, %xmm1522; SSE-NEXT: addsubps %xmm6, %xmm2523; SSE-NEXT: addsubps %xmm7, %xmm3524; SSE-NEXT: retq525;526; AVX1-LABEL: test17:527; AVX1: # %bb.0:528; AVX1-NEXT: vaddsubps %ymm2, %ymm0, %ymm0529; AVX1-NEXT: vaddsubps %ymm3, %ymm1, %ymm1530; AVX1-NEXT: retq531;532; AVX512-LABEL: test17:533; AVX512: # %bb.0:534; AVX512-NEXT: vsubps %zmm1, %zmm0, %zmm2535; AVX512-NEXT: movw $-21846, %ax # imm = 0xAAAA536; AVX512-NEXT: kmovw %eax, %k1537; AVX512-NEXT: vaddps %zmm1, %zmm0, %zmm2 {%k1}538; AVX512-NEXT: vmovaps %zmm2, %zmm0539; AVX512-NEXT: retq540 %1 = extractelement <16 x float> %A, i32 0541 %2 = extractelement <16 x float> %B, i32 0542 %sub = fsub float %1, %2543 %3 = extractelement <16 x float> %A, i32 2544 %4 = extractelement <16 x float> %B, i32 2545 %sub2 = fsub float %3, %4546 %5 = extractelement <16 x float> %A, i32 1547 %6 = extractelement <16 x float> %B, i32 1548 %add = fadd float %5, %6549 %7 = extractelement <16 x float> %A, i32 3550 %8 = extractelement <16 x float> %B, i32 3551 %add2 = fadd float %7, %8552 %9 = extractelement <16 x float> %A, i32 4553 %10 = extractelement <16 x float> %B, i32 4554 %sub3 = fsub float %9, %10555 %11 = extractelement <16 x float> %A, i32 6556 %12 = extractelement <16 x float> %B, i32 6557 %sub4 = fsub float %11, %12558 %13 = extractelement <16 x float> %A, i32 5559 %14 = extractelement <16 x float> %B, i32 5560 %add3 = fadd float %13, %14561 %15 = extractelement <16 x float> %A, i32 7562 %16 = extractelement <16 x float> %B, i32 7563 %add4 = fadd float %15, %16564 %17 = extractelement <16 x float> %A, i32 8565 %18 = extractelement <16 x float> %B, i32 8566 %sub5 = fsub float %17, %18567 %19 = extractelement <16 x float> %A, i32 10568 %20 = extractelement <16 x float> %B, i32 10569 %sub6 = fsub float %19, %20570 %21 = extractelement <16 x float> %A, i32 9571 %22 = extractelement <16 x float> %B, i32 9572 %add5 = fadd float %21, %22573 %23 = extractelement <16 x float> %A, i32 11574 %24 = extractelement <16 x float> %B, i32 11575 %add6 = fadd float %23, %24576 %25 = extractelement <16 x float> %A, i32 12577 %26 = extractelement <16 x float> %B, i32 12578 %sub7 = fsub float %25, %26579 %27 = extractelement <16 x float> %A, i32 14580 %28 = extractelement <16 x float> %B, i32 14581 %sub8 = fsub float %27, %28582 %29 = extractelement <16 x float> %A, i32 13583 %30 = extractelement <16 x float> %B, i32 13584 %add7 = fadd float %29, %30585 %31 = extractelement <16 x float> %A, i32 15586 %32 = extractelement <16 x float> %B, i32 15587 %add8 = fadd float %31, %32588 %vecinsert1 = insertelement <16 x float> undef, float %add, i32 1589 %vecinsert2 = insertelement <16 x float> %vecinsert1, float %add2, i32 3590 %vecinsert3 = insertelement <16 x float> %vecinsert2, float %sub, i32 0591 %vecinsert4 = insertelement <16 x float> %vecinsert3, float %sub2, i32 2592 %vecinsert5 = insertelement <16 x float> %vecinsert4, float %add3, i32 5593 %vecinsert6 = insertelement <16 x float> %vecinsert5, float %add4, i32 7594 %vecinsert7 = insertelement <16 x float> %vecinsert6, float %sub3, i32 4595 %vecinsert8 = insertelement <16 x float> %vecinsert7, float %sub4, i32 6596 %vecinsert9 = insertelement <16 x float> %vecinsert8, float %add5, i32 9597 %vecinsert10 = insertelement <16 x float> %vecinsert9, float %add6, i32 11598 %vecinsert11 = insertelement <16 x float> %vecinsert10, float %sub5, i32 8599 %vecinsert12 = insertelement <16 x float> %vecinsert11, float %sub6, i32 10600 %vecinsert13 = insertelement <16 x float> %vecinsert12, float %add7, i32 13601 %vecinsert14 = insertelement <16 x float> %vecinsert13, float %add8, i32 15602 %vecinsert15 = insertelement <16 x float> %vecinsert14, float %sub7, i32 12603 %vecinsert16 = insertelement <16 x float> %vecinsert15, float %sub8, i32 14604 ret <16 x float> %vecinsert16605}606 607define <8 x double> @test18(<8 x double> %A, <8 x double> %B) {608; SSE-LABEL: test18:609; SSE: # %bb.0:610; SSE-NEXT: addsubpd %xmm4, %xmm0611; SSE-NEXT: addsubpd %xmm5, %xmm1612; SSE-NEXT: addsubpd %xmm6, %xmm2613; SSE-NEXT: addsubpd %xmm7, %xmm3614; SSE-NEXT: retq615;616; AVX1-LABEL: test18:617; AVX1: # %bb.0:618; AVX1-NEXT: vaddsubpd %ymm2, %ymm0, %ymm0619; AVX1-NEXT: vaddsubpd %ymm3, %ymm1, %ymm1620; AVX1-NEXT: retq621;622; AVX512-LABEL: test18:623; AVX512: # %bb.0:624; AVX512-NEXT: vaddpd %zmm1, %zmm0, %zmm2625; AVX512-NEXT: vsubpd %zmm1, %zmm0, %zmm0626; AVX512-NEXT: vshufpd {{.*#+}} zmm0 = zmm0[0],zmm2[1],zmm0[2],zmm2[3],zmm0[4],zmm2[5],zmm0[6],zmm2[7]627; AVX512-NEXT: retq628 %1 = extractelement <8 x double> %A, i32 0629 %2 = extractelement <8 x double> %B, i32 0630 %sub = fsub double %1, %2631 %3 = extractelement <8 x double> %A, i32 2632 %4 = extractelement <8 x double> %B, i32 2633 %sub2 = fsub double %3, %4634 %5 = extractelement <8 x double> %A, i32 1635 %6 = extractelement <8 x double> %B, i32 1636 %add = fadd double %5, %6637 %7 = extractelement <8 x double> %A, i32 3638 %8 = extractelement <8 x double> %B, i32 3639 %add2 = fadd double %7, %8640 %9 = extractelement <8 x double> %A, i32 4641 %10 = extractelement <8 x double> %B, i32 4642 %sub3 = fsub double %9, %10643 %11 = extractelement <8 x double> %A, i32 6644 %12 = extractelement <8 x double> %B, i32 6645 %sub4 = fsub double %11, %12646 %13 = extractelement <8 x double> %A, i32 5647 %14 = extractelement <8 x double> %B, i32 5648 %add3 = fadd double %13, %14649 %15 = extractelement <8 x double> %A, i32 7650 %16 = extractelement <8 x double> %B, i32 7651 %add4 = fadd double %15, %16652 %vecinsert1 = insertelement <8 x double> undef, double %add, i32 1653 %vecinsert2 = insertelement <8 x double> %vecinsert1, double %add2, i32 3654 %vecinsert3 = insertelement <8 x double> %vecinsert2, double %sub, i32 0655 %vecinsert4 = insertelement <8 x double> %vecinsert3, double %sub2, i32 2656 %vecinsert5 = insertelement <8 x double> %vecinsert4, double %add3, i32 5657 %vecinsert6 = insertelement <8 x double> %vecinsert5, double %add4, i32 7658 %vecinsert7 = insertelement <8 x double> %vecinsert6, double %sub3, i32 4659 %vecinsert8 = insertelement <8 x double> %vecinsert7, double %sub4, i32 6660 ret <8 x double> %vecinsert8661}662