[flang-commits] [flang] [flang][NFC] simplify dispatching of reduction runtime calls (PR #110479)

via flang-commits flang-commits at lists.llvm.org
Mon Sep 30 02:43:09 PDT 2024


https://github.com/jeanPerier created https://github.com/llvm/llvm-project/pull/110479

As part of t[he RFC to replace fir.complex usages by mlir complex](https://discourse.llvm.org/t/rfc-flang-replace-usages-of-fir-complex-by-mlir-complex-type/82292), this patch updates the type dispatch in Reduction.cpp to use macros to avoid naming the types everywhere and to avoid typos when copy-pasting the if/else chains.

>From 35e94d9d8b1d4ac78502bfc4234255a1ab40ebb9 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Mon, 30 Sep 2024 02:33:26 -0700
Subject: [PATCH] [flang][NFC] simplify dispatching of reduction runtime calls

---
 flang/include/flang/Optimizer/Support/Utils.h |   4 +
 .../Optimizer/Builder/Runtime/Reduction.cpp   | 618 +++++-------------
 2 files changed, 158 insertions(+), 464 deletions(-)

diff --git a/flang/include/flang/Optimizer/Support/Utils.h b/flang/include/flang/Optimizer/Support/Utils.h
index 02bec4164fca08..06cf9c0be157c3 100644
--- a/flang/include/flang/Optimizer/Support/Utils.h
+++ b/flang/include/flang/Optimizer/Support/Utils.h
@@ -185,6 +185,10 @@ mlirTypeToCategoryKind(mlir::Location loc, mlir::Type type) {
     return {Fortran::common::TypeCategory::Complex, complexType.getFKind()};
   else if (auto logicalType = mlir::dyn_cast<fir::LogicalType>(type))
     return {Fortran::common::TypeCategory::Logical, logicalType.getFKind()};
+  else if (auto charType = mlir::dyn_cast<fir::CharacterType>(type))
+    return {Fortran::common::TypeCategory::Character, charType.getFKind()};
+  else if (mlir::isa<fir::RecordType>(type))
+    return {Fortran::common::TypeCategory::Derived, 0};
   else
     fir::emitFatalError(loc,
                         "unsupported type: " + fir::mlirTypeToString(type));
diff --git a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
index 18eff937278562..b39824428c78a9 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
@@ -120,6 +120,16 @@ struct ForcedMinvalInteger16 {
   }
 };
 
+// Maxloc/Minloc take descriptor, so these runtime signature are not ifdef
+// and the mkRTKey can safely be used here. Define alias so that the
+// REAL_INTRINSIC_INSTANCES macro works with them too
+using ForcedMaxlocReal10 = mkRTKey(MaxlocReal10);
+using ForcedMaxlocReal16 = mkRTKey(MaxlocReal16);
+using ForcedMaxlocInteger16 = mkRTKey(MaxlocInteger16);
+using ForcedMinlocReal10 = mkRTKey(MinlocReal10);
+using ForcedMinlocReal16 = mkRTKey(MinlocReal16);
+using ForcedMinlocInteger16 = mkRTKey(MinlocInteger16);
+
 /// Placeholder for real*10 version of Norm2 Intrinsic
 struct ForcedNorm2Real10 {
   static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Norm2_10));
@@ -468,7 +478,7 @@ struct ForcedIParity16 {
 };
 
 /// Placeholder for real*10 version of Reduce Intrinsic
-struct ForcedReduceReal10 {
+struct ForcedReduceReal10Ref {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(ReduceReal10Ref));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -508,7 +518,7 @@ struct ForcedReduceReal10Value {
 };
 
 /// Placeholder for real*16 version of Reduce Intrinsic
-struct ForcedReduceReal16 {
+struct ForcedReduceReal16Ref {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(ReduceReal16Ref));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -548,7 +558,7 @@ struct ForcedReduceReal16Value {
 };
 
 /// Placeholder for DIM real*10 version of Reduce Intrinsic
-struct ForcedReduceReal10Dim {
+struct ForcedReduceReal10DimRef {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(ReduceReal10DimRef));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -592,7 +602,7 @@ struct ForcedReduceReal10DimValue {
 };
 
 /// Placeholder for DIM real*16 version of Reduce Intrinsic
-struct ForcedReduceReal16Dim {
+struct ForcedReduceReal16DimRef {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(ReduceReal16DimRef));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -636,7 +646,7 @@ struct ForcedReduceReal16DimValue {
 };
 
 /// Placeholder for integer*16 version of Reduce Intrinsic
-struct ForcedReduceInteger16 {
+struct ForcedReduceInteger16Ref {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(ReduceInteger16Ref));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -676,7 +686,7 @@ struct ForcedReduceInteger16Value {
 };
 
 /// Placeholder for DIM integer*16 version of Reduce Intrinsic
-struct ForcedReduceInteger16Dim {
+struct ForcedReduceInteger16DimRef {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(ReduceInteger16DimRef));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -720,7 +730,7 @@ struct ForcedReduceInteger16DimValue {
 };
 
 /// Placeholder for complex(10) version of Reduce Intrinsic
-struct ForcedReduceComplex10 {
+struct ForcedReduceComplex10Ref {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(CppReduceComplex10Ref));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -762,7 +772,7 @@ struct ForcedReduceComplex10Value {
 };
 
 /// Placeholder for Dim complex(10) version of Reduce Intrinsic
-struct ForcedReduceComplex10Dim {
+struct ForcedReduceComplex10DimRef {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(CppReduceComplex10DimRef));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -806,7 +816,7 @@ struct ForcedReduceComplex10DimValue {
 };
 
 /// Placeholder for complex(16) version of Reduce Intrinsic
-struct ForcedReduceComplex16 {
+struct ForcedReduceComplex16Ref {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(CppReduceComplex16Ref));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -848,7 +858,7 @@ struct ForcedReduceComplex16Value {
 };
 
 /// Placeholder for Dim complex(16) version of Reduce Intrinsic
-struct ForcedReduceComplex16Dim {
+struct ForcedReduceComplex16DimRef {
   static constexpr const char *name =
       ExpandAndQuoteKey(RTNAME(CppReduceComplex16DimRef));
   static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
@@ -891,6 +901,63 @@ struct ForcedReduceComplex16DimValue {
   }
 };
 
+#define INTRINSIC_INSTANCE(NAME, CAT, KIND, SUFFIX)                            \
+  if (!func && cat == TypeCategory::CAT && kind == KIND) {                     \
+    func = fir::runtime::getRuntimeFunc<mkRTKey(NAME##CAT##KIND##SUFFIX)>(     \
+        loc, builder);                                                         \
+  }
+#define FORCED_INTRINSIC_INSTANCE(NAME, CAT, KIND, SUFFIX)                     \
+  if (!func && cat == TypeCategory::CAT && kind == KIND) {                     \
+    func = fir::runtime::getRuntimeFunc<Forced##NAME##CAT##KIND##SUFFIX>(      \
+        loc, builder);                                                         \
+  }
+
+#define INTEGER_INTRINSIC_INSTANCES(NAME, SUFFIX)                              \
+  INTRINSIC_INSTANCE(NAME, Integer, 1, SUFFIX)                                 \
+  INTRINSIC_INSTANCE(NAME, Integer, 2, SUFFIX)                                 \
+  INTRINSIC_INSTANCE(NAME, Integer, 4, SUFFIX)                                 \
+  INTRINSIC_INSTANCE(NAME, Integer, 8, SUFFIX)                                 \
+  FORCED_INTRINSIC_INSTANCE(NAME, Integer, 16, SUFFIX)
+
+#define REAL_INTRINSIC_INSTANCES(NAME, SUFFIX)                                 \
+  INTRINSIC_INSTANCE(NAME, Real, 4, SUFFIX)                                    \
+  INTRINSIC_INSTANCE(NAME, Real, 8, SUFFIX)                                    \
+  FORCED_INTRINSIC_INSTANCE(NAME, Real, 10, SUFFIX)                            \
+  FORCED_INTRINSIC_INSTANCE(NAME, Real, 16, SUFFIX)
+
+#define COMPLEX_INTRINSIC_INSTANCES(NAME, SUFFIX)                              \
+  INTRINSIC_INSTANCE(Cpp##NAME, Complex, 4, SUFFIX)                            \
+  INTRINSIC_INSTANCE(Cpp##NAME, Complex, 8, SUFFIX)                            \
+  FORCED_INTRINSIC_INSTANCE(NAME, Complex, 10, SUFFIX)                         \
+  FORCED_INTRINSIC_INSTANCE(NAME, Complex, 16, SUFFIX)
+
+#define NUMERICAL_INTRINSIC_INSTANCES(NAME)                                    \
+  INTEGER_INTRINSIC_INSTANCES(NAME, )                                          \
+  REAL_INTRINSIC_INSTANCES(NAME, )                                             \
+  COMPLEX_INTRINSIC_INSTANCES(NAME, )
+
+#define LOGICAL_INTRINSIC_INSTANCES(NAME, SUFFIX)                              \
+  INTRINSIC_INSTANCE(NAME, Logical, 1, SUFFIX)                                 \
+  INTRINSIC_INSTANCE(NAME, Logical, 2, SUFFIX)                                 \
+  INTRINSIC_INSTANCE(NAME, Logical, 4, SUFFIX)                                 \
+  INTRINSIC_INSTANCE(NAME, Logical, 8, SUFFIX)
+
+#define NUMERICAL_AND_LOGICAL_INSTANCES(NAME, SUFFIX)                          \
+  INTEGER_INTRINSIC_INSTANCES(NAME, SUFFIX)                                    \
+  REAL_INTRINSIC_INSTANCES(NAME, SUFFIX)                                       \
+  COMPLEX_INTRINSIC_INSTANCES(NAME, SUFFIX)                                    \
+  LOGICAL_INTRINSIC_INSTANCES(NAME, SUFFIX)
+
+// REAL/COMPLEX 2 and 3 usually have no runtime implementation, so they have
+// special macros.
+#define REAL_2_3_INTRINSIC_INSTANCES(NAME, SUFFIX)                             \
+  INTRINSIC_INSTANCE(NAME, Real, 2, SUFFIX)                                    \
+  INTRINSIC_INSTANCE(NAME, Real, 3, SUFFIX)
+
+#define COMPLEX_2_3_INTRINSIC_INSTANCES(NAME, SUFFIX)                          \
+  INTRINSIC_INSTANCE(Cpp##NAME, Complex, 2, SUFFIX)                            \
+  INTRINSIC_INSTANCE(Cpp##NAME, Complex, 3, SUFFIX)
+
 /// Generate call to specialized runtime function that takes a mask and
 /// dim argument. The All, Any, and Count intrinsics use this pattern.
 template <typename FN>
@@ -1086,36 +1153,21 @@ void fir::runtime::genFindlocDim(fir::FirOpBuilder &builder, mlir::Location loc,
 /// that does not take a dim argument.
 void fir::runtime::genMaxloc(fir::FirOpBuilder &builder, mlir::Location loc,
                              mlir::Value resultBox, mlir::Value arrayBox,
-                             mlir::Value maskBox, mlir::Value kind,
+                             mlir::Value maskBox, mlir::Value kindVal,
                              mlir::Value back) {
-  mlir::func::FuncOp func;
   auto ty = arrayBox.getType();
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
   fir::factory::CharacterExprHelper charHelper{builder, loc};
-  if (eleTy.isF32())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocReal4)>(loc, builder);
-  else if (eleTy.isF64())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocReal8)>(loc, builder);
-  else if (eleTy.isF80())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocReal10)>(loc, builder);
-  else if (eleTy.isF128())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocReal16)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocInteger1)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocInteger2)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocInteger4)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocInteger8)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocInteger16)>(loc, builder);
-  else if (charHelper.isCharacterScalar(eleTy))
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
+  mlir::func::FuncOp func;
+  REAL_INTRINSIC_INSTANCES(Maxloc, )
+  INTEGER_INTRINSIC_INSTANCES(Maxloc, )
+  if (charHelper.isCharacterScalar(eleTy))
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocCharacter)>(loc, builder);
-  else
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXLOC");
-  genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kind,
+  genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kindVal,
                     back);
 }
 
@@ -1135,31 +1187,15 @@ void fir::runtime::genMaxlocDim(fir::FirOpBuilder &builder, mlir::Location loc,
 mlir::Value fir::runtime::genMaxval(fir::FirOpBuilder &builder,
                                     mlir::Location loc, mlir::Value arrayBox,
                                     mlir::Value maskBox) {
-  mlir::func::FuncOp func;
   auto ty = arrayBox.getType();
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
-
-  if (eleTy.isF32())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalReal4)>(loc, builder);
-  else if (eleTy.isF64())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalReal8)>(loc, builder);
-  else if (eleTy.isF80())
-    func = fir::runtime::getRuntimeFunc<ForcedMaxvalReal10>(loc, builder);
-  else if (eleTy.isF128())
-    func = fir::runtime::getRuntimeFunc<ForcedMaxvalReal16>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalInteger1)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalInteger2)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalInteger4)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalInteger8)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
-    func = fir::runtime::getRuntimeFunc<ForcedMaxvalInteger16>(loc, builder);
-  else
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
+  mlir::func::FuncOp func;
+  REAL_INTRINSIC_INSTANCES(Maxval, )
+  INTEGER_INTRINSIC_INSTANCES(Maxval, )
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXVAL");
 
   auto fTy = func.getFunctionType();
