Skip to content

Commit f295c88

Browse files
committed
[flang] Add PPC vec_max, vec_min, vec_madd and vec_nmsub intrinsic
Differential Revision: https://reviews.llvm.org/D152938
1 parent 5b82591 commit f295c88

File tree

4 files changed

+696
-2
lines changed

4 files changed

+696
-2
lines changed

flang/include/flang/Optimizer/Builder/IntrinsicCall.h

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,19 @@ enum class ParamTypeId {
481481
Integer,
482482
Real,
483483
Complex,
484+
IntegerVector,
485+
UnsignedVector,
486+
RealVector,
484487
};
485488

489+
// Helper function to get length of a 16-byte vector of element type eleTy.
490+
static int getVecLen(mlir::Type eleTy) {
491+
assert((mlir::isa<mlir::IntegerType>(eleTy) ||
492+
mlir::isa<mlir::FloatType>(eleTy)) &&
493+
"unsupported vector element type");
494+
return 16 / (eleTy.getIntOrFloatBitWidth() / 8);
495+
}
496+
486497
template <ParamTypeId t, int k>
487498
struct ParamType {
488499
// Supported kinds can be checked with static asserts at compile time.
@@ -509,6 +520,12 @@ template <int k>
509520
using Integer = ParamType<ParamTypeId::Integer, k>;
510521
template <int k>
511522
using Complex = ParamType<ParamTypeId::Complex, k>;
523+
template <int k>
524+
using IntegerVector = ParamType<ParamTypeId::IntegerVector, k>;
525+
template <int k>
526+
using RealVector = ParamType<ParamTypeId::RealVector, k>;
527+
template <int k>
528+
using UnsignedVector = ParamType<ParamTypeId::UnsignedVector, k>;
512529
} // namespace Ty
513530

514531
// Helper function that generates most types that are supported for intrinsic
@@ -518,24 +535,46 @@ static inline mlir::Type getTypeHelper(mlir::MLIRContext *context,
518535
fir::FirOpBuilder &builder,
519536
ParamTypeId typeId, int kind) {
520537
mlir::Type r;
521-
int bits = 0;
538+
unsigned bits{0};
522539
switch (typeId) {
523540
case ParamTypeId::Void:
524541
llvm::report_fatal_error("can not get type of void");
525542
break;
526543
case ParamTypeId::Integer:
544+
case ParamTypeId::IntegerVector:
527545
bits = builder.getKindMap().getIntegerBitsize(kind);
528546
assert(bits != 0 && "failed to convert kind to integer bitsize");
529547
r = mlir::IntegerType::get(context, bits);
530548
break;
549+
case ParamTypeId::UnsignedVector:
550+
bits = builder.getKindMap().getIntegerBitsize(kind);
551+
assert(bits != 0 && "failed to convert kind to unsigned bitsize");
552+
r = mlir::IntegerType::get(context, bits, mlir::IntegerType::Unsigned);
553+
break;
531554
case ParamTypeId::Real:
555+
case ParamTypeId::RealVector:
532556
r = builder.getRealType(kind);
533557
break;
534558
case ParamTypeId::Complex:
535559
r = fir::ComplexType::get(context, kind);
536560
break;
537561
}
538-
return r;
562+
563+
switch (typeId) {
564+
case ParamTypeId::Void:
565+
case ParamTypeId::Integer:
566+
case ParamTypeId::Real:
567+
case ParamTypeId::Complex:
568+
// keep original type for void and non-vector
569+
return r;
570+
break;
571+
case ParamTypeId::IntegerVector:
572+
case ParamTypeId::UnsignedVector:
573+
case ParamTypeId::RealVector:
574+
// convert to FIR vector type
575+
return fir::VectorType::get(getVecLen(r), r);
576+
break;
577+
}
539578
}
540579

541580
// Generic function type generator that supports most of the function types

flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,98 @@ static constexpr MathOperation ppcMathOperations[] = {
116116
genLibCall},
117117
{"__ppc_frsqrtes", "llvm.ppc.frsqrtes",
118118
genFuncType<Ty::Real<4>, Ty::Real<4>>, genLibCall},
119+
{"__ppc_vec_madd", "llvm.fma.v4f32",
120+
genFuncType<Ty::RealVector<4>, Ty::RealVector<4>, Ty::RealVector<4>,
121+
Ty::RealVector<4>>,
122+
genLibCall},
123+
{"__ppc_vec_madd", "llvm.fma.v2f64",
124+
genFuncType<Ty::RealVector<8>, Ty::RealVector<8>, Ty::RealVector<8>,
125+
Ty::RealVector<8>>,
126+
genLibCall},
127+
{"__ppc_vec_max", "llvm.ppc.altivec.vmaxsb",
128+
genFuncType<Ty::IntegerVector<1>, Ty::IntegerVector<1>,
129+
Ty::IntegerVector<1>>,
130+
genLibCall},
131+
{"__ppc_vec_max", "llvm.ppc.altivec.vmaxsh",
132+
genFuncType<Ty::IntegerVector<2>, Ty::IntegerVector<2>,
133+
Ty::IntegerVector<2>>,
134+
genLibCall},
135+
{"__ppc_vec_max", "llvm.ppc.altivec.vmaxsw",
136+
genFuncType<Ty::IntegerVector<4>, Ty::IntegerVector<4>,
137+
Ty::IntegerVector<4>>,
138+
genLibCall},
139+
{"__ppc_vec_max", "llvm.ppc.altivec.vmaxsd",
140+
genFuncType<Ty::IntegerVector<8>, Ty::IntegerVector<8>,
141+
Ty::IntegerVector<8>>,
142+
genLibCall},
143+
{"__ppc_vec_max", "llvm.ppc.altivec.vmaxub",
144+
genFuncType<Ty::UnsignedVector<1>, Ty::UnsignedVector<1>,
145+
Ty::UnsignedVector<1>>,
146+
genLibCall},
147+
{"__ppc_vec_max", "llvm.ppc.altivec.vmaxuh",
148+
genFuncType<Ty::UnsignedVector<2>, Ty::UnsignedVector<2>,
149+
Ty::UnsignedVector<2>>,
150+
genLibCall},
151+
{"__ppc_vec_max", "llvm.ppc.altivec.vmaxuw",
152+
genFuncType<Ty::UnsignedVector<4>, Ty::UnsignedVector<4>,
153+
Ty::UnsignedVector<4>>,
154+
genLibCall},
155+
{"__ppc_vec_max", "llvm.ppc.altivec.vmaxud",
156+
genFuncType<Ty::UnsignedVector<8>, Ty::UnsignedVector<8>,
157+
Ty::UnsignedVector<8>>,
158+
genLibCall},
159+
{"__ppc_vec_max", "llvm.ppc.vsx.xvmaxsp",
160+
genFuncType<Ty::RealVector<4>, Ty::RealVector<4>, Ty::RealVector<4>>,
161+
genLibCall},
162+
{"__ppc_vec_max", "llvm.ppc.vsx.xvmaxdp",
163+
genFuncType<Ty::RealVector<8>, Ty::RealVector<8>, Ty::RealVector<8>>,
164+
genLibCall},
165+
{"__ppc_vec_min", "llvm.ppc.altivec.vminsb",
166+
genFuncType<Ty::IntegerVector<1>, Ty::IntegerVector<1>,
167+
Ty::IntegerVector<1>>,
168+
genLibCall},
169+
{"__ppc_vec_min", "llvm.ppc.altivec.vminsh",
170+
genFuncType<Ty::IntegerVector<2>, Ty::IntegerVector<2>,
171+
Ty::IntegerVector<2>>,
172+
genLibCall},
173+
{"__ppc_vec_min", "llvm.ppc.altivec.vminsw",
174+
genFuncType<Ty::IntegerVector<4>, Ty::IntegerVector<4>,
175+
Ty::IntegerVector<4>>,
176+
genLibCall},
177+
{"__ppc_vec_min", "llvm.ppc.altivec.vminsd",
178+
genFuncType<Ty::IntegerVector<8>, Ty::IntegerVector<8>,
179+
Ty::IntegerVector<8>>,
180+
genLibCall},
181+
{"__ppc_vec_min", "llvm.ppc.altivec.vminub",
182+
genFuncType<Ty::UnsignedVector<1>, Ty::UnsignedVector<1>,
183+
Ty::UnsignedVector<1>>,
184+
genLibCall},
185+
{"__ppc_vec_min", "llvm.ppc.altivec.vminuh",
186+
genFuncType<Ty::UnsignedVector<2>, Ty::UnsignedVector<2>,
187+
Ty::UnsignedVector<2>>,
188+
genLibCall},
189+
{"__ppc_vec_min", "llvm.ppc.altivec.vminuw",
190+
genFuncType<Ty::UnsignedVector<4>, Ty::UnsignedVector<4>,
191+
Ty::UnsignedVector<4>>,
192+
genLibCall},
193+
{"__ppc_vec_min", "llvm.ppc.altivec.vminud",
194+
genFuncType<Ty::UnsignedVector<8>, Ty::UnsignedVector<8>,
195+
Ty::UnsignedVector<8>>,
196+
genLibCall},
197+
{"__ppc_vec_min", "llvm.ppc.vsx.xvminsp",
198+
genFuncType<Ty::RealVector<4>, Ty::RealVector<4>, Ty::RealVector<4>>,
199+
genLibCall},
200+
{"__ppc_vec_min", "llvm.ppc.vsx.xvmindp",
201+
genFuncType<Ty::RealVector<8>, Ty::RealVector<8>, Ty::RealVector<8>>,
202+
genLibCall},
203+
{"__ppc_vec_nmsub", "llvm.ppc.fnmsub.v4f32",
204+
genFuncType<Ty::RealVector<4>, Ty::RealVector<4>, Ty::RealVector<4>,
205+
Ty::RealVector<4>>,
206+
genLibCall},
207+
{"__ppc_vec_nmsub", "llvm.ppc.fnmsub.v2f64",
208+
genFuncType<Ty::RealVector<8>, Ty::RealVector<8>, Ty::RealVector<8>,
209+
Ty::RealVector<8>>,
210+
genLibCall},
119211
};
120212

