ARM64: fix fmsub patterns which assumed accum operand was first

Confusingly, the NEON fmla instructions put the accumulator first but the
scalar versions put it at the end (like the fma lib function & LLVM's
intrinsic).

This should fix PR19345, assuming there's only one issue.

llvm-svn: 205758
This commit is contained in:
Tim Northover 2014-04-08 12:23:51 +00:00
parent 6c6bbfab19
commit 33d07468bc
2 changed files with 17 additions and 14 deletions

View File

@ -2009,11 +2009,14 @@ defm FNMSUB : ThreeOperandFPData<1, 1, "fnmsub",
// The following def pats catch the case where the LHS of an FMA is negated. // The following def pats catch the case where the LHS of an FMA is negated.
// The TriOpFrag above catches the case where the middle operand is negated. // The TriOpFrag above catches the case where the middle operand is negated.
def : Pat<(f32 (fma (fneg FPR32:$Rn), FPR32:$Rm, FPR32:$Rd)),
(FMSUBSrrr FPR32:$Rd, FPR32:$Rn, FPR32:$Rm)>;
def : Pat<(f64 (fma (fneg FPR64:$Rn), FPR64:$Rm, FPR64:$Rd)), // N.b. FMSUB etc have the accumulator at the *end* of (outs), unlike
(FMSUBDrrr FPR64:$Rd, FPR64:$Rn, FPR64:$Rm)>; // the NEON variant.
def : Pat<(f32 (fma (fneg FPR32:$Rn), FPR32:$Rm, FPR32:$Ra)),
(FMSUBSrrr FPR32:$Rn, FPR32:$Rm, FPR32:$Ra)>;
def : Pat<(f64 (fma (fneg FPR64:$Rn), FPR64:$Rm, FPR64:$Ra)),
(FMSUBDrrr FPR64:$Rn, FPR64:$Rm, FPR64:$Ra)>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Floating point comparison instructions. // Floating point comparison instructions.

View File

