356 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -global-isel -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5; Same as vecreduce-fadd-legalization.ll, but without fmf.6 7declare half @llvm.vector.reduce.fadd.f16.v1f16(half, <1 x half>)8declare float @llvm.vector.reduce.fadd.f32.v1f32(float, <1 x float>)9declare double @llvm.vector.reduce.fadd.f64.v1f64(double, <1 x double>)10declare fp128 @llvm.vector.reduce.fadd.f128.v1f128(fp128, <1 x fp128>)11 12declare float @llvm.vector.reduce.fadd.f32.v3f32(float, <3 x float>)13declare float @llvm.vector.reduce.fadd.f32.v5f32(float, <5 x float>)14declare fp128 @llvm.vector.reduce.fadd.f128.v2f128(fp128, <2 x fp128>)15declare float @llvm.vector.reduce.fadd.f32.v16f32(float, <16 x float>)16 17define half @test_v1f16(<1 x half> %a, half %s) nounwind {18; CHECK-SD-LABEL: test_v1f16:19; CHECK-SD: // %bb.0:20; CHECK-SD-NEXT: fcvt s0, h021; CHECK-SD-NEXT: fcvt s1, h122; CHECK-SD-NEXT: fadd s0, s1, s023; CHECK-SD-NEXT: fcvt h0, s024; CHECK-SD-NEXT: ret25;26; CHECK-GI-LABEL: test_v1f16:27; CHECK-GI: // %bb.0:28; CHECK-GI-NEXT: fcvt s1, h129; CHECK-GI-NEXT: fcvt s0, h030; CHECK-GI-NEXT: fadd s0, s1, s031; CHECK-GI-NEXT: fcvt h0, s032; CHECK-GI-NEXT: ret33 %b = call half @llvm.vector.reduce.fadd.f16.v1f16(half %s, <1 x half> %a)34 ret half %b35}36 37define half @test_v1f16_neutral(<1 x half> %a) nounwind {38; CHECK-LABEL: test_v1f16_neutral:39; CHECK: // %bb.0:40; CHECK-NEXT: ret41 %b = call half @llvm.vector.reduce.fadd.f16.v1f16(half -0.0, <1 x half> %a)42 ret half %b43}44 45define float @test_v1f32(<1 x float> %a, float %s) nounwind {46; CHECK-SD-LABEL: test_v1f32:47; CHECK-SD: // %bb.0:48; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q049; CHECK-SD-NEXT: fadd s0, s1, s050; CHECK-SD-NEXT: ret51;52; CHECK-GI-LABEL: test_v1f32:53; CHECK-GI: // %bb.0:54; CHECK-GI-NEXT: fadd s0, s1, s055; CHECK-GI-NEXT: ret56 %b = call float @llvm.vector.reduce.fadd.f32.v1f32(float %s, <1 x float> %a)57 ret float %b58}59 60define float @test_v1f32_neutral(<1 x float> %a) nounwind {61; CHECK-SD-LABEL: test_v1f32_neutral:62; CHECK-SD: // %bb.0:63; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q064; CHECK-SD-NEXT: // kill: def $s0 killed $s0 killed $q065; CHECK-SD-NEXT: ret66;67; CHECK-GI-LABEL: test_v1f32_neutral:68; CHECK-GI: // %bb.0:69; CHECK-GI-NEXT: // kill: def $s0 killed $s0 killed $d070; CHECK-GI-NEXT: ret71 %b = call float @llvm.vector.reduce.fadd.f32.v1f32(float -0.0, <1 x float> %a)72 ret float %b73}74 75define double @test_v1f64(<1 x double> %a, double %s) nounwind {76; CHECK-LABEL: test_v1f64:77; CHECK: // %bb.0:78; CHECK-NEXT: fadd d0, d1, d079; CHECK-NEXT: ret80 %b = call double @llvm.vector.reduce.fadd.f64.v1f64(double %s, <1 x double> %a)81 ret double %b82}83 84define double @test_v1f64_neutral(<1 x double> %a) nounwind {85; CHECK-LABEL: test_v1f64_neutral:86; CHECK: // %bb.0:87; CHECK-NEXT: ret88 %b = call double @llvm.vector.reduce.fadd.f64.v1f64(double -0.0, <1 x double> %a)89 ret double %b90}91 92define fp128 @test_v1f128(<1 x fp128> %a, fp128 %s) nounwind {93; CHECK-LABEL: test_v1f128:94; CHECK: // %bb.0:95; CHECK-NEXT: mov v2.16b, v0.16b96; CHECK-NEXT: mov v0.16b, v1.16b97; CHECK-NEXT: mov v1.16b, v2.16b98; CHECK-NEXT: b __addtf399 %b = call fp128 @llvm.vector.reduce.fadd.f128.v1f128(fp128 %s, <1 x fp128> %a)100 ret fp128 %b101}102 103define fp128 @test_v1f128_neutral(<1 x fp128> %a) nounwind {104; CHECK-LABEL: test_v1f128_neutral:105; CHECK: // %bb.0:106; CHECK-NEXT: ret107 %b = call fp128 @llvm.vector.reduce.fadd.f128.v1f128(fp128 0xL00000000000000008000000000000000, <1 x fp128> %a)108 ret fp128 %b109}110 111define float @test_v3f32(<3 x float> %a, float %s) nounwind {112; CHECK-SD-LABEL: test_v3f32:113; CHECK-SD: // %bb.0:114; CHECK-SD-NEXT: fadd s1, s1, s0115; CHECK-SD-NEXT: mov s2, v0.s[1]116; CHECK-SD-NEXT: mov s0, v0.s[2]117; CHECK-SD-NEXT: fadd s1, s1, s2118; CHECK-SD-NEXT: fadd s0, s1, s0119; CHECK-SD-NEXT: ret120;121; CHECK-GI-LABEL: test_v3f32:122; CHECK-GI: // %bb.0:123; CHECK-GI-NEXT: mov s2, v0.s[1]124; CHECK-GI-NEXT: fadd s1, s1, s0125; CHECK-GI-NEXT: mov s0, v0.s[2]126; CHECK-GI-NEXT: fadd s1, s1, s2127; CHECK-GI-NEXT: fadd s0, s1, s0128; CHECK-GI-NEXT: ret129 %b = call float @llvm.vector.reduce.fadd.f32.v3f32(float %s, <3 x float> %a)130 ret float %b131}132 133define float @test_v3f32_neutral(<3 x float> %a) nounwind {134; CHECK-LABEL: test_v3f32_neutral:135; CHECK: // %bb.0:136; CHECK-NEXT: mov s1, v0.s[2]137; CHECK-NEXT: faddp s0, v0.2s138; CHECK-NEXT: fadd s0, s0, s1139; CHECK-NEXT: ret140 %b = call float @llvm.vector.reduce.fadd.f32.v3f32(float -0.0, <3 x float> %a)141 ret float %b142}143 144define float @test_v5f32(<5 x float> %a, float %s) nounwind {145; CHECK-LABEL: test_v5f32:146; CHECK: // %bb.0:147; CHECK-NEXT: fadd s0, s5, s0148; CHECK-NEXT: fadd s0, s0, s1149; CHECK-NEXT: fadd s0, s0, s2150; CHECK-NEXT: fadd s0, s0, s3151; CHECK-NEXT: fadd s0, s0, s4152; CHECK-NEXT: ret153 %b = call float @llvm.vector.reduce.fadd.f32.v5f32(float %s, <5 x float> %a)154 ret float %b155}156 157define float @test_v5f32_neutral(<5 x float> %a) nounwind {158; CHECK-LABEL: test_v5f32_neutral:159; CHECK: // %bb.0:160; CHECK-NEXT: fadd s0, s0, s1161; CHECK-NEXT: fadd s0, s0, s2162; CHECK-NEXT: fadd s0, s0, s3163; CHECK-NEXT: fadd s0, s0, s4164; CHECK-NEXT: ret165 %b = call float @llvm.vector.reduce.fadd.f32.v5f32(float -0.0, <5 x float> %a)166 ret float %b167}168 169define fp128 @test_v2f128(<2 x fp128> %a, fp128 %s) nounwind {170; CHECK-SD-LABEL: test_v2f128:171; CHECK-SD: // %bb.0:172; CHECK-SD-NEXT: sub sp, sp, #32173; CHECK-SD-NEXT: str q1, [sp] // 16-byte Spill174; CHECK-SD-NEXT: mov v1.16b, v0.16b175; CHECK-SD-NEXT: mov v0.16b, v2.16b176; CHECK-SD-NEXT: str x30, [sp, #16] // 8-byte Spill177; CHECK-SD-NEXT: bl __addtf3178; CHECK-SD-NEXT: ldr q1, [sp] // 16-byte Reload179; CHECK-SD-NEXT: ldr x30, [sp, #16] // 8-byte Reload180; CHECK-SD-NEXT: add sp, sp, #32181; CHECK-SD-NEXT: b __addtf3182;183; CHECK-GI-LABEL: test_v2f128:184; CHECK-GI: // %bb.0:185; CHECK-GI-NEXT: sub sp, sp, #32186; CHECK-GI-NEXT: mov v3.16b, v0.16b187; CHECK-GI-NEXT: str q1, [sp] // 16-byte Spill188; CHECK-GI-NEXT: mov v0.16b, v2.16b189; CHECK-GI-NEXT: str x30, [sp, #16] // 8-byte Spill190; CHECK-GI-NEXT: mov v1.16b, v3.16b191; CHECK-GI-NEXT: bl __addtf3192; CHECK-GI-NEXT: ldr q1, [sp] // 16-byte Reload193; CHECK-GI-NEXT: bl __addtf3194; CHECK-GI-NEXT: ldr x30, [sp, #16] // 8-byte Reload195; CHECK-GI-NEXT: add sp, sp, #32196; CHECK-GI-NEXT: ret197 %b = call fp128 @llvm.vector.reduce.fadd.f128.v2f128(fp128 %s, <2 x fp128> %a)198 ret fp128 %b199}200 201define fp128 @test_v2f128_neutral(<2 x fp128> %a) nounwind {202; CHECK-SD-LABEL: test_v2f128_neutral:203; CHECK-SD: // %bb.0:204; CHECK-SD-NEXT: b __addtf3205;206; CHECK-GI-LABEL: test_v2f128_neutral:207; CHECK-GI: // %bb.0:208; CHECK-GI-NEXT: sub sp, sp, #32209; CHECK-GI-NEXT: mov v2.16b, v0.16b210; CHECK-GI-NEXT: adrp x8, .LCPI13_0211; CHECK-GI-NEXT: str q1, [sp] // 16-byte Spill212; CHECK-GI-NEXT: ldr q0, [x8, :lo12:.LCPI13_0]213; CHECK-GI-NEXT: str x30, [sp, #16] // 8-byte Spill214; CHECK-GI-NEXT: mov v1.16b, v2.16b215; CHECK-GI-NEXT: bl __addtf3216; CHECK-GI-NEXT: ldr q1, [sp] // 16-byte Reload217; CHECK-GI-NEXT: bl __addtf3218; CHECK-GI-NEXT: ldr x30, [sp, #16] // 8-byte Reload219; CHECK-GI-NEXT: add sp, sp, #32220; CHECK-GI-NEXT: ret221 %b = call fp128 @llvm.vector.reduce.fadd.f128.v2f128(fp128 0xL00000000000000008000000000000000, <2 x fp128> %a)222 ret fp128 %b223}224 225define float @test_v16f32(<16 x float> %a, float %s) nounwind {226; CHECK-SD-LABEL: test_v16f32:227; CHECK-SD: // %bb.0:228; CHECK-SD-NEXT: mov s6, v0.s[1]229; CHECK-SD-NEXT: fadd s4, s4, s0230; CHECK-SD-NEXT: mov s7, v0.s[2]231; CHECK-SD-NEXT: mov s0, v0.s[3]232; CHECK-SD-NEXT: mov s5, v2.s[1]233; CHECK-SD-NEXT: fadd s4, s4, s6234; CHECK-SD-NEXT: mov s6, v1.s[2]235; CHECK-SD-NEXT: fadd s4, s4, s7236; CHECK-SD-NEXT: fadd s0, s4, s0237; CHECK-SD-NEXT: mov s4, v1.s[1]238; CHECK-SD-NEXT: fadd s0, s0, s1239; CHECK-SD-NEXT: mov s1, v1.s[3]240; CHECK-SD-NEXT: fadd s0, s0, s4241; CHECK-SD-NEXT: fadd s0, s0, s6242; CHECK-SD-NEXT: fadd s0, s0, s1243; CHECK-SD-NEXT: mov s1, v2.s[2]244; CHECK-SD-NEXT: fadd s0, s0, s2245; CHECK-SD-NEXT: mov s2, v2.s[3]246; CHECK-SD-NEXT: fadd s0, s0, s5247; CHECK-SD-NEXT: fadd s0, s0, s1248; CHECK-SD-NEXT: mov s1, v3.s[1]249; CHECK-SD-NEXT: fadd s0, s0, s2250; CHECK-SD-NEXT: mov s2, v3.s[2]251; CHECK-SD-NEXT: fadd s0, s0, s3252; CHECK-SD-NEXT: fadd s0, s0, s1253; CHECK-SD-NEXT: mov s1, v3.s[3]254; CHECK-SD-NEXT: fadd s0, s0, s2255; CHECK-SD-NEXT: fadd s0, s0, s1256; CHECK-SD-NEXT: ret257;258; CHECK-GI-LABEL: test_v16f32:259; CHECK-GI: // %bb.0:260; CHECK-GI-NEXT: mov s5, v0.s[1]261; CHECK-GI-NEXT: fadd s4, s4, s0262; CHECK-GI-NEXT: mov s6, v0.s[2]263; CHECK-GI-NEXT: mov s0, v0.s[3]264; CHECK-GI-NEXT: fadd s4, s4, s5265; CHECK-GI-NEXT: mov s5, v1.s[2]266; CHECK-GI-NEXT: fadd s4, s4, s6267; CHECK-GI-NEXT: fadd s0, s4, s0268; CHECK-GI-NEXT: mov s4, v1.s[1]269; CHECK-GI-NEXT: fadd s0, s0, s1270; CHECK-GI-NEXT: mov s1, v1.s[3]271; CHECK-GI-NEXT: fadd s0, s0, s4272; CHECK-GI-NEXT: mov s4, v2.s[2]273; CHECK-GI-NEXT: fadd s0, s0, s5274; CHECK-GI-NEXT: fadd s0, s0, s1275; CHECK-GI-NEXT: mov s1, v2.s[1]276; CHECK-GI-NEXT: fadd s0, s0, s2277; CHECK-GI-NEXT: fadd s0, s0, s1278; CHECK-GI-NEXT: mov s1, v2.s[3]279; CHECK-GI-NEXT: mov s2, v3.s[2]280; CHECK-GI-NEXT: fadd s0, s0, s4281; CHECK-GI-NEXT: fadd s0, s0, s1282; CHECK-GI-NEXT: mov s1, v3.s[1]283; CHECK-GI-NEXT: fadd s0, s0, s3284; CHECK-GI-NEXT: fadd s0, s0, s1285; CHECK-GI-NEXT: mov s1, v3.s[3]286; CHECK-GI-NEXT: fadd s0, s0, s2287; CHECK-GI-NEXT: fadd s0, s0, s1288; CHECK-GI-NEXT: ret289 %b = call float @llvm.vector.reduce.fadd.f32.v16f32(float %s, <16 x float> %a)290 ret float %b291}292 293define float @test_v16f32_neutral(<16 x float> %a) nounwind {294; CHECK-SD-LABEL: test_v16f32_neutral:295; CHECK-SD: // %bb.0:296; CHECK-SD-NEXT: mov s5, v0.s[2]297; CHECK-SD-NEXT: faddp s6, v0.2s298; CHECK-SD-NEXT: mov s0, v0.s[3]299; CHECK-SD-NEXT: mov s4, v1.s[1]300; CHECK-SD-NEXT: fadd s5, s6, s5301; CHECK-SD-NEXT: fadd s0, s5, s0302; CHECK-SD-NEXT: mov s5, v1.s[2]303; CHECK-SD-NEXT: fadd s0, s0, s1304; CHECK-SD-NEXT: mov s1, v1.s[3]305; CHECK-SD-NEXT: fadd s0, s0, s4306; CHECK-SD-NEXT: mov s4, v2.s[2]307; CHECK-SD-NEXT: fadd s0, s0, s5308; CHECK-SD-NEXT: fadd s0, s0, s1309; CHECK-SD-NEXT: mov s1, v2.s[1]310; CHECK-SD-NEXT: fadd s0, s0, s2311; CHECK-SD-NEXT: fadd s0, s0, s1312; CHECK-SD-NEXT: mov s1, v2.s[3]313; CHECK-SD-NEXT: mov s2, v3.s[2]314; CHECK-SD-NEXT: fadd s0, s0, s4315; CHECK-SD-NEXT: fadd s0, s0, s1316; CHECK-SD-NEXT: mov s1, v3.s[1]317; CHECK-SD-NEXT: fadd s0, s0, s3318; CHECK-SD-NEXT: fadd s0, s0, s1319; CHECK-SD-NEXT: mov s1, v3.s[3]320; CHECK-SD-NEXT: fadd s0, s0, s2321; CHECK-SD-NEXT: fadd s0, s0, s1322; CHECK-SD-NEXT: ret323;324; CHECK-GI-LABEL: test_v16f32_neutral:325; CHECK-GI: // %bb.0:326; CHECK-GI-NEXT: mov s4, v0.s[2]327; CHECK-GI-NEXT: faddp s5, v0.2s328; CHECK-GI-NEXT: mov s0, v0.s[3]329; CHECK-GI-NEXT: fadd s4, s5, s4330; CHECK-GI-NEXT: mov s5, v1.s[2]331; CHECK-GI-NEXT: fadd s0, s4, s0332; CHECK-GI-NEXT: mov s4, v1.s[1]333; CHECK-GI-NEXT: fadd s0, s0, s1334; CHECK-GI-NEXT: mov s1, v1.s[3]335; CHECK-GI-NEXT: fadd s0, s0, s4336; CHECK-GI-NEXT: mov s4, v2.s[2]337; CHECK-GI-NEXT: fadd s0, s0, s5338; CHECK-GI-NEXT: fadd s0, s0, s1339; CHECK-GI-NEXT: mov s1, v2.s[1]340; CHECK-GI-NEXT: fadd s0, s0, s2341; CHECK-GI-NEXT: fadd s0, s0, s1342; CHECK-GI-NEXT: mov s1, v2.s[3]343; CHECK-GI-NEXT: mov s2, v3.s[2]344; CHECK-GI-NEXT: fadd s0, s0, s4345; CHECK-GI-NEXT: fadd s0, s0, s1346; CHECK-GI-NEXT: mov s1, v3.s[1]347; CHECK-GI-NEXT: fadd s0, s0, s3348; CHECK-GI-NEXT: fadd s0, s0, s1349; CHECK-GI-NEXT: mov s1, v3.s[3]350; CHECK-GI-NEXT: fadd s0, s0, s2351; CHECK-GI-NEXT: fadd s0, s0, s1352; CHECK-GI-NEXT: ret353 %b = call float @llvm.vector.reduce.fadd.f32.v16f32(float -0.0, <16 x float> %a)354 ret float %b355}356