[AArch64 NEON] Fixed fused multiply negate add/sub patterns
authorAna Pazos <apazos@codeaurora.org>
Tue, 24 Dec 2013 00:40:10 +0000 (00:40 +0000)
committerAna Pazos <apazos@codeaurora.org>
Tue, 24 Dec 2013 00:40:10 +0000 (00:40 +0000)
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

lib/Target/AArch64/AArch64InstrInfo.td
test/CodeGen/AArch64/fp-dp3.ll
test/CodeGen/AArch64/neon-fma.ll

index 4c35b466f1494ae086f34a78bba3b28a27b5cffe..add11de67f40e751633a551db403cc975a3241a0 100644 (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)>;
 }
 
index 590557f1e8edccffafbaa7be5603dab98b39ffa7..6b9acc8865f89b6d87d82585ff6e89f13a916654 100644 (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
 }
+
index 680e97728c39e0c5e4bc0a51501245a75eb0839d..7b8f2121ca684547f98dccc25e4650e34746de45 100644 (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
 }
+