diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h index a75314b5188dd..790d0a4d6d064 100644 --- a/flang/include/flang/Semantics/expression.h +++ b/flang/include/flang/Semantics/expression.h @@ -352,7 +352,6 @@ class ExpressionAnalyzer { const parser::ProcComponentRef &, ActualArguments &&, bool isSubroutine); std::optional CheckCall( parser::CharBlock, const ProcedureDesignator &, ActualArguments &); - bool CheckPPCIntrinsic(const ProcedureDesignator &, ActualArguments &); using AdjustActuals = std::optional>; bool ResolveForward(const Symbol &); diff --git a/flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp b/flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp index 6198b9326562f..7f7cf850c433a 100644 --- a/flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp @@ -248,6 +248,10 @@ static constexpr MathOperation ppcMathOperations[] = { genLibCall}, {"__ppc_frsqrtes", "llvm.ppc.frsqrtes", genFuncType, Ty::Real<4>>, genLibCall}, + {"__ppc_vec_cvbf16spn", "llvm.ppc.vsx.xvcvbf16spn", + genFuncType, Ty::UnsignedVector<1>>, genLibCall}, + {"__ppc_vec_cvspbf16_", "llvm.ppc.vsx.xvcvspbf16", + genFuncType, Ty::UnsignedVector<1>>, genLibCall}, {"__ppc_vec_madd", "llvm.fma.v4f32", genFuncType, Ty::RealVector<4>, Ty::RealVector<4>, Ty::RealVector<4>>, diff --git a/flang/module/__ppc_intrinsics.f90 b/flang/module/__ppc_intrinsics.f90 index 58d2c814b0506..80a5d87b37dc8 100644 --- a/flang/module/__ppc_intrinsics.f90 +++ b/flang/module/__ppc_intrinsics.f90 @@ -29,6 +29,12 @@ elemental vector(integer(VKIND)) function elem_func_vi##VKIND##vi##VKIND(arg1); vector(integer(VKIND)), intent(in) :: arg1; \ end function ; +! vector(u) function f(vector(u)) +#define ELEM_FUNC_VUVU(VKIND) \ + elemental vector(unsigned(VKIND)) function elem_func_vu##VKIND##vu##VKIND(arg1); \ + vector(unsigned(VKIND)), intent(in) :: arg1; \ + end function ; + ! vector(r) function f(vector(r)) #define ELEM_FUNC_VRVR_2(VKIND1, VKIND2) \ elemental vector(real(VKIND1)) function elem_func_vr##VKIND1##vr##VKIND2(arg1); \ @@ -37,11 +43,13 @@ elemental vector(real(VKIND1)) function elem_func_vr##VKIND1##vr##VKIND2(arg1); #define ELEM_FUNC_VRVR(VKIND) ELEM_FUNC_VRVR_2(VKIND, VKIND) ELEM_FUNC_VIVI(1) ELEM_FUNC_VIVI(2) ELEM_FUNC_VIVI(4) ELEM_FUNC_VIVI(8) + ELEM_FUNC_VUVU(1) ELEM_FUNC_VRVR_2(4,8) ELEM_FUNC_VRVR_2(8,4) ELEM_FUNC_VRVR(4) ELEM_FUNC_VRVR(8) #undef ELEM_FUNC_VRVR #undef ELEM_FUNC_VRVR_2 +#undef ELEM_FUNC_VUVU #undef ELEM_FUNC_VIVI !! ================ 2 arguments function interface ================ @@ -427,11 +435,14 @@ end function func_r8r8i ! vector function(vector) !------------------------- #define VI_VI(NAME, VKIND) __ppc_##NAME##_vi##VKIND##vi##VKIND +#define VU_VU(NAME, VKIND) __ppc_##NAME##_vu##VKIND##vu##VKIND #define VR_VR_2(NAME, VKIND1, VKIND2) __ppc_##NAME##_vr##VKIND1##vr##VKIND2 #define VR_VR(NAME, VKIND) VR_VR_2(NAME, VKIND, VKIND) #define VEC_VI_VI(NAME, VKIND) \ procedure(elem_func_vi##VKIND##vi##VKIND) :: VI_VI(NAME, VKIND); +#define VEC_VU_VU(NAME, VKIND) \ + procedure(elem_func_vu##VKIND##vu##VKIND) :: VU_VU(NAME, VKIND); #define VEC_VR_VR_2(NAME, VKIND1, VKIND2) \ procedure(elem_func_vr##VKIND1##vr##VKIND2) :: VR_VR_2(NAME, VKIND1, VKIND2); #define VEC_VR_VR(NAME, VKIND) VEC_VR_VR_2(NAME, VKIND, VKIND) @@ -452,11 +463,27 @@ end function func_r8r8i end interface vec_cvf public :: vec_cvf +! vec_cvbf16spn + VEC_VU_VU(vec_cvbf16spn,1) + interface vec_cvbf16spn + procedure :: VU_VU(vec_cvbf16spn,1) + end interface + public vec_cvbf16spn + +! vec_cvspbf16 + VEC_VU_VU(vec_cvspbf16_,1) + interface vec_cvspbf16 + procedure :: VU_VU(vec_cvspbf16_,1) + end interface + public vec_cvspbf16 + #undef VEC_VR_VR #undef VEC_VR_VR_2 +#undef VEC_VU_VU #undef VEC_VI_VI #undef VR_VR #undef VR_VR_2 +#undef VU_VU #undef VI_VI !--------------------------------- diff --git a/flang/test/Lower/PowerPC/ppc-pwr10-vec-intrinsics.f90 b/flang/test/Lower/PowerPC/ppc-pwr10-vec-intrinsics.f90 new file mode 100644 index 0000000000000..5ff0cd6e67741 --- /dev/null +++ b/flang/test/Lower/PowerPC/ppc-pwr10-vec-intrinsics.f90 @@ -0,0 +1,27 @@ +! RUN: %flang_fc1 -triple powerpc64le-unknown-unknown -target-cpu pwr10 -emit-llvm %s -o - | FileCheck --check-prefixes="CHECK" %s +! REQUIRES: target=powerpc{{.*}} + subroutine test_cvspbf16() + implicit none + vector(unsigned(1)) :: v1, v2 + v1 = vec_cvspbf16(v2) + end subroutine test_cvspbf16 + +!CHECK-LABEL: @test_cvspbf16_ +!CHECK: %1 = alloca <16 x i8>, i64 1, align 16 +!CHECK: %2 = alloca <16 x i8>, i64 1, align 16 +!CHECK: %3 = load <16 x i8>, ptr %2, align 16 +!CHECK: %4 = call <16 x i8> @llvm.ppc.vsx.xvcvspbf16(<16 x i8> %3) +!CHECK: store <16 x i8> %4, ptr %1, align 16 + + subroutine test_cvbf16spn() + implicit none + vector(unsigned(1)) :: v1, v2 + v1 = vec_cvbf16spn(v2) + end subroutine test_cvbf16spn + +!CHECK-LABEL: @test_cvbf16spn_ +!CHECK: %1 = alloca <16 x i8>, i64 1, align 16 +!CHECK: %2 = alloca <16 x i8>, i64 1, align 16 +!CHECK: %3 = load <16 x i8>, ptr %2, align 16 +!CHECK: %4 = call <16 x i8> @llvm.ppc.vsx.xvcvbf16spn(<16 x i8> %3) +!CHECK: store <16 x i8> %4, ptr %1, align 16