@@ -1201,36 +1237,21 @@ void fir::runtime::genMaxvalChar(fir::FirOpBuilder &builder, mlir::Location loc,
 /// that does not take a dim argument.
 void fir::runtime::genMinloc(fir::FirOpBuilder &builder, mlir::Location loc,
                              mlir::Value resultBox, mlir::Value arrayBox,
-                             mlir::Value maskBox, mlir::Value kind,
+                             mlir::Value maskBox, mlir::Value kindVal,
                              mlir::Value back) {
-  mlir::func::FuncOp func;
   auto ty = arrayBox.getType();
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
+  mlir::func::FuncOp func;
+  REAL_INTRINSIC_INSTANCES(Minloc, )
+  INTEGER_INTRINSIC_INSTANCES(Minloc, )
   fir::factory::CharacterExprHelper charHelper{builder, loc};
-  if (eleTy.isF32())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocReal4)>(loc, builder);
-  else if (eleTy.isF64())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocReal8)>(loc, builder);
-  else if (eleTy.isF80())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocReal10)>(loc, builder);
-  else if (eleTy.isF128())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocReal16)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocInteger1)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocInteger2)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocInteger4)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocInteger8)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocInteger16)>(loc, builder);
-  else if (charHelper.isCharacterScalar(eleTy))
+  if (charHelper.isCharacterScalar(eleTy))
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocCharacter)>(loc, builder);
-  else
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "MINLOC");
-  genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kind,
+  genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kindVal,
                     back);
 }
 
