diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md --- a/flang/docs/Intrinsics.md +++ b/flang/docs/Intrinsics.md @@ -657,6 +657,11 @@ ``` ## Non-standard intrinsics +### FLANG +``` +FMADD(REAL F1, REAL F2, REAL F3) -> REAL +``` + ### PGI ``` AND, OR, XOR diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -495,6 +495,9 @@ {"back", AnyLogical, Rank::scalar, Optionality::optional}}, KINDInt, Rank::vector, IntrinsicClass::transformationalFunction}, {"floor", {{"a", AnyReal}, DefaultingKIND}, KINDInt}, + {"fmadd", + {{"f1", SameFloating}, {"f2", SameFloating}, {"f3", SameFloating}}, + SameFloating}, {"fraction", {{"x", SameReal}}, SameReal}, {"gamma", {{"x", SameReal}}, SameReal}, {"get_team", {{"level", DefaultInt, Rank::scalar, Optionality::optional}}, diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -1023,6 +1023,10 @@ // math::FloorOp returns a real, while Fortran FLOOR returns integer. {"floor", "floorf", genF32F32FuncType, genMathOp}, {"floor", "floor", genF64F64FuncType, genMathOp}, + {"fmadd", "llvm.fma.f32", genF32F32F32F32FuncType, + genMathOp}, + {"fmadd", "llvm.fma.f64", genF64F64F64F64FuncType, + genMathOp}, {"gamma", "tgammaf", genF32F32FuncType, genLibCall}, {"gamma", "tgamma", genF64F64FuncType, genLibCall}, {"hypot", "hypotf", genF32F32F32FuncType, genLibCall}, diff --git a/flang/test/Lower/Intrinsics/fmadd.f90 b/flang/test/Lower/Intrinsics/fmadd.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/Intrinsics/fmadd.f90 @@ -0,0 +1,20 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck --check-prefix=CHECK-FIR %s +! RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-LLVMIR %s + +function test_real4(a, x, y) + real :: a, x, y + test_real4 = fmadd(a, x, y) +end function + +! CHECK-LABEL: @_QPtest_real4 +! CHECK-FIR: {{%[A-Za-z0-9._]+}} = math.fma {{%[0-9]+}}, {{%[0-9]+}}, {{%[0-9]+}} {{.*}} : f32 +! CHECK-LLVMIR: {{%[A-Za-z0-9._]+}} = call {{.*}} float @llvm.fma.f32(float {{%[0-9]+}}, float {{%[0-9]+}}, float {{%[0-9]+}}) + +function test_real8(a, x, y) + real(8) :: a, x, y + test_real8 = fmadd(a, x, y) +end function + +! CHECK-LABEL: @_QPtest_real8 +! CHECK-FIR: {{%[A-Za-z0-9._]+}} = math.fma {{%[0-9]+}}, {{%[0-9]+}}, {{%[0-9]+}} {{.*}} : f64 +! CHECK-LLVMIR: {{%[A-Za-z0-9._]+}} = call {{.*}} double @llvm.fma.f64(double {{%[0-9]+}}, double {{%[0-9]+}}, double {{%[0-9]+}})