@ -3,7 +3,7 @@
define float @fma32(float %a, float %b, float %c) nounwind readnone ssp { define float @fma32(float %a, float %b, float %c) nounwind readnone ssp {
entry: entry:
; CHECK-LABEL: fma32: ; CHECK-LABEL: fma32:
; CHECK: fmadd ; CHECK: fmadd s0, s0, s1, s2
%0 = tail call float @llvm.fma.f32(float %a, float %b, float %c) %0 = tail call float @llvm.fma.f32(float %a, float %b, float %c)
ret float %0 ret float %0
} }
@ -11,7 +11,7 @@ entry:
define float @fnma32(float %a, float %b, float %c) nounwind readnone ssp { define float @fnma32(float %a, float %b, float %c) nounwind readnone ssp {
entry: entry:
; CHECK-LABEL: fnma32: ; CHECK-LABEL: fnma32:
; CHECK: fnmadd ; CHECK: fnmadd s0, s0, s1, s2
%0 = tail call float @llvm.fma.f32(float %a, float %b, float %c) %0 = tail call float @llvm.fma.f32(float %a, float %b, float %c)
%mul = fmul float %0, -1.000000e+00 %mul = fmul float %0, -1.000000e+00
ret float %mul ret float %mul
@ -20,7 +20,7 @@ entry:
define float @fms32(float %a, float %b, float %c) nounwind readnone ssp { define float @fms32(float %a, float %b, float %c) nounwind readnone ssp {
entry: entry:
; CHECK-LABEL: fms32: ; CHECK-LABEL: fms32:
; CHECK: fmsub ; CHECK: fmsub s0, s0, s1, s2
%mul = fmul float %b, -1.000000e+00 %mul = fmul float %b, -1.000000e+00
%0 = tail call float @llvm.fma.f32(float %a, float %mul, float %c) %0 = tail call float @llvm.fma.f32(float %a, float %mul, float %c)
ret float %0 ret float %0
@ -29,7 +29,7 @@ entry:
define float @fms32_com(float %a, float %b, float %c) nounwind readnone ssp { define float @fms32_com(float %a, float %b, float %c) nounwind readnone ssp {
entry: entry:
; CHECK-LABEL: fms32_com: ; CHECK-LABEL: fms32_com:
; CHECK: fmsub ; CHECK: fmsub s0, s1, s0, s2
%mul = fmul float %b, -1.000000e+00 %mul = fmul float %b, -1.000000e+00
%0 = tail call float @llvm.fma.f32(float %mul, float %a, float %c) %0 = tail call float @llvm.fma.f32(float %mul, float %a, float %c)
ret float %0 ret float %0
@ -38,7 +38,7 @@ entry:
define float @fnms32(float %a, float %b, float %c) nounwind readnone ssp { define float @fnms32(float %a, float %b, float %c) nounwind readnone ssp {
entry: entry:
; CHECK-LABEL: fnms32: ; CHECK-LABEL: fnms32:
; CHECK: fnmsub ; CHECK: fnmsub s0, s0, s1, s2
%mul = fmul float %c, -1.000000e+00 %mul = fmul float %c, -1.000000e+00
%0 = tail call float @llvm.fma.f32(float %a, float %b, float %mul) %0 = tail call float @llvm.fma.f32(float %a, float %b, float %mul)
ret float %0 ret float %0
@ -46,7 +46,7 @@ entry:
define double @fma64(double %a, double %b, double %c) nounwind readnone ssp { define double @fma64(double %a, double %b, double %c) nounwind readnone ssp {
; CHECK-LABEL: fma64: ; CHECK-LABEL: fma64:
; CHECK: fmadd ; CHECK: fmadd d0, d0, d1, d2
entry: entry:
%0 = tail call double @llvm.fma.f64(double %a, double %b, double %c) %0 = tail call double @llvm.fma.f64(double %a, double %b, double %c)
ret double %0 ret double %0
@ -54,7 +54,7 @@ entry:
define double @fnma64(double %a, double %b, double %c) nounwind readnone ssp { define double @fnma64(double %a, double %b, double %c) nounwind readnone ssp {
; CHECK-LABEL: fnma64: ; CHECK-LABEL: fnma64:
; CHECK: fnmadd ; CHECK: fnmadd d0, d0, d1, d2
entry: entry:
%0 = tail call double @llvm.fma.f64(double %a, double %b, double %c) %0 = tail call double @llvm.fma.f64(double %a, double %b, double %c)
%mul = fmul double %0, -1.000000e+00 %mul = fmul double %0, -1.000000e+00
@ -63,7 +63,7 @@ entry:
define double @fms64(double %a, double %b, double %c) nounwind readnone ssp { define double @fms64(double %a, double %b, double %c) nounwind readnone ssp {
; CHECK-LABEL: fms64: ; CHECK-LABEL: fms64:
; CHECK: fmsub ; CHECK: fmsub d0, d0, d1, d2
entry: entry:
%mul = fmul double %b, -1.000000e+00 %mul = fmul double %b, -1.000000e+00
%0 = tail call double @llvm.fma.f64(double %a, double %mul, double %c) %0 = tail call double @llvm.fma.f64(double %a, double %mul, double %c)
@ -72,7 +72,7 @@ entry:
define double @fms64_com(double %a, double %b, double %c) nounwind readnone ssp { define double @fms64_com(double %a, double %b, double %c) nounwind readnone ssp {
; CHECK-LABEL: fms64_com: ; CHECK-LABEL: fms64_com:
; CHECK: fmsub ; CHECK: fmsub d0, d1, d0, d2
entry: entry:
%mul = fmul double %b, -1.000000e+00 %mul = fmul double %b, -1.000000e+00
%0 = tail call double @llvm.fma.f64(double %mul, double %a, double %c) %0 = tail call double @llvm.fma.f64(double %mul, double %a, double %c)
@ -81,7 +81,7 @@ entry:
define double @fnms64(double %a, double %b, double %c) nounwind readnone ssp { define double @fnms64(double %a, double %b, double %c) nounwind readnone ssp {
; CHECK-LABEL: fnms64: ; CHECK-LABEL: fnms64:
; CHECK: fnmsub ; CHECK: fnmsub d0, d0, d1, d2
entry: entry:
%mul = fmul double %c, -1.000000e+00 %mul = fmul double %c, -1.000000e+00
%0 = tail call double @llvm.fma.f64(double %a, double %b, double %mul) %0 = tail call double @llvm.fma.f64(double %a, double %b, double %mul)