@@ -1275,31 +1296,16 @@ void fir::runtime::genMinvalChar(fir::FirOpBuilder &builder, mlir::Location loc,
 mlir::Value fir::runtime::genMinval(fir::FirOpBuilder &builder,
                                     mlir::Location loc, mlir::Value arrayBox,
                                     mlir::Value maskBox) {
-  mlir::func::FuncOp func;
   auto ty = arrayBox.getType();
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
 
-  if (eleTy.isF32())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalReal4)>(loc, builder);
-  else if (eleTy.isF64())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalReal8)>(loc, builder);
-  else if (eleTy.isF80())
-    func = fir::runtime::getRuntimeFunc<ForcedMinvalReal10>(loc, builder);
-  else if (eleTy.isF128())
-    func = fir::runtime::getRuntimeFunc<ForcedMinvalReal16>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalInteger1)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalInteger2)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalInteger4)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalInteger8)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
-    func = fir::runtime::getRuntimeFunc<ForcedMinvalInteger16>(loc, builder);
-  else
+  mlir::func::FuncOp func;
+  REAL_INTRINSIC_INSTANCES(Minval, )
+  INTEGER_INTRINSIC_INSTANCES(Minval, )
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "MINVAL");
 
   auto fTy = func.getFunctionType();
@@ -1390,41 +1396,15 @@ mlir::Value fir::runtime::genProduct(fir::FirOpBuilder &builder,
                                      mlir::Location loc, mlir::Value arrayBox,
                                      mlir::Value maskBox,
                                      mlir::Value resultBox) {
-  mlir::func::FuncOp func;
   auto ty = arrayBox.getType();
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF32())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ProductReal4)>(loc, builder);
-  else if (eleTy.isF64())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ProductReal8)>(loc, builder);
-  else if (eleTy.isF80())
-    func = fir::runtime::getRuntimeFunc<ForcedProductReal10>(loc, builder);
-  else if (eleTy.isF128())
-    func = fir::runtime::getRuntimeFunc<ForcedProductReal16>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ProductInteger1)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ProductInteger2)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ProductInteger4)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ProductInteger8)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
-    func = fir::runtime::getRuntimeFunc<ForcedProductInteger16>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 4))
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(CppProductComplex4)>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 8))
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(CppProductComplex8)>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 10))
-    func = fir::runtime::getRuntimeFunc<ForcedProductComplex10>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 16))
-    func = fir::runtime::getRuntimeFunc<ForcedProductComplex16>(loc, builder);
-  else
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
+  mlir::func::FuncOp func;
+  NUMERICAL_INTRINSIC_INSTANCES(Product)
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "PRODUCT");
 
   auto fTy = func.getFunctionType();
