[AArch64 NEON] Fixed fused multiply negate add/sub patterns

The correct pattern matching should be:

- fnmadd is (-Ra) + (-Rn)*Rm  which should be matched as:

  fma (fneg node:$Rn),  node:$Rm, (fneg node:$Ra) and as

  (f32 (fsub (f32 (fneg FPR32:$Ra)), (f32 (fmul FPR32:$Rn, FPR32:$Rm))))

- fnmsub is (-Ra) + Rn*Rm which should be matched as

  fma node:$Rn,  node:$Rm, (fneg node:$Ra) and as

  (f32 (fsub (f32 (fmul FPR32:$Rn, FPR32:$Rm)), FPR32:$Ra))))



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197928 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ana Pazos 2013-12-24 00:40:10 +00:00
parent b8a316bfcb
commit f5bfe97875
3 changed files with 21 additions and 20 deletions

View File

@ -2172,9 +2172,9 @@ defm FSUB : A64I_fpdp2sizes<0b0011, "fsub", fsub>;
def fmsub : PatFrag<(ops node:$Rn, node:$Rm, node:$Ra),
(fma (fneg node:$Rn), node:$Rm, node:$Ra)>;
def fnmadd : PatFrag<(ops node:$Rn, node:$Rm, node:$Ra),
(fma node:$Rn, node:$Rm, (fneg node:$Ra))>;
def fnmsub : PatFrag<(ops node:$Rn, node:$Rm, node:$Ra),
(fma node:$Rn, node:$Rm, (fneg node:$Ra))>;
def fnmadd : PatFrag<(ops node:$Rn, node:$Rm, node:$Ra),
(fma (fneg node:$Rn), node:$Rm, (fneg node:$Ra))>;
class A64I_fpdp3Impl<string asmop, RegisterClass FPR, ValueType VT,
@ -2202,18 +2202,18 @@ def : Pat<(f32 (fadd FPR32:$Ra, (f32 (fmul FPR32:$Rn, FPR32:$Rm)))),
(FMADDssss FPR32:$Rn, FPR32:$Rm, FPR32:$Ra)>;
def : Pat<(f32 (fsub FPR32:$Ra, (f32 (fmul FPR32:$Rn, FPR32:$Rm)))),
(FMSUBssss FPR32:$Rn, FPR32:$Rm, FPR32:$Ra)>;
def : Pat<(f32 (fsub (f32 (fmul FPR32:$Rn, FPR32:$Rm)), FPR32:$Ra)),
(FNMADDssss FPR32:$Rn, FPR32:$Rm, FPR32:$Ra)>;
def : Pat<(f32 (fsub (f32 (fneg FPR32:$Ra)), (f32 (fmul FPR32:$Rn, FPR32:$Rm)))),
(FNMADDssss FPR32:$Rn, FPR32:$Rm, FPR32:$Ra)>;
def : Pat<(f32 (fsub (f32 (fmul FPR32:$Rn, FPR32:$Rm)), FPR32:$Ra)),
(FNMSUBssss FPR32:$Rn, FPR32:$Rm, FPR32:$Ra)>;
def : Pat<(f64 (fadd FPR64:$Ra, (f64 (fmul FPR64:$Rn, FPR64:$Rm)))),
(FMADDdddd FPR64:$Rn, FPR64:$Rm, FPR64:$Ra)>;
def : Pat<(f64 (fsub FPR64:$Ra, (f64 (fmul FPR64:$Rn, FPR64:$Rm)))),
(FMSUBdddd FPR64:$Rn, FPR64:$Rm, FPR64:$Ra)>;
def : Pat<(f64 (fsub (f64 (fmul FPR64:$Rn, FPR64:$Rm)), FPR64:$Ra)),
(FNMADDdddd FPR64:$Rn, FPR64:$Rm, FPR64:$Ra)>;
def : Pat<(f64 (fsub (f64 (fneg FPR64:$Ra)), (f64 (fmul FPR64:$Rn, FPR64:$Rm)))),
(FNMADDdddd FPR64:$Rn, FPR64:$Rm, FPR64:$Ra)>;
def : Pat<(f64 (fsub (f64 (fmul FPR64:$Rn, FPR64:$Rm)), FPR64:$Ra)),
(FNMSUBdddd FPR64:$Rn, FPR64:$Rm, FPR64:$Ra)>;
}

