234 lines · plain
1; RUN: llc < %s -mtriple=armv7-eabi -mattr=+neon,+vfp4 -fp-contract=fast | FileCheck %s2; RUN: llc < %s -mtriple=arm-arm-eabi -mcpu=cortex-m7 -fp-contract=fast | FileCheck %s3; RUN: llc < %s -mtriple=arm-arm-eabi -mcpu=cortex-m4 -fp-contract=fast | FileCheck %s -check-prefix=DONT-FUSE4; RUN: llc < %s -mtriple=arm-arm-eabi -mcpu=cortex-m33 -fp-contract=fast | FileCheck %s -check-prefix=DONT-FUSE5 6; Check generated fused MAC and MLS.7 8define arm_aapcs_vfpcc double @fusedMACTest1(double %d1, double %d2, double %d3) {9;CHECK-LABEL: fusedMACTest1:10;CHECK: vfma.f6411 %1 = fmul double %d1, %d212 %2 = fadd double %1, %d313 ret double %214}15 16define arm_aapcs_vfpcc float @fusedMACTest2(float %f1, float %f2, float %f3) {17;CHECK-LABEL: fusedMACTest2:18;CHECK: vfma.f3219 20;DONT-FUSE-LABEL: fusedMACTest2:21;DONT-FUSE: vmul.f3222;DONT-FUSE-NEXT: vadd.f3223 24 %1 = fmul float %f1, %f225 %2 = fadd float %1, %f326 ret float %227}28 29define arm_aapcs_vfpcc double @fusedMACTest3(double %d1, double %d2, double %d3) {30;CHECK-LABEL: fusedMACTest3:31;CHECK: vfms.f6432 %1 = fmul double %d2, %d333 %2 = fsub double %d1, %134 ret double %235}36 37define arm_aapcs_vfpcc float @fusedMACTest4(float %f1, float %f2, float %f3) {38;CHECK-LABEL: fusedMACTest4:39;CHECK: vfms.f3240 %1 = fmul float %f2, %f341 %2 = fsub float %f1, %142 ret float %243}44 45define arm_aapcs_vfpcc double @fusedMACTest5(double %d1, double %d2, double %d3) {46;CHECK-LABEL: fusedMACTest5:47;CHECK: vfnma.f6448 %1 = fmul double %d1, %d249 %2 = fsub double -0.0, %150 %3 = fsub double %2, %d351 ret double %352}53 54define arm_aapcs_vfpcc float @fusedMACTest6(float %f1, float %f2, float %f3) {55;CHECK-LABEL: fusedMACTest6:56;CHECK: vfnma.f3257 %1 = fmul float %f1, %f258 %2 = fsub float -0.0, %159 %3 = fsub float %2, %f360 ret float %361}62 63define arm_aapcs_vfpcc double @fusedMACTest7(double %d1, double %d2, double %d3) {64;CHECK-LABEL: fusedMACTest7:65;CHECK: vfnms.f6466 %1 = fmul double %d1, %d267 %2 = fsub double %1, %d368 ret double %269}70 71define arm_aapcs_vfpcc float @fusedMACTest8(float %f1, float %f2, float %f3) {72;CHECK-LABEL: fusedMACTest8:73;CHECK: vfnms.f3274 %1 = fmul float %f1, %f275 %2 = fsub float %1, %f376 ret float %277}78 79define arm_aapcs_vfpcc <2 x float> @fusedMACTest9(<2 x float> %a, <2 x float> %b) {80;CHECK-LABEL: fusedMACTest9:81;CHECK: vfma.f3282 %mul = fmul <2 x float> %a, %b83 %add = fadd <2 x float> %mul, %a84 ret <2 x float> %add85}86 87define arm_aapcs_vfpcc <2 x float> @fusedMACTest10(<2 x float> %a, <2 x float> %b) {88;CHECK-LABEL: fusedMACTest10:89;CHECK: vfms.f3290 %mul = fmul <2 x float> %a, %b91 %sub = fsub <2 x float> %a, %mul92 ret <2 x float> %sub93}94 95define arm_aapcs_vfpcc <4 x float> @fusedMACTest11(<4 x float> %a, <4 x float> %b) {96;CHECK-LABEL: fusedMACTest11:97;CHECK: vfma.f3298 %mul = fmul <4 x float> %a, %b99 %add = fadd <4 x float> %mul, %a100 ret <4 x float> %add101}102 103define arm_aapcs_vfpcc <4 x float> @fusedMACTest12(<4 x float> %a, <4 x float> %b) {104;CHECK-LABEL: fusedMACTest12:105;CHECK: vfms.f32106 %mul = fmul <4 x float> %a, %b107 %sub = fsub <4 x float> %a, %mul108 ret <4 x float> %sub109}110 111define arm_aapcs_vfpcc float @test_fma_f32(float %a, float %b, float %c) nounwind readnone ssp {112entry:113; CHECK: test_fma_f32114; CHECK: vfma.f32115 %tmp1 = tail call float @llvm.fma.f32(float %a, float %b, float %c) nounwind readnone116 ret float %tmp1117}118 119define arm_aapcs_vfpcc double @test_fma_f64(double %a, double %b, double %c) nounwind readnone ssp {120entry:121; CHECK: test_fma_f64122; CHECK: vfma.f64123 %tmp1 = tail call double @llvm.fma.f64(double %a, double %b, double %c) nounwind readnone124 ret double %tmp1125}126 127define arm_aapcs_vfpcc <2 x float> @test_fma_v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind readnone ssp {128entry:129; CHECK: test_fma_v2f32130; CHECK: vfma.f32131 %tmp1 = tail call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind132 ret <2 x float> %tmp1133}134 135define arm_aapcs_vfpcc double @test_fms_f64(double %a, double %b, double %c) nounwind readnone ssp {136entry:137; CHECK: test_fms_f64138; CHECK: vfms.f64139 %tmp1 = fsub double -0.0, %a140 %tmp2 = tail call double @llvm.fma.f64(double %tmp1, double %b, double %c) nounwind readnone141 ret double %tmp2142}143 144define arm_aapcs_vfpcc double @test_fms_f64_2(double %a, double %b, double %c) nounwind readnone ssp {145entry:146; CHECK: test_fms_f64_2147; CHECK: vfms.f64148 %tmp1 = fsub double -0.0, %b149 %tmp2 = tail call double @llvm.fma.f64(double %a, double %tmp1, double %c) nounwind readnone150 ret double %tmp2151}152 153define arm_aapcs_vfpcc float @test_fnms_f32(float %a, float %b, ptr %c) nounwind readnone ssp {154; CHECK: test_fnms_f32155; CHECK: vfnms.f32156 %tmp1 = load float, ptr %c, align 4157 %tmp2 = fsub float -0.0, %tmp1158 %tmp3 = tail call float @llvm.fma.f32(float %a, float %b, float %tmp2) nounwind readnone159 ret float %tmp3 160}161 162define arm_aapcs_vfpcc double @test_fnms_f64(double %a, double %b, double %c) nounwind readnone ssp {163entry:164; CHECK: test_fnms_f64165; CHECK: vfnms.f64166 %tmp1 = fsub double -0.0, %a167 %tmp2 = tail call double @llvm.fma.f64(double %tmp1, double %b, double %c) nounwind readnone168 %tmp3 = fsub double -0.0, %tmp2169 ret double %tmp3170}171 172define arm_aapcs_vfpcc double @test_fnms_f64_2(double %a, double %b, double %c) nounwind readnone ssp {173entry:174; CHECK: test_fnms_f64_2175; CHECK: vfnms.f64176 %tmp1 = fsub double -0.0, %b177 %tmp2 = tail call double @llvm.fma.f64(double %a, double %tmp1, double %c) nounwind readnone178 %tmp3 = fsub double -0.0, %tmp2179 ret double %tmp3180}181 182define arm_aapcs_vfpcc double @test_fnma_f64(double %a, double %b, double %c) nounwind readnone ssp {183entry:184; CHECK: test_fnma_f64185; CHECK: vfnma.f64186 %tmp1 = tail call double @llvm.fma.f64(double %a, double %b, double %c) nounwind readnone187 %tmp2 = fsub double -0.0, %tmp1188 ret double %tmp2189}190 191define arm_aapcs_vfpcc double @test_fnma_f64_2(double %a, double %b, double %c) nounwind readnone ssp {192entry:193; CHECK: test_fnma_f64_2194; CHECK: vfnma.f64195 %tmp1 = fsub double -0.0, %a196 %tmp2 = fsub double -0.0, %c197 %tmp3 = tail call double @llvm.fma.f64(double %tmp1, double %b, double %tmp2) nounwind readnone198 ret double %tmp3199}200 201define arm_aapcs_vfpcc float @test_fma_const_fold(float %a, float %b) nounwind {202; CHECK: test_fma_const_fold203; CHECK-NOT: vfma204; CHECK-NOT: vmul205; CHECK: vadd206 %ret = call float @llvm.fma.f32(float %a, float 1.0, float %b)207 ret float %ret208}209 210define arm_aapcs_vfpcc float @test_fma_canonicalize(float %a, float %b) nounwind {211; CHECK: test_fma_canonicalize212; CHECK: vmov.f32 [[R1:s[0-9]+]], #2.000000e+00213; CHECK: vfma.f32 {{s[0-9]+}}, {{s[0-9]+}}, [[R1]]214 %ret = call float @llvm.fma.f32(float 2.0, float %a, float %b)215 ret float %ret216}217 218; Check that very wide vector fma's can be split into legal fma's.219define arm_aapcs_vfpcc void @test_fma_v8f32(<8 x float> %a, <8 x float> %b, <8 x float> %c, ptr %p) nounwind readnone ssp {220; CHECK: test_fma_v8f32221; CHECK: vfma.f32222; CHECK: vfma.f32223entry:224 %call = tail call <8 x float> @llvm.fma.v8f32(<8 x float> %a, <8 x float> %b, <8 x float> %c) nounwind readnone225 store <8 x float> %call, ptr %p, align 16226 ret void227}228 229 230declare float @llvm.fma.f32(float, float, float) nounwind readnone231declare double @llvm.fma.f64(double, double, double) nounwind readnone232declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>) nounwind readnone233declare <8 x float> @llvm.fma.v8f32(<8 x float>, <8 x float>, <8 x float>) nounwind readnone234