300 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; Test ADDSUB ISel patterns.7 8; Functions below are obtained from the following source:9;10; typedef double double2 __attribute__((ext_vector_type(2)));11; typedef double double4 __attribute__((ext_vector_type(4)));12; typedef float float4 __attribute__((ext_vector_type(4)));13; typedef float float8 __attribute__((ext_vector_type(8)));14;15; float4 test1(float4 A, float4 B) {16; float4 X = A - B;17; float4 Y = A + B;18; return (float4){X[0], Y[1], X[2], Y[3]};19; }20;21; float8 test2(float8 A, float8 B) {22; float8 X = A - B;23; float8 Y = A + B;24; return (float8){X[0], Y[1], X[2], Y[3], X[4], Y[5], X[6], Y[7]};25; }26;27; double4 test3(double4 A, double4 B) {28; double4 X = A - B;29; double4 Y = A + B;30; return (double4){X[0], Y[1], X[2], Y[3]};31; }32;33; double2 test4(double2 A, double2 B) {34; double2 X = A - B;35; double2 Y = A + B;36; return (double2){X[0], Y[1]};37; }38 39define <4 x float> @test1(<4 x float> %A, <4 x float> %B) {40; SSE-LABEL: test1:41; SSE: # %bb.0:42; SSE-NEXT: addsubps %xmm1, %xmm043; SSE-NEXT: retq44;45; AVX-LABEL: test1:46; AVX: # %bb.0:47; AVX-NEXT: vaddsubps %xmm1, %xmm0, %xmm048; AVX-NEXT: retq49 %sub = fsub <4 x float> %A, %B50 %add = fadd <4 x float> %A, %B51 %vecinit6 = shufflevector <4 x float> %sub, <4 x float> %add, <4 x i32> <i32 0, i32 5, i32 2, i32 7>52 ret <4 x float> %vecinit653}54 55define <8 x float> @test2(<8 x float> %A, <8 x float> %B) {56; SSE-LABEL: test2:57; SSE: # %bb.0:58; SSE-NEXT: addsubps %xmm2, %xmm059; SSE-NEXT: addsubps %xmm3, %xmm160; SSE-NEXT: retq61;62; AVX-LABEL: test2:63; AVX: # %bb.0:64; AVX-NEXT: vaddsubps %ymm1, %ymm0, %ymm065; AVX-NEXT: retq66 %sub = fsub <8 x float> %A, %B67 %add = fadd <8 x float> %A, %B68 %vecinit14 = shufflevector <8 x float> %sub, <8 x float> %add, <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>69 ret <8 x float> %vecinit1470}71 72define <4 x double> @test3(<4 x double> %A, <4 x double> %B) {73; SSE-LABEL: test3:74; SSE: # %bb.0:75; SSE-NEXT: addsubpd %xmm2, %xmm076; SSE-NEXT: addsubpd %xmm3, %xmm177; SSE-NEXT: retq78;79; AVX-LABEL: test3:80; AVX: # %bb.0:81; AVX-NEXT: vaddsubpd %ymm1, %ymm0, %ymm082; AVX-NEXT: retq83 %sub = fsub <4 x double> %A, %B84 %add = fadd <4 x double> %A, %B85 %vecinit6 = shufflevector <4 x double> %sub, <4 x double> %add, <4 x i32> <i32 0, i32 5, i32 2, i32 7>86 ret <4 x double> %vecinit687}88 89define <2 x double> @test4(<2 x double> %A, <2 x double> %B) #0 {90; SSE-LABEL: test4:91; SSE: # %bb.0:92; SSE-NEXT: addsubpd %xmm1, %xmm093; SSE-NEXT: retq94;95; AVX-LABEL: test4:96; AVX: # %bb.0:97; AVX-NEXT: vaddsubpd %xmm1, %xmm0, %xmm098; AVX-NEXT: retq99 %add = fadd <2 x double> %A, %B100 %sub = fsub <2 x double> %A, %B101 %vecinit2 = shufflevector <2 x double> %sub, <2 x double> %add, <2 x i32> <i32 0, i32 3>102 ret <2 x double> %vecinit2103}104 105define <16 x float> @test5(<16 x float> %A, <16 x float> %B) {106; SSE-LABEL: test5:107; SSE: # %bb.0:108; SSE-NEXT: addsubps %xmm4, %xmm0109; SSE-NEXT: addsubps %xmm5, %xmm1110; SSE-NEXT: addsubps %xmm6, %xmm2111; SSE-NEXT: addsubps %xmm7, %xmm3112; SSE-NEXT: retq113;114; AVX1-LABEL: test5:115; AVX1: # %bb.0:116; AVX1-NEXT: vaddsubps %ymm2, %ymm0, %ymm0117; AVX1-NEXT: vaddsubps %ymm3, %ymm1, %ymm1118; AVX1-NEXT: retq119;120; AVX512-LABEL: test5:121; AVX512: # %bb.0:122; AVX512-NEXT: vsubps %zmm1, %zmm0, %zmm2123; AVX512-NEXT: movw $-21846, %ax # imm = 0xAAAA124; AVX512-NEXT: kmovw %eax, %k1125; AVX512-NEXT: vaddps %zmm1, %zmm0, %zmm2 {%k1}126; AVX512-NEXT: vmovaps %zmm2, %zmm0127; AVX512-NEXT: retq128 %add = fadd <16 x float> %A, %B129 %sub = fsub <16 x float> %A, %B130 %vecinit2 = shufflevector <16 x float> %sub, <16 x float> %add, <16 x i32> <i32 0, i32 17, i32 2, i32 19, i32 4, i32 21, i32 6, i32 23, i32 8, i32 25, i32 10, i32 27, i32 12, i32 29, i32 14, i32 31>131 ret <16 x float> %vecinit2132}133 134define <8 x double> @test6(<8 x double> %A, <8 x double> %B) {135; SSE-LABEL: test6:136; SSE: # %bb.0:137; SSE-NEXT: addsubpd %xmm4, %xmm0138; SSE-NEXT: addsubpd %xmm5, %xmm1139; SSE-NEXT: addsubpd %xmm6, %xmm2140; SSE-NEXT: addsubpd %xmm7, %xmm3141; SSE-NEXT: retq142;143; AVX1-LABEL: test6:144; AVX1: # %bb.0:145; AVX1-NEXT: vaddsubpd %ymm2, %ymm0, %ymm0146; AVX1-NEXT: vaddsubpd %ymm3, %ymm1, %ymm1147; AVX1-NEXT: retq148;149; AVX512-LABEL: test6:150; AVX512: # %bb.0:151; AVX512-NEXT: vaddpd %zmm1, %zmm0, %zmm2152; AVX512-NEXT: vsubpd %zmm1, %zmm0, %zmm0153; AVX512-NEXT: vshufpd {{.*#+}} zmm0 = zmm0[0],zmm2[1],zmm0[2],zmm2[3],zmm0[4],zmm2[5],zmm0[6],zmm2[7]154; AVX512-NEXT: retq155 %add = fadd <8 x double> %A, %B156 %sub = fsub <8 x double> %A, %B157 %vecinit2 = shufflevector <8 x double> %sub, <8 x double> %add, <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>158 ret <8 x double> %vecinit2159}160 161define <4 x float> @test1b(<4 x float> %A, ptr %B) {162; SSE-LABEL: test1b:163; SSE: # %bb.0:164; SSE-NEXT: addsubps (%rdi), %xmm0165; SSE-NEXT: retq166;167; AVX-LABEL: test1b:168; AVX: # %bb.0:169; AVX-NEXT: vaddsubps (%rdi), %xmm0, %xmm0170; AVX-NEXT: retq171 %1 = load <4 x float>, ptr %B172 %add = fadd <4 x float> %A, %1173 %sub = fsub <4 x float> %A, %1174 %vecinit6 = shufflevector <4 x float> %sub, <4 x float> %add, <4 x i32> <i32 0, i32 5, i32 2, i32 7>175 ret <4 x float> %vecinit6176}177 178define <8 x float> @test2b(<8 x float> %A, ptr %B) {179; SSE-LABEL: test2b:180; SSE: # %bb.0:181; SSE-NEXT: addsubps (%rdi), %xmm0182; SSE-NEXT: addsubps 16(%rdi), %xmm1183; SSE-NEXT: retq184;185; AVX-LABEL: test2b:186; AVX: # %bb.0:187; AVX-NEXT: vaddsubps (%rdi), %ymm0, %ymm0188; AVX-NEXT: retq189 %1 = load <8 x float>, ptr %B190 %add = fadd <8 x float> %A, %1191 %sub = fsub <8 x float> %A, %1192 %vecinit14 = shufflevector <8 x float> %sub, <8 x float> %add, <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>193 ret <8 x float> %vecinit14194}195 196define <4 x double> @test3b(<4 x double> %A, ptr %B) {197; SSE-LABEL: test3b:198; SSE: # %bb.0:199; SSE-NEXT: addsubpd (%rdi), %xmm0200; SSE-NEXT: addsubpd 16(%rdi), %xmm1201; SSE-NEXT: retq202;203; AVX-LABEL: test3b:204; AVX: # %bb.0:205; AVX-NEXT: vaddsubpd (%rdi), %ymm0, %ymm0206; AVX-NEXT: retq207 %1 = load <4 x double>, ptr %B208 %add = fadd <4 x double> %A, %1209 %sub = fsub <4 x double> %A, %1210 %vecinit6 = shufflevector <4 x double> %sub, <4 x double> %add, <4 x i32> <i32 0, i32 5, i32 2, i32 7>211 ret <4 x double> %vecinit6212}213 214define <2 x double> @test4b(<2 x double> %A, ptr %B) {215; SSE-LABEL: test4b:216; SSE: # %bb.0:217; SSE-NEXT: addsubpd (%rdi), %xmm0218; SSE-NEXT: retq219;220; AVX-LABEL: test4b:221; AVX: # %bb.0:222; AVX-NEXT: vaddsubpd (%rdi), %xmm0, %xmm0223; AVX-NEXT: retq224 %1 = load <2 x double>, ptr %B225 %sub = fsub <2 x double> %A, %1226 %add = fadd <2 x double> %A, %1227 %vecinit2 = shufflevector <2 x double> %sub, <2 x double> %add, <2 x i32> <i32 0, i32 3>228 ret <2 x double> %vecinit2229}230 231define <4 x float> @test1c(<4 x float> %A, ptr %B) {232; SSE-LABEL: test1c:233; SSE: # %bb.0:234; SSE-NEXT: addsubps (%rdi), %xmm0235; SSE-NEXT: retq236;237; AVX-LABEL: test1c:238; AVX: # %bb.0:239; AVX-NEXT: vaddsubps (%rdi), %xmm0, %xmm0240; AVX-NEXT: retq241 %1 = load <4 x float>, ptr %B242 %add = fadd <4 x float> %A, %1243 %sub = fsub <4 x float> %A, %1244 %vecinit6 = shufflevector <4 x float> %add, <4 x float> %sub, <4 x i32> <i32 4, i32 1, i32 6, i32 3>245 ret <4 x float> %vecinit6246}247 248define <8 x float> @test2c(<8 x float> %A, ptr %B) {249; SSE-LABEL: test2c:250; SSE: # %bb.0:251; SSE-NEXT: addsubps (%rdi), %xmm0252; SSE-NEXT: addsubps 16(%rdi), %xmm1253; SSE-NEXT: retq254;255; AVX-LABEL: test2c:256; AVX: # %bb.0:257; AVX-NEXT: vaddsubps (%rdi), %ymm0, %ymm0258; AVX-NEXT: retq259 %1 = load <8 x float>, ptr %B260 %add = fadd <8 x float> %A, %1261 %sub = fsub <8 x float> %A, %1262 %vecinit14 = shufflevector <8 x float> %add, <8 x float> %sub, <8 x i32> <i32 8, i32 1, i32 10, i32 3, i32 12, i32 5, i32 14, i32 7>263 ret <8 x float> %vecinit14264}265 266define <4 x double> @test3c(<4 x double> %A, ptr %B) {267; SSE-LABEL: test3c:268; SSE: # %bb.0:269; SSE-NEXT: addsubpd (%rdi), %xmm0270; SSE-NEXT: addsubpd 16(%rdi), %xmm1271; SSE-NEXT: retq272;273; AVX-LABEL: test3c:274; AVX: # %bb.0:275; AVX-NEXT: vaddsubpd (%rdi), %ymm0, %ymm0276; AVX-NEXT: retq277 %1 = load <4 x double>, ptr %B278 %add = fadd <4 x double> %A, %1279 %sub = fsub <4 x double> %A, %1280 %vecinit6 = shufflevector <4 x double> %add, <4 x double> %sub, <4 x i32> <i32 4, i32 1, i32 6, i32 3>281 ret <4 x double> %vecinit6282}283 284define <2 x double> @test4c(<2 x double> %A, ptr %B) {285; SSE-LABEL: test4c:286; SSE: # %bb.0:287; SSE-NEXT: addsubpd (%rdi), %xmm0288; SSE-NEXT: retq289;290; AVX-LABEL: test4c:291; AVX: # %bb.0:292; AVX-NEXT: vaddsubpd (%rdi), %xmm0, %xmm0293; AVX-NEXT: retq294 %1 = load <2 x double>, ptr %B295 %sub = fsub <2 x double> %A, %1296 %add = fadd <2 x double> %A, %1297 %vecinit2 = shufflevector <2 x double> %add, <2 x double> %sub, <2 x i32> <i32 2, i32 1>298 ret <2 x double> %vecinit2299}300