121213
const IntrinsicHandler *findPPCIntrinsicHandler(llvm::StringRef name) {

flang/module/__ppc_intrinsics.f90

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ elemental vector(real(VKIND)) function elem_func_vr##VKIND##vr##VKIND##vr##VKIND
4949
#undef ELEM_FUNC_VUVUVU
5050
#undef ELEM_FUNC_VIVIVI
5151

52+
!! ================ 3 arguments function interface ================
53+
! vector(r) function f(vector(r), vector(r), vector(r))
54+
#define ELEM_FUNC_VRVRVRVR(VKIND) \
55+
elemental vector(real(VKIND)) function elem_func_vr##VKIND##vr##VKIND##vr##VKIND##vr##VKIND(arg1, arg2, arg3); \
56+
vector(real(VKIND)), intent(in) :: arg1, arg2, arg3; \
57+
end function ;
58+
59+
ELEM_FUNC_VRVRVRVR(4) ELEM_FUNC_VRVRVRVR(8)
60+
61+
#undef ELEM_FUNC_VRVRVRVR
62+
5263
end interface
5364

5465
procedure(func_r4r4r4r4) :: __ppc_fmadd_r4
@@ -242,6 +253,28 @@ end function func_r8r8i
242253
end interface vec_and
243254
public :: vec_and
244255

256+
! vec_max
257+
VEC_VI_VI_VI(vec_max,1) VEC_VI_VI_VI(vec_max,2) VEC_VI_VI_VI(vec_max,4) VEC_VI_VI_VI(vec_max,8)
258+
VEC_VU_VU_VU(vec_max,1) VEC_VU_VU_VU(vec_max,2) VEC_VU_VU_VU(vec_max,4) VEC_VU_VU_VU(vec_max,8)
259+
VEC_VR_VR_VR(vec_max,4) VEC_VR_VR_VR(vec_max,8)
260+
interface vec_max
261+
procedure :: VI_VI_VI(vec_max,1), VI_VI_VI(vec_max,2), VI_VI_VI(vec_max,4), VI_VI_VI(vec_max,8)
262+
procedure :: VU_VU_VU(vec_max,1), VU_VU_VU(vec_max,2), VU_VU_VU(vec_max,4), VU_VU_VU(vec_max,8)
263+
procedure :: VR_VR_VR(vec_max,4), VR_VR_VR(vec_max,8)
264+
end interface vec_max
265+
public :: vec_max
266+
267+
! vec_min
268+
VEC_VI_VI_VI(vec_min,1) VEC_VI_VI_VI(vec_min,2) VEC_VI_VI_VI(vec_min,4) VEC_VI_VI_VI(vec_min,8)
269+
VEC_VU_VU_VU(vec_min,1) VEC_VU_VU_VU(vec_min,2) VEC_VU_VU_VU(vec_min,4) VEC_VU_VU_VU(vec_min,8)
270+
VEC_VR_VR_VR(vec_min,4) VEC_VR_VR_VR(vec_min,8)
271+
interface vec_min
272+
procedure :: VI_VI_VI(vec_min,1), VI_VI_VI(vec_min,2), VI_VI_VI(vec_min,4), VI_VI_VI(vec_min,8)
273+
procedure :: VU_VU_VU(vec_min,1), VU_VU_VU(vec_min,2), VU_VU_VU(vec_min,4), VU_VU_VU(vec_min,8)
274+
procedure :: VR_VR_VR(vec_min,4), VR_VR_VR(vec_min,8)
275+
end interface vec_min
276+
public :: vec_min
277+
245278
! vec_mul
246279
VEC_VI_VI_VI(vec_mul,1) VEC_VI_VI_VI(vec_mul,2) VEC_VI_VI_VI(vec_mul,4) VEC_VI_VI_VI(vec_mul,8)
247280
VEC_VU_VU_VU(vec_mul,1) VEC_VU_VU_VU(vec_mul,2) VEC_VU_VU_VU(vec_mul,4) VEC_VU_VU_VU(vec_mul,8)
@@ -281,4 +314,30 @@ end function func_r8r8i
281314
#undef VR_VR_VR
282315
#undef VU_VU_VU
283316
#undef VI_VI_VI
317+
318+
!-----------------------------------------
319+
! vector function(vector, vector, vector)
320+
!-----------------------------------------
321+
#define VR_VR_VR_VR(NAME, VKIND) __ppc_##NAME##_vr##VKIND##vr##VKIND##vr##VKIND##vr##VKIND
322+
323+
#define VEC_VR_VR_VR_VR(NAME, VKIND) \
324+
procedure(elem_func_vr##VKIND##vr##VKIND##vr##VKIND##vr##VKIND) :: VR_VR_VR_VR(NAME, VKIND);
325+
326+
! vec_madd
327+
VEC_VR_VR_VR_VR(vec_madd,4) VEC_VR_VR_VR_VR(vec_madd,8)
328+
interface vec_madd
329+
procedure :: VR_VR_VR_VR(vec_madd,4), VR_VR_VR_VR(vec_madd,8)
330+
end interface vec_madd
331+
public :: vec_madd
332+
333+
! vec_nmsub
334+
VEC_VR_VR_VR_VR(vec_nmsub,4) VEC_VR_VR_VR_VR(vec_nmsub,8)
335+
interface vec_nmsub
336+
procedure :: VR_VR_VR_VR(vec_nmsub,4), VR_VR_VR_VR(vec_nmsub,8)
337+
end interface vec_nmsub
338+
public :: vec_nmsub
339+
340+
#undef VEC_VR_VR_VR_VR
341+
#undef VR_VR_VR_VR
342+
284343
end module __ppc_intrinsics

0 commit comments

Comments
 (0)