@@ -1453,51 +1433,18 @@ mlir::Value fir::runtime::genDotProduct(fir::FirOpBuilder &builder,
                                         mlir::Value vectorABox,
                                         mlir::Value vectorBBox,
                                         mlir::Value resultBox) {
-  mlir::func::FuncOp func;
   // For complex data types, resultBox is !fir.ref<!fir.complex<N>>,
   // otherwise it is !fir.box<T>.
   auto ty = resultBox.getType();
   auto eleTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
 
-  if (eleTy.isF32())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(DotProductReal4)>(loc, builder);
-  else if (eleTy.isF64())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(DotProductReal8)>(loc, builder);
-  else if (eleTy.isF80())
-    func = fir::runtime::getRuntimeFunc<ForcedDotProductReal10>(loc, builder);
-  else if (eleTy.isF128())
-    func = fir::runtime::getRuntimeFunc<ForcedDotProductReal16>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 4))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppDotProductComplex4)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 8))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppDotProductComplex8)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 10))
-    func =
-        fir::runtime::getRuntimeFunc<ForcedDotProductComplex10>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 16))
-    func =
-        fir::runtime::getRuntimeFunc<ForcedDotProductComplex16>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)))
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(DotProductInteger1)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)))
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(DotProductInteger2)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)))
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(DotProductInteger4)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)))
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(DotProductInteger8)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
-    func =
-        fir::runtime::getRuntimeFunc<ForcedDotProductInteger16>(loc, builder);
-  else if (mlir::isa<fir::LogicalType>(eleTy))
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
+  mlir::func::FuncOp func;
+  NUMERICAL_INTRINSIC_INSTANCES(DotProduct)
+  if (cat == Fortran::common::TypeCategory::Logical)
     func =
         fir::runtime::getRuntimeFunc<mkRTKey(DotProductLogical)>(loc, builder);
