Skip to content

Commit

Permalink
[Flang] Map ieee_fma intrinsic to llvm.fma
Browse files Browse the repository at this point in the history
Map `ieee_fma` intrinsic to LLVM IR as `llvm.fma`.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D151872
  • Loading branch information
Shao-Ce SUN committed Jun 5, 2023
1 parent 65ceb42 commit 68f55d7
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 10 deletions.
2 changes: 2 additions & 0 deletions flang/lib/Evaluate/fold-real.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
return FoldSum<T>(context, std::move(funcRef));
} else if (name == "tiny") {
return Expr<T>{Scalar<T>::TINY()};
} else if (name == "__builtin_fma") {
CHECK(args.size() == 3);
} else if (name == "__builtin_ieee_next_after") {
if (const auto *yExpr{UnwrapExpr<Expr<SomeReal>>(args[1])}) {
return common::visit(
Expand Down
2 changes: 2 additions & 0 deletions flang/lib/Evaluate/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"back", AnyLogical, Rank::elemental, Optionality::optional},
DefaultingKIND},
KINDInt},
{"__builtin_fma", {{"f1", SameReal}, {"f2", SameReal}, {"f3", SameReal}},
SameReal},
{"__builtin_ieee_is_nan", {{"a", AnyFloating}}, DefaultLogical},
{"__builtin_ieee_is_negative", {{"a", AnyFloating}}, DefaultLogical},
{"__builtin_ieee_is_normal", {{"a", AnyFloating}}, DefaultLogical},
Expand Down
4 changes: 4 additions & 0 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,10 @@ static constexpr MathOperation mathOperations[] = {
// math::FloorOp returns a real, while Fortran FLOOR returns integer.
{"floor", "floorf", genF32F32FuncType, genMathOp<mlir::math::FloorOp>},
{"floor", "floor", genF64F64FuncType, genMathOp<mlir::math::FloorOp>},
{"fma", "llvm.fma.f32", genF32F32F32F32FuncType,
genMathOp<mlir::math::FmaOp>},
{"fma", "llvm.fma.f64", genF64F64F64F64FuncType,
genMathOp<mlir::math::FmaOp>},
{"gamma", "tgammaf", genF32F32FuncType, genLibCall},
{"gamma", "tgamma", genF64F64FuncType, genLibCall},
{"hypot", "hypotf", genF32F32F32FuncType, genLibCall},
Expand Down
1 change: 1 addition & 0 deletions flang/module/__fortran_builtins.f90
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
__builtin_threadIdx, __builtin_blockDim, __builtin_blockIdx, __builtin_gridDim
integer, parameter :: __builtin_warpsize = 32

intrinsic :: __builtin_fma
intrinsic :: __builtin_ieee_is_nan, __builtin_ieee_is_negative, &
__builtin_ieee_is_normal
intrinsic :: __builtin_ieee_next_after, __builtin_ieee_next_down, &
Expand Down
11 changes: 1 addition & 10 deletions flang/module/ieee_arithmetic.f90
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module ieee_arithmetic
use __Fortran_ieee_exceptions

use __Fortran_builtins, only: &
ieee_fma => __builtin_fma, &
ieee_is_nan => __builtin_ieee_is_nan, &
ieee_is_negative => __builtin_ieee_is_negative, &
ieee_is_normal => __builtin_ieee_is_normal, &
Expand Down Expand Up @@ -220,16 +221,6 @@ end function ieee_copy_sign_a##XKIND##_a##YKIND;
PRIVATE_RR(IEEE_COPY_SIGN)
#undef IEEE_COPY_SIGN_RR

#define IEEE_FMA_R(AKIND) \
elemental real(AKIND) function ieee_fma_a##AKIND(a, b, c); \
real(AKIND), intent(in) :: a, b, c; \
end function ieee_fma_a##AKIND;
interface ieee_fma
SPECIFICS_R(IEEE_FMA_R)
end interface ieee_fma
PRIVATE_R(IEEE_FMA)
#undef IEEE_FMA_R

#define IEEE_GET_ROUNDING_MODE_I(RKIND) \
subroutine ieee_get_rounding_mode_i##RKIND(round_value, radix); \
import ieee_round_type; \
Expand Down
22 changes: 22 additions & 0 deletions flang/test/Lower/Intrinsics/fma.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
! 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)
use ieee_arithmetic, only: ieee_fma
real :: a, x, y
test_real4 = ieee_fma(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)
use ieee_arithmetic, only: ieee_fma
real(8) :: a, x, y
test_real8 = ieee_fma(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]+}})

0 comments on commit 68f55d7

Please sign in to comment.