1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=armv7-eabi -mattr=+neon,+vfp4 -fp-contract=fast | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; Check generated fused MAC and MLS. 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workerdefine double @fusedMACTest1(double %d1, double %d2, double %d3) { 5*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest1: 6*9880d681SAndroid Build Coastguard Worker;CHECK: vfma.f64 7*9880d681SAndroid Build Coastguard Worker %1 = fmul double %d1, %d2 8*9880d681SAndroid Build Coastguard Worker %2 = fadd double %1, %d3 9*9880d681SAndroid Build Coastguard Worker ret double %2 10*9880d681SAndroid Build Coastguard Worker} 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerdefine float @fusedMACTest2(float %f1, float %f2, float %f3) { 13*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest2: 14*9880d681SAndroid Build Coastguard Worker;CHECK: vfma.f32 15*9880d681SAndroid Build Coastguard Worker %1 = fmul float %f1, %f2 16*9880d681SAndroid Build Coastguard Worker %2 = fadd float %1, %f3 17*9880d681SAndroid Build Coastguard Worker ret float %2 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Workerdefine double @fusedMACTest3(double %d1, double %d2, double %d3) { 21*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest3: 22*9880d681SAndroid Build Coastguard Worker;CHECK: vfms.f64 23*9880d681SAndroid Build Coastguard Worker %1 = fmul double %d2, %d3 24*9880d681SAndroid Build Coastguard Worker %2 = fsub double %d1, %1 25*9880d681SAndroid Build Coastguard Worker ret double %2 26*9880d681SAndroid Build Coastguard Worker} 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Workerdefine float @fusedMACTest4(float %f1, float %f2, float %f3) { 29*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest4: 30*9880d681SAndroid Build Coastguard Worker;CHECK: vfms.f32 31*9880d681SAndroid Build Coastguard Worker %1 = fmul float %f2, %f3 32*9880d681SAndroid Build Coastguard Worker %2 = fsub float %f1, %1 33*9880d681SAndroid Build Coastguard Worker ret float %2 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Workerdefine double @fusedMACTest5(double %d1, double %d2, double %d3) { 37*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest5: 38*9880d681SAndroid Build Coastguard Worker;CHECK: vfnma.f64 39*9880d681SAndroid Build Coastguard Worker %1 = fmul double %d1, %d2 40*9880d681SAndroid Build Coastguard Worker %2 = fsub double -0.0, %1 41*9880d681SAndroid Build Coastguard Worker %3 = fsub double %2, %d3 42*9880d681SAndroid Build Coastguard Worker ret double %3 43*9880d681SAndroid Build Coastguard Worker} 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Workerdefine float @fusedMACTest6(float %f1, float %f2, float %f3) { 46*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest6: 47*9880d681SAndroid Build Coastguard Worker;CHECK: vfnma.f32 48*9880d681SAndroid Build Coastguard Worker %1 = fmul float %f1, %f2 49*9880d681SAndroid Build Coastguard Worker %2 = fsub float -0.0, %1 50*9880d681SAndroid Build Coastguard Worker %3 = fsub float %2, %f3 51*9880d681SAndroid Build Coastguard Worker ret float %3 52*9880d681SAndroid Build Coastguard Worker} 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Workerdefine double @fusedMACTest7(double %d1, double %d2, double %d3) { 55*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest7: 56*9880d681SAndroid Build Coastguard Worker;CHECK: vfnms.f64 57*9880d681SAndroid Build Coastguard Worker %1 = fmul double %d1, %d2 58*9880d681SAndroid Build Coastguard Worker %2 = fsub double %1, %d3 59*9880d681SAndroid Build Coastguard Worker ret double %2 60*9880d681SAndroid Build Coastguard Worker} 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Workerdefine float @fusedMACTest8(float %f1, float %f2, float %f3) { 63*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest8: 64*9880d681SAndroid Build Coastguard Worker;CHECK: vfnms.f32 65*9880d681SAndroid Build Coastguard Worker %1 = fmul float %f1, %f2 66*9880d681SAndroid Build Coastguard Worker %2 = fsub float %1, %f3 67*9880d681SAndroid Build Coastguard Worker ret float %2 68*9880d681SAndroid Build Coastguard Worker} 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Workerdefine <2 x float> @fusedMACTest9(<2 x float> %a, <2 x float> %b) { 71*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest9: 72*9880d681SAndroid Build Coastguard Worker;CHECK: vfma.f32 73*9880d681SAndroid Build Coastguard Worker %mul = fmul <2 x float> %a, %b 74*9880d681SAndroid Build Coastguard Worker %add = fadd <2 x float> %mul, %a 75*9880d681SAndroid Build Coastguard Worker ret <2 x float> %add 76*9880d681SAndroid Build Coastguard Worker} 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Workerdefine <2 x float> @fusedMACTest10(<2 x float> %a, <2 x float> %b) { 79*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest10: 80*9880d681SAndroid Build Coastguard Worker;CHECK: vfms.f32 81*9880d681SAndroid Build Coastguard Worker %mul = fmul <2 x float> %a, %b 82*9880d681SAndroid Build Coastguard Worker %sub = fsub <2 x float> %a, %mul 83*9880d681SAndroid Build Coastguard Worker ret <2 x float> %sub 84*9880d681SAndroid Build Coastguard Worker} 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fusedMACTest11(<4 x float> %a, <4 x float> %b) { 87*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest11: 88*9880d681SAndroid Build Coastguard Worker;CHECK: vfma.f32 89*9880d681SAndroid Build Coastguard Worker %mul = fmul <4 x float> %a, %b 90*9880d681SAndroid Build Coastguard Worker %add = fadd <4 x float> %mul, %a 91*9880d681SAndroid Build Coastguard Worker ret <4 x float> %add 92*9880d681SAndroid Build Coastguard Worker} 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fusedMACTest12(<4 x float> %a, <4 x float> %b) { 95*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: fusedMACTest12: 96*9880d681SAndroid Build Coastguard Worker;CHECK: vfms.f32 97*9880d681SAndroid Build Coastguard Worker %mul = fmul <4 x float> %a, %b 98*9880d681SAndroid Build Coastguard Worker %sub = fsub <4 x float> %a, %mul 99*9880d681SAndroid Build Coastguard Worker ret <4 x float> %sub 100*9880d681SAndroid Build Coastguard Worker} 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Workerdefine float @test_fma_f32(float %a, float %b, float %c) nounwind readnone ssp { 103*9880d681SAndroid Build Coastguard Workerentry: 104*9880d681SAndroid Build Coastguard Worker; CHECK: test_fma_f32 105*9880d681SAndroid Build Coastguard Worker; CHECK: vfma.f32 106*9880d681SAndroid Build Coastguard Worker %tmp1 = tail call float @llvm.fma.f32(float %a, float %b, float %c) nounwind readnone 107*9880d681SAndroid Build Coastguard Worker ret float %tmp1 108*9880d681SAndroid Build Coastguard Worker} 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workerdefine double @test_fma_f64(double %a, double %b, double %c) nounwind readnone ssp { 111*9880d681SAndroid Build Coastguard Workerentry: 112*9880d681SAndroid Build Coastguard Worker; CHECK: test_fma_f64 113*9880d681SAndroid Build Coastguard Worker; CHECK: vfma.f64 114*9880d681SAndroid Build Coastguard Worker %tmp1 = tail call double @llvm.fma.f64(double %a, double %b, double %c) nounwind readnone 115*9880d681SAndroid Build Coastguard Worker ret double %tmp1 116*9880d681SAndroid Build Coastguard Worker} 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Workerdefine <2 x float> @test_fma_v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind readnone ssp { 119*9880d681SAndroid Build Coastguard Workerentry: 120*9880d681SAndroid Build Coastguard Worker; CHECK: test_fma_v2f32 121*9880d681SAndroid Build Coastguard Worker; CHECK: vfma.f32 122*9880d681SAndroid Build Coastguard Worker %tmp1 = tail call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind 123*9880d681SAndroid Build Coastguard Worker ret <2 x float> %tmp1 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerdefine double @test_fms_f64(double %a, double %b, double %c) nounwind readnone ssp { 127*9880d681SAndroid Build Coastguard Workerentry: 128*9880d681SAndroid Build Coastguard Worker; CHECK: test_fms_f64 129*9880d681SAndroid Build Coastguard Worker; CHECK: vfms.f64 130*9880d681SAndroid Build Coastguard Worker %tmp1 = fsub double -0.0, %a 131*9880d681SAndroid Build Coastguard Worker %tmp2 = tail call double @llvm.fma.f64(double %tmp1, double %b, double %c) nounwind readnone 132*9880d681SAndroid Build Coastguard Worker ret double %tmp2 133*9880d681SAndroid Build Coastguard Worker} 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Workerdefine double @test_fms_f64_2(double %a, double %b, double %c) nounwind readnone ssp { 136*9880d681SAndroid Build Coastguard Workerentry: 137*9880d681SAndroid Build Coastguard Worker; CHECK: test_fms_f64_2 138*9880d681SAndroid Build Coastguard Worker; CHECK: vfms.f64 139*9880d681SAndroid Build Coastguard Worker %tmp1 = fsub double -0.0, %b 140*9880d681SAndroid Build Coastguard Worker %tmp2 = tail call double @llvm.fma.f64(double %a, double %tmp1, double %c) nounwind readnone 141*9880d681SAndroid Build Coastguard Worker ret double %tmp2 142*9880d681SAndroid Build Coastguard Worker} 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Workerdefine float @test_fnms_f32(float %a, float %b, float* %c) nounwind readnone ssp { 145*9880d681SAndroid Build Coastguard Worker; CHECK: test_fnms_f32 146*9880d681SAndroid Build Coastguard Worker; CHECK: vfnms.f32 147*9880d681SAndroid Build Coastguard Worker %tmp1 = load float, float* %c, align 4 148*9880d681SAndroid Build Coastguard Worker %tmp2 = fsub float -0.0, %tmp1 149*9880d681SAndroid Build Coastguard Worker %tmp3 = tail call float @llvm.fma.f32(float %a, float %b, float %tmp2) nounwind readnone 150*9880d681SAndroid Build Coastguard Worker ret float %tmp3 151*9880d681SAndroid Build Coastguard Worker} 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Workerdefine double @test_fnms_f64(double %a, double %b, double %c) nounwind readnone ssp { 154*9880d681SAndroid Build Coastguard Workerentry: 155*9880d681SAndroid Build Coastguard Worker; CHECK: test_fnms_f64 156*9880d681SAndroid Build Coastguard Worker; CHECK: vfnms.f64 157*9880d681SAndroid Build Coastguard Worker %tmp1 = fsub double -0.0, %a 158*9880d681SAndroid Build Coastguard Worker %tmp2 = tail call double @llvm.fma.f64(double %tmp1, double %b, double %c) nounwind readnone 159*9880d681SAndroid Build Coastguard Worker %tmp3 = fsub double -0.0, %tmp2 160*9880d681SAndroid Build Coastguard Worker ret double %tmp3 161*9880d681SAndroid Build Coastguard Worker} 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Workerdefine double @test_fnms_f64_2(double %a, double %b, double %c) nounwind readnone ssp { 164*9880d681SAndroid Build Coastguard Workerentry: 165*9880d681SAndroid Build Coastguard Worker; CHECK: test_fnms_f64_2 166*9880d681SAndroid Build Coastguard Worker; CHECK: vfnms.f64 167*9880d681SAndroid Build Coastguard Worker %tmp1 = fsub double -0.0, %b 168*9880d681SAndroid Build Coastguard Worker %tmp2 = tail call double @llvm.fma.f64(double %a, double %tmp1, double %c) nounwind readnone 169*9880d681SAndroid Build Coastguard Worker %tmp3 = fsub double -0.0, %tmp2 170*9880d681SAndroid Build Coastguard Worker ret double %tmp3 171*9880d681SAndroid Build Coastguard Worker} 172*9880d681SAndroid Build Coastguard Worker 173*9880d681SAndroid Build Coastguard Workerdefine double @test_fnma_f64(double %a, double %b, double %c) nounwind readnone ssp { 174*9880d681SAndroid Build Coastguard Workerentry: 175*9880d681SAndroid Build Coastguard Worker; CHECK: test_fnma_f64 176*9880d681SAndroid Build Coastguard Worker; CHECK: vfnma.f64 177*9880d681SAndroid Build Coastguard Worker %tmp1 = tail call double @llvm.fma.f64(double %a, double %b, double %c) nounwind readnone 178*9880d681SAndroid Build Coastguard Worker %tmp2 = fsub double -0.0, %tmp1 179*9880d681SAndroid Build Coastguard Worker ret double %tmp2 180*9880d681SAndroid Build Coastguard Worker} 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Workerdefine double @test_fnma_f64_2(double %a, double %b, double %c) nounwind readnone ssp { 183*9880d681SAndroid Build Coastguard Workerentry: 184*9880d681SAndroid Build Coastguard Worker; CHECK: test_fnma_f64_2 185*9880d681SAndroid Build Coastguard Worker; CHECK: vfnma.f64 186*9880d681SAndroid Build Coastguard Worker %tmp1 = fsub double -0.0, %a 187*9880d681SAndroid Build Coastguard Worker %tmp2 = fsub double -0.0, %c 188*9880d681SAndroid Build Coastguard Worker %tmp3 = tail call double @llvm.fma.f64(double %tmp1, double %b, double %tmp2) nounwind readnone 189*9880d681SAndroid Build Coastguard Worker ret double %tmp3 190*9880d681SAndroid Build Coastguard Worker} 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Workerdefine float @test_fma_const_fold(float %a, float %b) nounwind { 193*9880d681SAndroid Build Coastguard Worker; CHECK: test_fma_const_fold 194*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: vfma 195*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: vmul 196*9880d681SAndroid Build Coastguard Worker; CHECK: vadd 197*9880d681SAndroid Build Coastguard Worker %ret = call float @llvm.fma.f32(float %a, float 1.0, float %b) 198*9880d681SAndroid Build Coastguard Worker ret float %ret 199*9880d681SAndroid Build Coastguard Worker} 200*9880d681SAndroid Build Coastguard Worker 201*9880d681SAndroid Build Coastguard Workerdefine float @test_fma_canonicalize(float %a, float %b) nounwind { 202*9880d681SAndroid Build Coastguard Worker; CHECK: test_fma_canonicalize 203*9880d681SAndroid Build Coastguard Worker; CHECK: vmov.f32 [[R1:s[0-9]+]], #2.000000e+00 204*9880d681SAndroid Build Coastguard Worker; CHECK: vfma.f32 {{s[0-9]+}}, {{s[0-9]+}}, [[R1]] 205*9880d681SAndroid Build Coastguard Worker %ret = call float @llvm.fma.f32(float 2.0, float %a, float %b) 206*9880d681SAndroid Build Coastguard Worker ret float %ret 207*9880d681SAndroid Build Coastguard Worker} 208*9880d681SAndroid Build Coastguard Worker 209*9880d681SAndroid Build Coastguard Worker; Check that very wide vector fma's can be split into legal fma's. 210*9880d681SAndroid Build Coastguard Workerdefine void @test_fma_v8f32(<8 x float> %a, <8 x float> %b, <8 x float> %c, <8 x float>* %p) nounwind readnone ssp { 211*9880d681SAndroid Build Coastguard Worker; CHECK: test_fma_v8f32 212*9880d681SAndroid Build Coastguard Worker; CHECK: vfma.f32 213*9880d681SAndroid Build Coastguard Worker; CHECK: vfma.f32 214*9880d681SAndroid Build Coastguard Workerentry: 215*9880d681SAndroid Build Coastguard Worker %call = tail call <8 x float> @llvm.fma.v8f32(<8 x float> %a, <8 x float> %b, <8 x float> %c) nounwind readnone 216*9880d681SAndroid Build Coastguard Worker store <8 x float> %call, <8 x float>* %p, align 16 217*9880d681SAndroid Build Coastguard Worker ret void 218*9880d681SAndroid Build Coastguard Worker} 219*9880d681SAndroid Build Coastguard Worker 220*9880d681SAndroid Build Coastguard Worker 221*9880d681SAndroid Build Coastguard Workerdeclare float @llvm.fma.f32(float, float, float) nounwind readnone 222*9880d681SAndroid Build Coastguard Workerdeclare double @llvm.fma.f64(double, double, double) nounwind readnone 223*9880d681SAndroid Build Coastguard Workerdeclare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>) nounwind readnone 224*9880d681SAndroid Build Coastguard Workerdeclare <8 x float> @llvm.fma.v8f32(<8 x float>, <8 x float>, <8 x float>) nounwind readnone 225