-  else
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "DOTPRODUCT");
 
   auto fTy = func.getFunctionType();
@@ -1533,39 +1480,15 @@ void fir::runtime::genSumDim(fir::FirOpBuilder &builder, mlir::Location loc,
 mlir::Value fir::runtime::genSum(fir::FirOpBuilder &builder, mlir::Location loc,
                                  mlir::Value arrayBox, mlir::Value maskBox,
                                  mlir::Value resultBox) {
-  mlir::func::FuncOp func;
   auto ty = arrayBox.getType();
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF32())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(SumReal4)>(loc, builder);
-  else if (eleTy.isF64())
-    func = fir::runtime::getRuntimeFunc<mkRTKey(SumReal8)>(loc, builder);
-  else if (eleTy.isF80())
-    func = fir::runtime::getRuntimeFunc<ForcedSumReal10>(loc, builder);
-  else if (eleTy.isF128())
-    func = fir::runtime::getRuntimeFunc<ForcedSumReal16>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(SumInteger1)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(SumInteger2)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(SumInteger4)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(SumInteger8)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
-    func = fir::runtime::getRuntimeFunc<ForcedSumInteger16>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 4))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppSumComplex4)>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 8))
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppSumComplex8)>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 10))
-    func = fir::runtime::getRuntimeFunc<ForcedSumComplex10>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(builder.getContext(), 16))
-    func = fir::runtime::getRuntimeFunc<ForcedSumComplex16>(loc, builder);
-  else
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
+  mlir::func::FuncOp func;
+  NUMERICAL_INTRINSIC_INSTANCES(Sum)
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "SUM");
 
   auto fTy = func.getFunctionType();
