261 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ssse3 | FileCheck %s --check-prefixes=SSE,SSE-SLOW3; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ssse3,fast-hops | FileCheck %s --check-prefixes=SSE,SSE-FAST4; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1,AVX1-SLOW5; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx,fast-hops | FileCheck %s --check-prefixes=AVX,AVX1,AVX1-FAST6; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX27; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2,fast-hops | FileCheck %s --check-prefixes=AVX,AVX28; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx512vl | FileCheck %s --check-prefixes=AVX,AVX5129; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx512vl,fast-hops | FileCheck %s --check-prefixes=AVX,AVX51210 11; Verify that we correctly fold horizontal binop even in the presence of UNDEFs.12 13define <8 x i32> @test14_undef(<8 x i32> %a, <8 x i32> %b) {14; SSE-LABEL: test14_undef:15; SSE: # %bb.0:16; SSE-NEXT: phaddd %xmm2, %xmm017; SSE-NEXT: retq18;19; AVX-LABEL: test14_undef:20; AVX: # %bb.0:21; AVX-NEXT: vphaddd %xmm1, %xmm0, %xmm022; AVX-NEXT: retq23 %vecext = extractelement <8 x i32> %a, i32 024 %vecext1 = extractelement <8 x i32> %a, i32 125 %add = add i32 %vecext, %vecext126 %vecinit = insertelement <8 x i32> undef, i32 %add, i32 027 %vecext2 = extractelement <8 x i32> %b, i32 228 %vecext3 = extractelement <8 x i32> %b, i32 329 %add4 = add i32 %vecext2, %vecext330 %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 331 ret <8 x i32> %vecinit532}33 34; integer horizontal adds instead of two scalar adds followed by vector inserts.35define <8 x i32> @test15_undef(<8 x i32> %a, <8 x i32> %b) {36; SSE-SLOW-LABEL: test15_undef:37; SSE-SLOW: # %bb.0:38; SSE-SLOW-NEXT: movd %xmm0, %eax39; SSE-SLOW-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]40; SSE-SLOW-NEXT: movd %xmm0, %ecx41; SSE-SLOW-NEXT: addl %eax, %ecx42; SSE-SLOW-NEXT: movd %xmm3, %eax43; SSE-SLOW-NEXT: pshufd {{.*#+}} xmm0 = xmm3[1,1,1,1]44; SSE-SLOW-NEXT: movd %xmm0, %edx45; SSE-SLOW-NEXT: addl %eax, %edx46; SSE-SLOW-NEXT: movd %ecx, %xmm047; SSE-SLOW-NEXT: movd %edx, %xmm148; SSE-SLOW-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,1,0,1]49; SSE-SLOW-NEXT: retq50;51; SSE-FAST-LABEL: test15_undef:52; SSE-FAST: # %bb.0:53; SSE-FAST-NEXT: movdqa %xmm3, %xmm154; SSE-FAST-NEXT: phaddd %xmm0, %xmm055; SSE-FAST-NEXT: phaddd %xmm3, %xmm156; SSE-FAST-NEXT: retq57;58; AVX1-SLOW-LABEL: test15_undef:59; AVX1-SLOW: # %bb.0:60; AVX1-SLOW-NEXT: vmovd %xmm0, %eax61; AVX1-SLOW-NEXT: vpextrd $1, %xmm0, %ecx62; AVX1-SLOW-NEXT: addl %eax, %ecx63; AVX1-SLOW-NEXT: vextractf128 $1, %ymm1, %xmm064; AVX1-SLOW-NEXT: vmovd %xmm0, %eax65; AVX1-SLOW-NEXT: vpextrd $1, %xmm0, %edx66; AVX1-SLOW-NEXT: addl %eax, %edx67; AVX1-SLOW-NEXT: vmovd %ecx, %xmm068; AVX1-SLOW-NEXT: vmovd %edx, %xmm169; AVX1-SLOW-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[0,1,0,1]70; AVX1-SLOW-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm071; AVX1-SLOW-NEXT: retq72;73; AVX1-FAST-LABEL: test15_undef:74; AVX1-FAST: # %bb.0:75; AVX1-FAST-NEXT: vphaddd %xmm0, %xmm0, %xmm076; AVX1-FAST-NEXT: vextractf128 $1, %ymm1, %xmm177; AVX1-FAST-NEXT: vphaddd %xmm1, %xmm1, %xmm178; AVX1-FAST-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm079; AVX1-FAST-NEXT: retq80;81; AVX2-LABEL: test15_undef:82; AVX2: # %bb.0:83; AVX2-NEXT: vphaddd %ymm1, %ymm0, %ymm084; AVX2-NEXT: retq85;86; AVX512-LABEL: test15_undef:87; AVX512: # %bb.0:88; AVX512-NEXT: vphaddd %ymm1, %ymm0, %ymm089; AVX512-NEXT: retq90 %vecext = extractelement <8 x i32> %a, i32 091 %vecext1 = extractelement <8 x i32> %a, i32 192 %add = add i32 %vecext, %vecext193 %vecinit = insertelement <8 x i32> undef, i32 %add, i32 094 %vecext2 = extractelement <8 x i32> %b, i32 495 %vecext3 = extractelement <8 x i32> %b, i32 596 %add4 = add i32 %vecext2, %vecext397 %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 698 ret <8 x i32> %vecinit599}100 101define <8 x i32> @PR40243_alt(<8 x i32> %a, <8 x i32> %b) {102; SSE-LABEL: PR40243_alt:103; SSE: # %bb.0:104; SSE-NEXT: phaddd %xmm3, %xmm1105; SSE-NEXT: retq106;107; AVX1-LABEL: PR40243_alt:108; AVX1: # %bb.0:109; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1110; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0111; AVX1-NEXT: vphaddd %xmm1, %xmm0, %xmm0112; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0113; AVX1-NEXT: retq114;115; AVX2-LABEL: PR40243_alt:116; AVX2: # %bb.0:117; AVX2-NEXT: vphaddd %ymm1, %ymm0, %ymm0118; AVX2-NEXT: retq119;120; AVX512-LABEL: PR40243_alt:121; AVX512: # %bb.0:122; AVX512-NEXT: vphaddd %ymm1, %ymm0, %ymm0123; AVX512-NEXT: retq124 %a4 = extractelement <8 x i32> %a, i32 4125 %a5 = extractelement <8 x i32> %a, i32 5126 %add4 = add i32 %a4, %a5127 %b6 = extractelement <8 x i32> %b, i32 6128 %b7 = extractelement <8 x i32> %b, i32 7129 %add7 = add i32 %b6, %b7130 %r4 = insertelement <8 x i32> undef, i32 %add4, i32 4131 %r = insertelement <8 x i32> %r4, i32 %add7, i32 7132 ret <8 x i32> %r133}134 135define <8 x i32> @test16_undef(<8 x i32> %a, <8 x i32> %b) {136; SSE-LABEL: test16_undef:137; SSE: # %bb.0:138; SSE-NEXT: phaddd %xmm0, %xmm0139; SSE-NEXT: retq140;141; AVX-LABEL: test16_undef:142; AVX: # %bb.0:143; AVX-NEXT: vphaddd %xmm0, %xmm0, %xmm0144; AVX-NEXT: retq145 %vecext = extractelement <8 x i32> %a, i32 0146 %vecext1 = extractelement <8 x i32> %a, i32 1147 %add = add i32 %vecext, %vecext1148 %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0149 %vecext2 = extractelement <8 x i32> %a, i32 2150 %vecext3 = extractelement <8 x i32> %a, i32 3151 %add4 = add i32 %vecext2, %vecext3152 %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 1153 ret <8 x i32> %vecinit5154}155 156define <16 x i32> @test16_v16i32_undef(<16 x i32> %a, <16 x i32> %b) {157; SSE-LABEL: test16_v16i32_undef:158; SSE: # %bb.0:159; SSE-NEXT: phaddd %xmm0, %xmm0160; SSE-NEXT: retq161;162; AVX-LABEL: test16_v16i32_undef:163; AVX: # %bb.0:164; AVX-NEXT: vphaddd %xmm0, %xmm0, %xmm0165; AVX-NEXT: retq166 %vecext = extractelement <16 x i32> %a, i32 0167 %vecext1 = extractelement <16 x i32> %a, i32 1168 %add = add i32 %vecext, %vecext1169 %vecinit = insertelement <16 x i32> undef, i32 %add, i32 0170 %vecext2 = extractelement <16 x i32> %a, i32 2171 %vecext3 = extractelement <16 x i32> %a, i32 3172 %add4 = add i32 %vecext2, %vecext3173 %vecinit5 = insertelement <16 x i32> %vecinit, i32 %add4, i32 1174 ret <16 x i32> %vecinit5175}176 177define <8 x i32> @test17_undef(<8 x i32> %a, <8 x i32> %b) {178; SSE-LABEL: test17_undef:179; SSE: # %bb.0:180; SSE-NEXT: phaddd %xmm1, %xmm0181; SSE-NEXT: retq182;183; AVX1-LABEL: test17_undef:184; AVX1: # %bb.0:185; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1186; AVX1-NEXT: vphaddd %xmm1, %xmm0, %xmm0187; AVX1-NEXT: retq188;189; AVX2-LABEL: test17_undef:190; AVX2: # %bb.0:191; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1192; AVX2-NEXT: vphaddd %xmm1, %xmm0, %xmm0193; AVX2-NEXT: retq194;195; AVX512-LABEL: test17_undef:196; AVX512: # %bb.0:197; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm1198; AVX512-NEXT: vphaddd %xmm1, %xmm0, %xmm0199; AVX512-NEXT: retq200 %vecext = extractelement <8 x i32> %a, i32 0201 %vecext1 = extractelement <8 x i32> %a, i32 1202 %add1 = add i32 %vecext, %vecext1203 %vecinit1 = insertelement <8 x i32> undef, i32 %add1, i32 0204 %vecext2 = extractelement <8 x i32> %a, i32 2205 %vecext3 = extractelement <8 x i32> %a, i32 3206 %add2 = add i32 %vecext2, %vecext3207 %vecinit2 = insertelement <8 x i32> %vecinit1, i32 %add2, i32 1208 %vecext4 = extractelement <8 x i32> %a, i32 4209 %vecext5 = extractelement <8 x i32> %a, i32 5210 %add3 = add i32 %vecext4, %vecext5211 %vecinit3 = insertelement <8 x i32> %vecinit2, i32 %add3, i32 2212 %vecext6 = extractelement <8 x i32> %a, i32 6213 %vecext7 = extractelement <8 x i32> %a, i32 7214 %add4 = add i32 %vecext6, %vecext7215 %vecinit4 = insertelement <8 x i32> %vecinit3, i32 %add4, i32 3216 ret <8 x i32> %vecinit4217}218 219define <16 x i32> @test17_v16i32_undef(<16 x i32> %a, <16 x i32> %b) {220; SSE-LABEL: test17_v16i32_undef:221; SSE: # %bb.0:222; SSE-NEXT: phaddd %xmm1, %xmm0223; SSE-NEXT: retq224;225; AVX1-LABEL: test17_v16i32_undef:226; AVX1: # %bb.0:227; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1228; AVX1-NEXT: vphaddd %xmm1, %xmm0, %xmm0229; AVX1-NEXT: retq230;231; AVX2-LABEL: test17_v16i32_undef:232; AVX2: # %bb.0:233; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1234; AVX2-NEXT: vphaddd %xmm1, %xmm0, %xmm0235; AVX2-NEXT: retq236;237; AVX512-LABEL: test17_v16i32_undef:238; AVX512: # %bb.0:239; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm1240; AVX512-NEXT: vphaddd %xmm1, %xmm0, %xmm0241; AVX512-NEXT: retq242 %vecext = extractelement <16 x i32> %a, i32 0243 %vecext1 = extractelement <16 x i32> %a, i32 1244 %add1 = add i32 %vecext, %vecext1245 %vecinit1 = insertelement <16 x i32> undef, i32 %add1, i32 0246 %vecext2 = extractelement <16 x i32> %a, i32 2247 %vecext3 = extractelement <16 x i32> %a, i32 3248 %add2 = add i32 %vecext2, %vecext3249 %vecinit2 = insertelement <16 x i32> %vecinit1, i32 %add2, i32 1250 %vecext4 = extractelement <16 x i32> %a, i32 4251 %vecext5 = extractelement <16 x i32> %a, i32 5252 %add3 = add i32 %vecext4, %vecext5253 %vecinit3 = insertelement <16 x i32> %vecinit2, i32 %add3, i32 2254 %vecext6 = extractelement <16 x i32> %a, i32 6255 %vecext7 = extractelement <16 x i32> %a, i32 7256 %add4 = add i32 %vecext6, %vecext7257 %vecinit4 = insertelement <16 x i32> %vecinit3, i32 %add4, i32 3258 ret <16 x i32> %vecinit4259}260 261