[Flang] [PowerPC] Implement remaining PPC math operation intrinsics that do not requi...
authorPaul Scoropan <1paulscoropan@gmail.com>
Wed, 15 Mar 2023 14:43:06 +0000 (14:43 +0000)
committerPaul Scoropan <1paulscoropan@gmail.com>
Mon, 20 Mar 2023 15:04:16 +0000 (15:04 +0000)
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
flang/module/__fortran_ppc_intrinsics.f90
flang/test/Lower/ppc-intrinsics.f90

index b933603..8ff8689 100644 (file)
@@ -1419,12 +1419,18 @@ static constexpr MathOperation ppcMathOperations[] = {
      genMathOp<mlir::math::FmaOp>},
     {"__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.
index fff18aa..1447df1 100644 (file)
@@ -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
index 8410fbd..c0eef7e 100644 (file)
@@ -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