@@ -1671,7 +1594,6 @@ void fir::runtime::genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
                              mlir::Value maskBox, mlir::Value identity,
                              mlir::Value ordered, mlir::Value resultBox,
                              bool argByRef) {
-  mlir::func::FuncOp func;
   auto ty = arrayBox.getType();
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
@@ -1682,44 +1604,17 @@ void fir::runtime::genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
           fir::isa_derived(eleTy)) &&
          "expect character, complex or derived-type");
 
-  mlir::MLIRContext *ctx = builder.getContext();
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
+  mlir::func::FuncOp func;
+  if (argByRef) {
+    COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, Ref)
+    COMPLEX_INTRINSIC_INSTANCES(Reduce, Ref)
+  } else {
+    COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, Value)
+    COMPLEX_INTRINSIC_INSTANCES(Reduce, Value)
+  }
   fir::factory::CharacterExprHelper charHelper{builder, loc};
-
-  if (eleTy == fir::ComplexType::get(ctx, 2) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2Ref)>(loc,
-                                                                       builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 2) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2Value)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 3) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3Ref)>(loc,
-                                                                       builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 3) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3Value)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 4) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4Ref)>(loc,
-                                                                       builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 4) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4Value)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 8) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8Ref)>(loc,
-                                                                       builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 8) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8Value)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 10) && argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceComplex10>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 10) && !argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<ForcedReduceComplex10Value>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 16) && argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceComplex16>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 16) && !argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<ForcedReduceComplex16Value>(loc, builder);
-  else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
+  if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
     func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar1)>(loc, builder);
   else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)
     func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar2)>(loc, builder);
@@ -1728,7 +1623,7 @@ void fir::runtime::genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
   else if (fir::isa_derived(eleTy))
     func =
         fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedType)>(loc, builder);
-  else
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
 
   auto fTy = func.getFunctionType();
@@ -1749,111 +1644,29 @@ mlir::Value fir::runtime::genReduce(fir::FirOpBuilder &builder,
                                     mlir::Value operation, mlir::Value maskBox,
                                     mlir::Value identity, mlir::Value ordered,
                                     bool argByRef) {
-  mlir::func::FuncOp func;
   auto ty = arrayBox.getType();
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getI32Type(), 1);
 
