From 5a222c0b82f8ade6904aa25b33fe93c2d09516f8 Mon Sep 17 00:00:00 2001 From: Paul Scoropan <1paulscoropan@gmail.com> Date: Wed, 15 Mar 2023 14:43:06 +0000 Subject: [PATCH] [Flang] [PowerPC] Implement remaining PPC math operation intrinsics that do not require semantic error checks This review implements the following PowerPC math operations that we care about: - fnabs - fre - fres - frsqrte - frsqrtes None of these intrinsics require additional error checks in semantics. The interfaces handle checking types and kinds Reviewed By: kkwli0 Differential Revision: https://reviews.llvm.org/D146139 --- flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 6 ++++ flang/module/__fortran_ppc_intrinsics.f90 | 37 +++++++++++++++++++++ flang/test/Lower/ppc-intrinsics.f90 | 48 +++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index b933603..8ff8689 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -1419,12 +1419,18 @@ static constexpr MathOperation ppcMathOperations[] = { genMathOp}, {"__ppc_fmsub", "llvm.ppc.fmsubs", genF32F32F32F32FuncType, genLibCall}, {"__ppc_fmsub", "llvm.ppc.fmsub", genF64F64F64F64FuncType, genLibCall}, + {"__ppc_fnabs", "llvm.ppc.fnabss", genF32F32FuncType, genLibCall}, + {"__ppc_fnabs", "llvm.ppc.fnabs", genF64F64FuncType, genLibCall}, {"__ppc_fnmadd", "llvm.ppc.fnmadds", genF32F32F32F32FuncType, genLibCall}, {"__ppc_fnmadd", "llvm.ppc.fnmadd", genF64F64F64F64FuncType, genLibCall}, {"__ppc_fnmsub", "llvm.ppc.fnmsub.f32", genF32F32F32F32FuncType, genLibCall}, {"__ppc_fnmsub", "llvm.ppc.fnmsub.f64", genF64F64F64F64FuncType, genLibCall}, + {"__ppc_fre", "llvm.ppc.fre", genF64F64FuncType, genLibCall}, + {"__ppc_fres", "llvm.ppc.fres", genF32F32FuncType, genLibCall}, + {"__ppc_frsqrte", "llvm.ppc.frsqrte", genF64F64FuncType, genLibCall}, + {"__ppc_frsqrtes", "llvm.ppc.frsqrtes", genF32F32FuncType, genLibCall}, }; // This helper class computes a "distance" between two function types. diff --git a/flang/module/__fortran_ppc_intrinsics.f90 b/flang/module/__fortran_ppc_intrinsics.f90 index fff18aa..1447df1 100644 --- a/flang/module/__fortran_ppc_intrinsics.f90 +++ b/flang/module/__fortran_ppc_intrinsics.f90 @@ -54,6 +54,9 @@ module __Fortran_PPC_intrinsics ! fctid, fctidz, fctiw, fctiwz, fctudz, fctuwz abstract interface + elemental real(4) function func_r4r4x(x) + real(4), intent(in) :: x + end function func_r4r4x elemental real(8) function func_r8r8x(x) real(8), intent(in) :: x end function func_r8r8x @@ -120,4 +123,38 @@ module __Fortran_PPC_intrinsics end interface fcfud public :: fcfud +! fnabs + procedure(func_r4r4x) :: __ppc_fnabs_r4 + procedure(func_r8r8x) :: __ppc_fnabs_r8 + interface fnabs + procedure :: __ppc_fnabs_r4 + procedure :: __ppc_fnabs_r8 + end interface fnabs + public :: fnabs + +! fre, fres + procedure(func_r8r8x) :: __ppc_fre + interface fre + procedure :: __ppc_fre + end interface fre + public :: fre + + procedure(func_r4r4x) :: __ppc_fres + interface fres + procedure :: __ppc_fres + end interface fres + public :: fres + +! frsqrte, frsqrtes + procedure(func_r8r8x) :: __ppc_frsqrte + interface frsqrte + procedure :: __ppc_frsqrte + end interface frsqrte + public :: frsqrte + + procedure(func_r4r4x) :: __ppc_frsqrtes + interface frsqrtes + procedure :: __ppc_frsqrtes + end interface frsqrtes + public :: frsqrtes end module __Fortran_PPC_intrinsics diff --git a/flang/test/Lower/ppc-intrinsics.f90 b/flang/test/Lower/ppc-intrinsics.f90 index 8410fbd..c0eef7e 100644 --- a/flang/test/Lower/ppc-intrinsics.f90 +++ b/flang/test/Lower/ppc-intrinsics.f90 @@ -137,3 +137,51 @@ subroutine fcfud_test(i) ! CHECK-FIR: fir.call @fir.__ppc_fcfud.f64.f64 ! CHECK-LLVMIR: call contract double @llvm.ppc.fcfud(double %{{[0-9]}}) end + +! CHECK-LABEL: fnabs_testr(x) +subroutine fnabs_testr(x) + real :: x, y + y = fnabs(x) +! CHECK-FIR: fir.call @fir.__ppc_fnabs.f32.f32 +! CHECK-LLVMIR: call contract float @llvm.ppc.fnabss(float %{{[0-9]}}) +end + +! CHECK-LABEL: fnabs_testd(x) +subroutine fnabs_testd(x) + real(8) :: x, y + y = fnabs(x) +! CHECK-FIR: fir.call @fir.__ppc_fnabs.f64.f64 +! CHECK-LLVMIR: call contract double @llvm.ppc.fnabs(double %{{[0-9]}}) +end + +!CHECK-LABEL: fre_test(x) +subroutine fre_test(x) + real(8) :: x, y + y = fre(x) +! CHECK-FIR: fir.call @fir.__ppc_fre.f64.f64 +! CHECK-LLVMIR: call contract double @llvm.ppc.fre(double %{{[0-9]}}) +end + +!CHECK-LABEL: fres_test(x) +subroutine fres_test(x) + real :: x, y + y = fres(x) +! CHECK-FIR: fir.call @fir.__ppc_fres.f32.f32 +! CHECK-LLVMIR: call contract float @llvm.ppc.fres(float %{{[0-9]}}) +end + +!CHECK-LABEL: frsqrte_test(x) +subroutine frsqrte_test(x) + real(8) :: x, y + y = frsqrte(x) +! CHECK-FIR: fir.call @fir.__ppc_frsqrte.f64.f64 +! CHECK-LLVMIR: call contract double @llvm.ppc.frsqrte(double %{{[0-9]}}) +end + +!CHECK-LABEL: frsqrtes_test(x) +subroutine frsqrtes_test(x) + real :: x, y + y = frsqrtes(x) +! CHECK-FIR: fir.call @fir.__ppc_frsqrtes.f32.f32 +! CHECK-LLVMIR: call contract float @llvm.ppc.frsqrtes(float %{{[0-9]}}) +end -- 2.7.4