View File

@ -26,8 +26,9 @@ define float @test_fmsub(float %a, float %b, float %c) {
define float @test_fnmadd(float %a, float %b, float %c) {
; CHECK-LABEL: test_fnmadd:
; CHECK-NOFAST-LABEL: test_fnmadd:
%nega = fsub float -0.0, %a
%negc = fsub float -0.0, %c
%val = call float @llvm.fma.f32(float %a, float %b, float %negc)
%val = call float @llvm.fma.f32(float %nega, float %b, float %negc)
; CHECK: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
ret float %val
@ -36,9 +37,8 @@ define float @test_fnmadd(float %a, float %b, float %c) {
define float @test_fnmsub(float %a, float %b, float %c) {
; CHECK-LABEL: test_fnmsub:
; CHECK-NOFAST-LABEL: test_fnmsub:
%nega = fsub float -0.0, %a
%negc = fsub float -0.0, %c
%val = call float @llvm.fma.f32(float %nega, float %b, float %negc)
%val = call float @llvm.fma.f32(float %a, float %b, float %negc)
; CHECK: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
ret float %val
@ -66,8 +66,9 @@ define double @testd_fmsub(double %a, double %b, double %c) {
define double @testd_fnmadd(double %a, double %b, double %c) {
; CHECK-LABEL: testd_fnmadd:
; CHECK-NOFAST-LABEL: testd_fnmadd:
%nega = fsub double -0.0, %a
%negc = fsub double -0.0, %c
%val = call double @llvm.fma.f64(double %a, double %b, double %negc)
%val = call double @llvm.fma.f64(double %nega, double %b, double %negc)
; CHECK: fnmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
; CHECK-NOFAST: fnmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
ret double %val
@ -76,9 +77,8 @@ define double @testd_fnmadd(double %a, double %b, double %c) {
define double @testd_fnmsub(double %a, double %b, double %c) {
; CHECK-LABEL: testd_fnmsub:
; CHECK-NOFAST-LABEL: testd_fnmsub:
%nega = fsub double -0.0, %a
%negc = fsub double -0.0, %c
%val = call double @llvm.fma.f64(double %nega, double %b, double %negc)
%val = call double @llvm.fma.f64(double %a, double %b, double %negc)
; CHECK: fnmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
; CHECK-NOFAST: fnmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
ret double %val
@ -113,12 +113,13 @@ define float @test_fnmadd_unfused(float %a, float %b, float %c) {
; CHECK-NOFAST-LABEL: test_fnmadd_unfused:
%nega = fsub float -0.0, %a
%prod = fmul float %b, %c
%sum = fadd float %nega, %prod
%diff = fsub float %nega, %prod
; CHECK: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST-NOT: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
ret float %sum
; CHECK-NOFAST: ret
ret float %diff
}
define float @test_fnmsub_unfused(float %a, float %b, float %c) {
@ -126,12 +127,11 @@ define float @test_fnmsub_unfused(float %a, float %b, float %c) {
; CHECK-NOFAST-LABEL: test_fnmsub_unfused:
%nega = fsub float -0.0, %a
%prod = fmul float %b, %c
%diff = fsub float %nega, %prod
%sum = fadd float %nega, %prod
; CHECK: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST-NOT: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST-DAG: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST-DAG: fneg {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST-DAG: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST: ret
ret float %diff
; CHECK-NOFAST: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
; CHECK-NOFAST: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
ret float %sum
}

View File

@ -110,3 +110,4 @@ define <2 x double> @fmuladd2xdouble_fused(<2 x double> %A, <2 x double> %B, <2
%val = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %A, <2 x double> %B, <2 x double> %C)
ret <2 x double> %val
}