-  mlir::MLIRContext *ctx = builder.getContext();
-  fir::factory::CharacterExprHelper charHelper{builder, loc};
-
   assert((fir::isa_real(eleTy) || fir::isa_integer(eleTy) ||
           mlir::isa<fir::LogicalType>(eleTy)) &&
          "expect real, interger or logical");
 
-  if (eleTy.isF16() && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal2Ref)>(loc, builder);
-  else if (eleTy.isF16() && !argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal2Value)>(loc, builder);
-  else if (eleTy.isBF16() && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal3Ref)>(loc, builder);
-  else if (eleTy.isBF16() && !argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal3Value)>(loc, builder);
-  else if (eleTy.isF32() && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal4Ref)>(loc, builder);
-  else if (eleTy.isF32() && !argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal4Value)>(loc, builder);
-  else if (eleTy.isF64() && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal8Ref)>(loc, builder);
-  else if (eleTy.isF64() && !argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal8Value)>(loc, builder);
-  else if (eleTy.isF80() && argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceReal10>(loc, builder);
-  else if (eleTy.isF80() && !argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceReal10Value>(loc, builder);
-  else if (eleTy.isF128() && argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceReal16>(loc, builder);
-  else if (eleTy.isF128() && !argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceReal16Value>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)) &&
-           argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger1Ref)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)) &&
-           !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger1Value)>(loc,
-                                                                      builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)) &&
-           argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger2Ref)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)) &&
-           !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger2Value)>(loc,
-                                                                      builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)) &&
-           argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger4Ref)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)) &&
-           !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger4Value)>(loc,
-                                                                      builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)) &&
-           argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger8Ref)>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)) &&
-           !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger8Value)>(loc,
-                                                                      builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)) &&
-           argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceInteger16>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)) &&
-           !argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<ForcedReduceInteger16Value>(loc, builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 1) && argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical1Ref)>(loc, builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 1) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical1Value)>(loc,
-                                                                      builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 2) && argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical2Ref)>(loc, builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 2) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical2Value)>(loc,
-                                                                      builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 4) && argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical4Ref)>(loc, builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 4) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical4Value)>(loc,
-                                                                      builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 8) && argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical8Ref)>(loc, builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 8) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical8Value)>(loc,
-                                                                      builder);
-  else
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
+  mlir::func::FuncOp func;
+  if (argByRef) {
+    REAL_2_3_INTRINSIC_INSTANCES(Reduce, Ref)
+    REAL_INTRINSIC_INSTANCES(Reduce, Ref)
+    INTEGER_INTRINSIC_INSTANCES(Reduce, Ref)
+    LOGICAL_INTRINSIC_INSTANCES(Reduce, Ref)
+  } else {
+    REAL_2_3_INTRINSIC_INSTANCES(Reduce, Value)
+    REAL_INTRINSIC_INSTANCES(Reduce, Value)
+    INTEGER_INTRINSIC_INSTANCES(Reduce, Value)
+    LOGICAL_INTRINSIC_INSTANCES(Reduce, Value)
+  }
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
 
   auto fTy = func.getFunctionType();
@@ -1872,146 +1685,23 @@ void fir::runtime::genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc,
                                 mlir::Value dim, mlir::Value maskBox,
                                 mlir::Value identity, mlir::Value ordered,
                                 mlir::Value resultBox, bool argByRef) {
-  mlir::func::FuncOp func;
   auto ty = arrayBox.getType();
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
+  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
 
-  mlir::MLIRContext *ctx = builder.getContext();
+  mlir::func::FuncOp func;
+  if (argByRef) {
+    REAL_2_3_INTRINSIC_INSTANCES(Reduce, DimRef)
+    COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, DimRef)
+    NUMERICAL_AND_LOGICAL_INSTANCES(Reduce, DimRef)
+  } else {
+    REAL_2_3_INTRINSIC_INSTANCES(Reduce, DimValue)
+    COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, DimValue)
+    NUMERICAL_AND_LOGICAL_INSTANCES(Reduce, DimValue)
+  }
   fir::factory::CharacterExprHelper charHelper{builder, loc};
-
-  if (eleTy.isF16() && argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal2DimRef)>(loc, builder);
-  else if (eleTy.isF16() && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal2DimValue)>(loc,
-                                                                      builder);
-  else if (eleTy.isBF16() && argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal3DimRef)>(loc, builder);
-  else if (eleTy.isBF16() && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal3DimValue)>(loc,
-                                                                      builder);
-  else if (eleTy.isF32() && argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal4DimRef)>(loc, builder);
-  else if (eleTy.isF32() && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal4DimValue)>(loc,
-                                                                      builder);
-  else if (eleTy.isF64() && argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal8DimRef)>(loc, builder);
-  else if (eleTy.isF64() && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal8DimValue)>(loc,
-                                                                      builder);
-  else if (eleTy.isF80() && argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceReal10Dim>(loc, builder);
-  else if (eleTy.isF80() && !argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<ForcedReduceReal10DimValue>(loc, builder);
-  else if (eleTy.isF128() && argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceReal16Dim>(loc, builder);
-  else if (eleTy.isF128() && !argByRef)
-    func =
-        fir::runtime::getRuntimeFunc<ForcedReduceReal16DimValue>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)) &&
-           argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger1DimRef)>(loc,
-                                                                       builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)) &&
-           !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger1DimValue)>(
-        loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)) &&
-           argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger2DimRef)>(loc,
-                                                                       builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)) &&
-           !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger2DimValue)>(
-        loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)) &&
-           argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger4DimRef)>(loc,
-                                                                       builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)) &&
-           !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger4DimValue)>(
-        loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)) &&
-           argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger8DimRef)>(loc,
-                                                                       builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)) &&
-           !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger8DimValue)>(
-        loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)) &&
-           argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceInteger16Dim>(loc, builder);
-  else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)) &&
-           !argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceInteger16DimValue>(loc,
-                                                                       builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 2) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2DimRef)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 2) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2DimValue)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 3) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3DimRef)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 3) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3DimValue)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 4) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4DimRef)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 4) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4DimValue)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 8) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8DimRef)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 8) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8DimValue)>(
-        loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 10) && argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceComplex10Dim>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 10) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceComplex10DimValue>(loc,
-                                                                       builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 16) && argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceComplex16Dim>(loc, builder);
-  else if (eleTy == fir::ComplexType::get(ctx, 16) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<ForcedReduceComplex16DimValue>(loc,
-                                                                       builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 1) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical1DimRef)>(loc,
-                                                                       builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 1) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical1DimValue)>(
-        loc, builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 2) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical2DimRef)>(loc,
-                                                                       builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 2) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical2DimValue)>(
-        loc, builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 4) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical4DimRef)>(loc,
-                                                                       builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 4) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical4DimValue)>(
-        loc, builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 8) && argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical8DimRef)>(loc,
-                                                                       builder);
-  else if (eleTy == fir::LogicalType::get(ctx, 8) && !argByRef)
-    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical8DimValue)>(
-        loc, builder);
-  else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
+  if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
     func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter1Dim)>(loc,
                                                                       builder);
   else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)
@@ -2023,7 +1713,7 @@ void fir::runtime::genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc,
   else if (fir::isa_derived(eleTy))
     func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedTypeDim)>(loc,
                                                                        builder);
-  else
+  if (!func)
     fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
 
   auto fTy = func.getFunctionType();



More information about the flang-commits mailing list