Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flang] Cleanup of NYI messages #73740

Merged
merged 2 commits into from
Nov 29, 2023
Merged

[flang] Cleanup of NYI messages #73740

merged 2 commits into from
Nov 29, 2023

Conversation

psteinfeld
Copy link
Contributor

This update makes the user visible messages relating to features that are not yet implemented be more consistent. I also cleaned up some of the code.

For NYI messages that refer to intrinsics, I made sure the the message begins with "not yet implemented: intrinsic:" to make them easier to recognize.

I created some utility functions for NYI reporting that I put into .../include/Optimizer/Support/Utils.h. These mainly convert MLIR types to their Fortran equivalents.

I converted the NYI code to use the newly created utility functions.

This update makes the user visible messages relating to features that
are not yet implemented be more consistent.  I also cleaned up some of
the code.

For NYI messages that refer to intrinsics, I made sure the the message
begins with "not yet implemented: intrinsic:" to make them easier to
recognize.

I created some utility functions for NYI reporting that I put into
.../include/Optimizer/Support/Utils.h.  These mainly convert MLIR types to
their Fortran equivalents.

I converted the NYI code to use the newly created utility functions.
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 29, 2023

@llvm/pr-subscribers-flang-fir-hlfir

@llvm/pr-subscribers-flang-runtime

Author: Pete Steinfeld (psteinfeld)

Changes

This update makes the user visible messages relating to features that are not yet implemented be more consistent. I also cleaned up some of the code.

For NYI messages that refer to intrinsics, I made sure the the message begins with "not yet implemented: intrinsic:" to make them easier to recognize.

I created some utility functions for NYI reporting that I put into .../include/Optimizer/Support/Utils.h. These mainly convert MLIR types to their Fortran equivalents.

I converted the NYI code to use the newly created utility functions.


Patch is 42.96 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73740.diff

12 Files Affected:

  • (modified) flang/include/flang/Optimizer/Support/Utils.h (+63)
  • (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+16-9)
  • (modified) flang/lib/Optimizer/Builder/Runtime/Numeric.cpp (+17-34)
  • (modified) flang/lib/Optimizer/Builder/Runtime/Reduction.cpp (+17-42)
  • (modified) flang/lib/Optimizer/Builder/Runtime/Transformational.cpp (+9-17)
  • (modified) flang/lib/Optimizer/CodeGen/Target.cpp (+27-13)
  • (modified) flang/runtime/character.cpp (+5-2)
  • (modified) flang/runtime/descriptor-io.h (+15-19)
  • (modified) flang/runtime/random.cpp (+14-10)
  • (modified) flang/runtime/tools.cpp (+2-2)
  • (modified) flang/runtime/transformational.cpp (+2-1)
  • (modified) flang/test/Lower/Intrinsics/missing-math-runtime.f90 (+1-1)
diff --git a/flang/include/flang/Optimizer/Support/Utils.h b/flang/include/flang/Optimizer/Support/Utils.h
index d5b045924f3c0cb..34c8e79173bcd41 100644
--- a/flang/include/flang/Optimizer/Support/Utils.h
+++ b/flang/include/flang/Optimizer/Support/Utils.h
@@ -14,8 +14,11 @@
 #define FORTRAN_OPTIMIZER_SUPPORT_UTILS_H
 
 #include "flang/Common/default-kinds.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/Todo.h"
 #include "flang/Optimizer/Dialect/FIROps.h"
 #include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Support/FatalError.h"
 #include "mlir/Dialect/Arith/IR/Arith.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/IR/BuiltinAttributes.h"
@@ -70,6 +73,66 @@ fromDefaultKinds(const Fortran::common::IntrinsicTypeDefaultKinds &defKinds) {
           static_cast<fir::KindTy>(
               defKinds.GetDefaultKind(Fortran::common::TypeCategory::Real))};
 }
+
+inline std::string mlirTypeToString(mlir::Type type) {
+  std::string result{};
+  llvm::raw_string_ostream sstream(result);
+  sstream << type;
+  return result;
+}
+
+inline std::string numericMlirTypeToFortran(fir::FirOpBuilder &builder,
+                                            mlir::Type type, mlir::Location loc,
+                                            const llvm::Twine &name) {
+  if (type.isF16())
+    return "REAL(KIND=2)";
+  else if (type.isBF16())
+    return "REAL(KIND=3)";
+  else if (type.isTF32())
+    return "REAL(KIND=unknown)";
+  else if (type.isF32())
+    return "REAL(KIND=4)";
+  else if (type.isF64())
+    return "REAL(KIND=8)";
+  else if (type.isF80())
+    return "REAL(KIND=10)";
+  else if (type.isF128())
+    return "REAL(KIND=16)";
+  else if (type.isInteger(8))
+    return "INTEGER(KIND=1)";
+  else if (type.isInteger(16))
+    return "INTEGER(KIND=2)";
+  else if (type.isInteger(32))
+    return "INTEGER(KIND=4)";
+  else if (type.isInteger(64))
+    return "INTEGER(KIND=8)";
+  else if (type.isInteger(128))
+    return "INTEGER(KIND=16)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 2))
+    return "COMPLEX(KIND=2)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 3))
+    return "COMPLEX(KIND=3)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 4))
+    return "COMPLEX(KIND=4)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 8))
+    return "COMPLEX(KIND=8)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 10))
+    return "COMPLEX(KIND=10)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 16))
+    return "COMPLEX(KIND=16)";
+  else
+    fir::emitFatalError(loc, "unsupported type in " + name + ": " +
+                                 fir::mlirTypeToString(type));
+}
+
+inline void intrinsicTypeTODO(fir::FirOpBuilder &builder, mlir::Type type,
+                              mlir::Location loc,
+                              const llvm::Twine &intrinsicName) {
+  TODO(loc,
+       "intrinsic: " +
+           fir::numericMlirTypeToFortran(builder, type, loc, intrinsicName) +
+           " in " + intrinsicName);
+}
 } // namespace fir
 
 #endif // FORTRAN_OPTIMIZER_SUPPORT_UTILS_H
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 24fdbe97856b3ab..9d9093861041ff3 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -1235,7 +1235,7 @@ searchMathOperation(fir::FirOpBuilder &builder, llvm::StringRef name,
 static void checkPrecisionLoss(llvm::StringRef name,
                                mlir::FunctionType funcType,
                                const FunctionDistance &distance,
-                               mlir::Location loc) {
+                               fir::FirOpBuilder &builder, mlir::Location loc) {
   if (!distance.isLosingPrecision())
     return;
 
@@ -1249,13 +1249,20 @@ static void checkPrecisionLoss(llvm::StringRef name,
   llvm::raw_string_ostream sstream(message);
   if (name == "pow") {
     assert(funcType.getNumInputs() == 2 && "power operator has two arguments");
-    sstream << funcType.getInput(0) << " ** " << funcType.getInput(1);
+    std::string displayName{" ** "};
+    sstream << numericMlirTypeToFortran(builder, funcType.getInput(0), loc,
+                                        displayName)
+            << displayName
+            << numericMlirTypeToFortran(builder, funcType.getInput(1), loc,
+                                        displayName);
   } else {
-    sstream << name << "(";
+    sstream << name.upper() << "(";
     if (funcType.getNumInputs() > 0)
-      sstream << funcType.getInput(0);
-    for (mlir::Type argType : funcType.getInputs().drop_front())
-      sstream << ", " << argType;
+      sstream << numericMlirTypeToFortran(builder, funcType.getInput(0), loc,
+                                          name);
+    for (mlir::Type argType : funcType.getInputs().drop_front()) {
+      sstream << ", " << numericMlirTypeToFortran(builder, argType, loc, name);
+    }
     sstream << ")";
   }
   sstream << "'";
@@ -1373,7 +1380,7 @@ void crashOnMissingIntrinsic(mlir::Location loc, llvm::StringRef name) {
   else if (isCoarrayIntrinsic(name))
     TODO(loc, "coarray: intrinsic " + llvm::Twine(name));
   else
-    TODO(loc, "intrinsic: " + llvm::Twine(name));
+    TODO(loc, "intrinsic: " + llvm::Twine(name.upper()));
 }
 
 template <typename GeneratorType>
@@ -1756,7 +1763,7 @@ IntrinsicLibrary::getRuntimeCallGenerator(llvm::StringRef name,
   if (!mathOp && bestNearMatch) {
     // Use the best near match, optionally issuing an error,
     // if types conversions cause precision loss.
-    checkPrecisionLoss(name, soughtFuncType, bestMatchDistance, loc);
+    checkPrecisionLoss(name, soughtFuncType, bestMatchDistance, builder, loc);
     mathOp = bestNearMatch;
   }
 
@@ -4344,7 +4351,7 @@ mlir::Value IntrinsicLibrary::genModulo(mlir::Type resultType,
   // Real case
   if (resultType == mlir::FloatType::getF128(builder.getContext()))
 
-    TODO(loc, "intrinsic: modulo for floating point of KIND=16");
+    TODO(loc, "REAL(KIND=16): in MODULO intrinsic");
   auto remainder = builder.create<mlir::arith::RemFOp>(loc, args[0], args[1]);
   mlir::Value zero = builder.createRealZeroConstant(loc, remainder.getType());
   auto remainderIsNotZero = builder.create<mlir::arith::CmpFOp>(
diff --git a/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp b/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
index cb4035d53d5b59f..b958a30eb6e5b55 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
@@ -11,7 +11,7 @@
 #include "flang/Optimizer/Builder/Character.h"
 #include "flang/Optimizer/Builder/FIRBuilder.h"
 #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
-#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Support/Utils.h"
 #include "flang/Runtime/numeric.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 
@@ -240,10 +240,7 @@ mlir::Value fir::runtime::genExponent(fir::FirOpBuilder &builder,
                                       mlir::Value x) {
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
-
-  if (fltTy.isF16()) {
-    TODO(loc, "support for REAL with KIND = 2 in EXPONENT");
-  } else if (fltTy.isF32()) {
+  if (fltTy.isF32()) {
     if (resultType.isInteger(32))
       func = fir::runtime::getRuntimeFunc<mkRTKey(Exponent4_4)>(loc, builder);
     else if (resultType.isInteger(64))
@@ -264,7 +261,7 @@ mlir::Value fir::runtime::genExponent(fir::FirOpBuilder &builder,
     else if (resultType.isInteger(64))
       func = fir::runtime::getRuntimeFunc<ForcedExponent16_8>(loc, builder);
   } else
-    fir::emitFatalError(loc, "unsupported REAL kind in EXPONENT");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "EXPONENT");
 
   auto funcTy = func.getFunctionType();
   llvm::SmallVector<mlir::Value> args = {
@@ -278,9 +275,7 @@ mlir::Value fir::runtime::genFraction(fir::FirOpBuilder &builder,
                                       mlir::Location loc, mlir::Value x) {
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in FRACTION");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Fraction4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Fraction8)>(loc, builder);
@@ -289,7 +284,7 @@ mlir::Value fir::runtime::genFraction(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedFraction16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in FRACTION");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "FRACTION");
 
   auto funcTy = func.getFunctionType();
   llvm::SmallVector<mlir::Value> args = {
@@ -307,9 +302,7 @@ mlir::Value fir::runtime::genMod(fir::FirOpBuilder &builder, mlir::Location loc,
   if (fltTy != p.getType())
     fir::emitFatalError(loc, "arguments type mismatch in MOD");
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in MOD");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(ModReal4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(ModReal8)>(loc, builder);
@@ -318,7 +311,7 @@ mlir::Value fir::runtime::genMod(fir::FirOpBuilder &builder, mlir::Location loc,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedMod16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in MOD");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "MOD");
 
   auto funcTy = func.getFunctionType();
   auto sourceFile = fir::factory::locationToFilename(builder, loc);
@@ -337,9 +330,7 @@ mlir::Value fir::runtime::genNearest(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in NEAREST");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Nearest4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Nearest8)>(loc, builder);
@@ -348,7 +339,7 @@ mlir::Value fir::runtime::genNearest(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedNearest16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in NEAREST");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "NEAREST");
 
   auto funcTy = func.getFunctionType();
 
@@ -374,9 +365,7 @@ mlir::Value fir::runtime::genRRSpacing(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in RRSPACING");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(RRSpacing4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(RRSpacing8)>(loc, builder);
@@ -385,7 +374,7 @@ mlir::Value fir::runtime::genRRSpacing(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedRRSpacing16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in RRSPACING");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "RRSPACING");
 
   auto funcTy = func.getFunctionType();
   llvm::SmallVector<mlir::Value> args = {
@@ -401,9 +390,7 @@ mlir::Value fir::runtime::genScale(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in SCALE");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Scale4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Scale8)>(loc, builder);
@@ -412,7 +399,7 @@ mlir::Value fir::runtime::genScale(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedScale16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in SCALE");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "SCALE");
 
   auto funcTy = func.getFunctionType();
   auto args = fir::runtime::createArguments(builder, loc, funcTy, x, i);
@@ -480,9 +467,7 @@ mlir::Value fir::runtime::genSetExponent(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in FRACTION");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(SetExponent4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(SetExponent8)>(loc, builder);
@@ -491,7 +476,7 @@ mlir::Value fir::runtime::genSetExponent(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedSetExponent16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in FRACTION");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "SET_EXPONENT");
 
   auto funcTy = func.getFunctionType();
   auto args = fir::runtime::createArguments(builder, loc, funcTy, x, i);
@@ -505,9 +490,7 @@ mlir::Value fir::runtime::genSpacing(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in SPACING");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing8)>(loc, builder);
@@ -516,7 +499,7 @@ mlir::Value fir::runtime::genSpacing(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedSpacing16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in SPACING");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "SPACING");
 
   auto funcTy = func.getFunctionType();
   llvm::SmallVector<mlir::Value> args = {
diff --git a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
index 9d47d65ece36013..fabbff818b6f0ef 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
@@ -11,7 +11,7 @@
 #include "flang/Optimizer/Builder/Character.h"
 #include "flang/Optimizer/Builder/FIRBuilder.h"
 #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
-#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Support/Utils.h"
 #include "flang/Runtime/reduction.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 
@@ -652,9 +652,7 @@ void fir::runtime::genMaxloc(fir::FirOpBuilder &builder, mlir::Location loc,
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   fir::factory::CharacterExprHelper charHelper{builder, loc};
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision MAXLOC");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocReal8)>(loc, builder);
@@ -675,7 +673,7 @@ void fir::runtime::genMaxloc(fir::FirOpBuilder &builder, mlir::Location loc,
   else if (charHelper.isCharacterScalar(eleTy))
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocCharacter)>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in MAXLOC");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXLOC");
   genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kind,
                     back);
 }
@@ -702,9 +700,7 @@ mlir::Value fir::runtime::genMaxval(fir::FirOpBuilder &builder,
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision MAXVAL");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalReal8)>(loc, builder);
@@ -723,7 +719,7 @@ mlir::Value fir::runtime::genMaxval(fir::FirOpBuilder &builder,
   else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
     func = fir::runtime::getRuntimeFunc<ForcedMaxvalInteger16>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in MAXVAL");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXVAL");
 
   auto fTy = func.getFunctionType();
   auto sourceFile = fir::factory::locationToFilename(builder, loc);
@@ -771,9 +767,7 @@ void fir::runtime::genMinloc(fir::FirOpBuilder &builder, mlir::Location loc,
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   fir::factory::CharacterExprHelper charHelper{builder, loc};
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision MINLOC");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocReal8)>(loc, builder);
@@ -794,7 +788,7 @@ void fir::runtime::genMinloc(fir::FirOpBuilder &builder, mlir::Location loc,
   else if (charHelper.isCharacterScalar(eleTy))
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocCharacter)>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in MINLOC");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "MINLOC");
   genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kind,
                     back);
 }
@@ -846,9 +840,7 @@ mlir::Value fir::runtime::genMinval(fir::FirOpBuilder &builder,
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision MINVAL");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalReal8)>(loc, builder);
@@ -867,7 +859,7 @@ mlir::Value fir::runtime::genMinval(fir::FirOpBuilder &builder,
   else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
     func = fir::runtime::getRuntimeFunc<ForcedMinvalInteger16>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in MINVAL");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "MINVAL");
 
   auto fTy = func.getFunctionType();
   auto sourceFile = fir::factory::locationToFilename(builder, loc);
@@ -905,9 +897,7 @@ mlir::Value fir::runtime::genNorm2(fir::FirOpBuilder &builder,
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision NORM2");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2_4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2_8)>(loc, builder);
@@ -916,7 +906,7 @@ mlir::Value fir::runtime::genNorm2(fir::FirOpBuilder &builder,
   else if (eleTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedNorm2Real16>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in NORM2");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "NORM2");
 
   auto fTy = func.getFunctionType();
   auto sourceFile = fir::factory::locationToFilename(builder, loc);
@@ -958,9 +948,7 @@ mlir::Value fir::runtime::genProduct(fir::FirOpBuilder &builder,
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision PRODUCT");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(ProductReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(ProductReal8)>(loc, builder);
@@ -988,11 +976,8 @@ mlir::Value fir::runtime::genProd...
[truncated]

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 29, 2023

@llvm/pr-subscribers-flang-codegen

Author: Pete Steinfeld (psteinfeld)

Changes

This update makes the user visible messages relating to features that are not yet implemented be more consistent. I also cleaned up some of the code.

For NYI messages that refer to intrinsics, I made sure the the message begins with "not yet implemented: intrinsic:" to make them easier to recognize.

I created some utility functions for NYI reporting that I put into .../include/Optimizer/Support/Utils.h. These mainly convert MLIR types to their Fortran equivalents.

I converted the NYI code to use the newly created utility functions.


Patch is 42.96 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73740.diff

12 Files Affected:

  • (modified) flang/include/flang/Optimizer/Support/Utils.h (+63)
  • (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+16-9)
  • (modified) flang/lib/Optimizer/Builder/Runtime/Numeric.cpp (+17-34)
  • (modified) flang/lib/Optimizer/Builder/Runtime/Reduction.cpp (+17-42)
  • (modified) flang/lib/Optimizer/Builder/Runtime/Transformational.cpp (+9-17)
  • (modified) flang/lib/Optimizer/CodeGen/Target.cpp (+27-13)
  • (modified) flang/runtime/character.cpp (+5-2)
  • (modified) flang/runtime/descriptor-io.h (+15-19)
  • (modified) flang/runtime/random.cpp (+14-10)
  • (modified) flang/runtime/tools.cpp (+2-2)
  • (modified) flang/runtime/transformational.cpp (+2-1)
  • (modified) flang/test/Lower/Intrinsics/missing-math-runtime.f90 (+1-1)
diff --git a/flang/include/flang/Optimizer/Support/Utils.h b/flang/include/flang/Optimizer/Support/Utils.h
index d5b045924f3c0cb..34c8e79173bcd41 100644
--- a/flang/include/flang/Optimizer/Support/Utils.h
+++ b/flang/include/flang/Optimizer/Support/Utils.h
@@ -14,8 +14,11 @@
 #define FORTRAN_OPTIMIZER_SUPPORT_UTILS_H
 
 #include "flang/Common/default-kinds.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/Todo.h"
 #include "flang/Optimizer/Dialect/FIROps.h"
 #include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Support/FatalError.h"
 #include "mlir/Dialect/Arith/IR/Arith.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/IR/BuiltinAttributes.h"
@@ -70,6 +73,66 @@ fromDefaultKinds(const Fortran::common::IntrinsicTypeDefaultKinds &defKinds) {
           static_cast<fir::KindTy>(
               defKinds.GetDefaultKind(Fortran::common::TypeCategory::Real))};
 }
+
+inline std::string mlirTypeToString(mlir::Type type) {
+  std::string result{};
+  llvm::raw_string_ostream sstream(result);
+  sstream << type;
+  return result;
+}
+
+inline std::string numericMlirTypeToFortran(fir::FirOpBuilder &builder,
+                                            mlir::Type type, mlir::Location loc,
+                                            const llvm::Twine &name) {
+  if (type.isF16())
+    return "REAL(KIND=2)";
+  else if (type.isBF16())
+    return "REAL(KIND=3)";
+  else if (type.isTF32())
+    return "REAL(KIND=unknown)";
+  else if (type.isF32())
+    return "REAL(KIND=4)";
+  else if (type.isF64())
+    return "REAL(KIND=8)";
+  else if (type.isF80())
+    return "REAL(KIND=10)";
+  else if (type.isF128())
+    return "REAL(KIND=16)";
+  else if (type.isInteger(8))
+    return "INTEGER(KIND=1)";
+  else if (type.isInteger(16))
+    return "INTEGER(KIND=2)";
+  else if (type.isInteger(32))
+    return "INTEGER(KIND=4)";
+  else if (type.isInteger(64))
+    return "INTEGER(KIND=8)";
+  else if (type.isInteger(128))
+    return "INTEGER(KIND=16)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 2))
+    return "COMPLEX(KIND=2)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 3))
+    return "COMPLEX(KIND=3)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 4))
+    return "COMPLEX(KIND=4)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 8))
+    return "COMPLEX(KIND=8)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 10))
+    return "COMPLEX(KIND=10)";
+  else if (type == fir::ComplexType::get(builder.getContext(), 16))
+    return "COMPLEX(KIND=16)";
+  else
+    fir::emitFatalError(loc, "unsupported type in " + name + ": " +
+                                 fir::mlirTypeToString(type));
+}
+
+inline void intrinsicTypeTODO(fir::FirOpBuilder &builder, mlir::Type type,
+                              mlir::Location loc,
+                              const llvm::Twine &intrinsicName) {
+  TODO(loc,
+       "intrinsic: " +
+           fir::numericMlirTypeToFortran(builder, type, loc, intrinsicName) +
+           " in " + intrinsicName);
+}
 } // namespace fir
 
 #endif // FORTRAN_OPTIMIZER_SUPPORT_UTILS_H
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 24fdbe97856b3ab..9d9093861041ff3 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -1235,7 +1235,7 @@ searchMathOperation(fir::FirOpBuilder &builder, llvm::StringRef name,
 static void checkPrecisionLoss(llvm::StringRef name,
                                mlir::FunctionType funcType,
                                const FunctionDistance &distance,
-                               mlir::Location loc) {
+                               fir::FirOpBuilder &builder, mlir::Location loc) {
   if (!distance.isLosingPrecision())
     return;
 
@@ -1249,13 +1249,20 @@ static void checkPrecisionLoss(llvm::StringRef name,
   llvm::raw_string_ostream sstream(message);
   if (name == "pow") {
     assert(funcType.getNumInputs() == 2 && "power operator has two arguments");
-    sstream << funcType.getInput(0) << " ** " << funcType.getInput(1);
+    std::string displayName{" ** "};
+    sstream << numericMlirTypeToFortran(builder, funcType.getInput(0), loc,
+                                        displayName)
+            << displayName
+            << numericMlirTypeToFortran(builder, funcType.getInput(1), loc,
+                                        displayName);
   } else {
-    sstream << name << "(";
+    sstream << name.upper() << "(";
     if (funcType.getNumInputs() > 0)
-      sstream << funcType.getInput(0);
-    for (mlir::Type argType : funcType.getInputs().drop_front())
-      sstream << ", " << argType;
+      sstream << numericMlirTypeToFortran(builder, funcType.getInput(0), loc,
+                                          name);
+    for (mlir::Type argType : funcType.getInputs().drop_front()) {
+      sstream << ", " << numericMlirTypeToFortran(builder, argType, loc, name);
+    }
     sstream << ")";
   }
   sstream << "'";
@@ -1373,7 +1380,7 @@ void crashOnMissingIntrinsic(mlir::Location loc, llvm::StringRef name) {
   else if (isCoarrayIntrinsic(name))
     TODO(loc, "coarray: intrinsic " + llvm::Twine(name));
   else
-    TODO(loc, "intrinsic: " + llvm::Twine(name));
+    TODO(loc, "intrinsic: " + llvm::Twine(name.upper()));
 }
 
 template <typename GeneratorType>
@@ -1756,7 +1763,7 @@ IntrinsicLibrary::getRuntimeCallGenerator(llvm::StringRef name,
   if (!mathOp && bestNearMatch) {
     // Use the best near match, optionally issuing an error,
     // if types conversions cause precision loss.
-    checkPrecisionLoss(name, soughtFuncType, bestMatchDistance, loc);
+    checkPrecisionLoss(name, soughtFuncType, bestMatchDistance, builder, loc);
     mathOp = bestNearMatch;
   }
 
@@ -4344,7 +4351,7 @@ mlir::Value IntrinsicLibrary::genModulo(mlir::Type resultType,
   // Real case
   if (resultType == mlir::FloatType::getF128(builder.getContext()))
 
-    TODO(loc, "intrinsic: modulo for floating point of KIND=16");
+    TODO(loc, "REAL(KIND=16): in MODULO intrinsic");
   auto remainder = builder.create<mlir::arith::RemFOp>(loc, args[0], args[1]);
   mlir::Value zero = builder.createRealZeroConstant(loc, remainder.getType());
   auto remainderIsNotZero = builder.create<mlir::arith::CmpFOp>(
diff --git a/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp b/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
index cb4035d53d5b59f..b958a30eb6e5b55 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
@@ -11,7 +11,7 @@
 #include "flang/Optimizer/Builder/Character.h"
 #include "flang/Optimizer/Builder/FIRBuilder.h"
 #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
-#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Support/Utils.h"
 #include "flang/Runtime/numeric.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 
@@ -240,10 +240,7 @@ mlir::Value fir::runtime::genExponent(fir::FirOpBuilder &builder,
                                       mlir::Value x) {
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
-
-  if (fltTy.isF16()) {
-    TODO(loc, "support for REAL with KIND = 2 in EXPONENT");
-  } else if (fltTy.isF32()) {
+  if (fltTy.isF32()) {
     if (resultType.isInteger(32))
       func = fir::runtime::getRuntimeFunc<mkRTKey(Exponent4_4)>(loc, builder);
     else if (resultType.isInteger(64))
@@ -264,7 +261,7 @@ mlir::Value fir::runtime::genExponent(fir::FirOpBuilder &builder,
     else if (resultType.isInteger(64))
       func = fir::runtime::getRuntimeFunc<ForcedExponent16_8>(loc, builder);
   } else
-    fir::emitFatalError(loc, "unsupported REAL kind in EXPONENT");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "EXPONENT");
 
   auto funcTy = func.getFunctionType();
   llvm::SmallVector<mlir::Value> args = {
@@ -278,9 +275,7 @@ mlir::Value fir::runtime::genFraction(fir::FirOpBuilder &builder,
                                       mlir::Location loc, mlir::Value x) {
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in FRACTION");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Fraction4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Fraction8)>(loc, builder);
@@ -289,7 +284,7 @@ mlir::Value fir::runtime::genFraction(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedFraction16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in FRACTION");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "FRACTION");
 
   auto funcTy = func.getFunctionType();
   llvm::SmallVector<mlir::Value> args = {
@@ -307,9 +302,7 @@ mlir::Value fir::runtime::genMod(fir::FirOpBuilder &builder, mlir::Location loc,
   if (fltTy != p.getType())
     fir::emitFatalError(loc, "arguments type mismatch in MOD");
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in MOD");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(ModReal4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(ModReal8)>(loc, builder);
@@ -318,7 +311,7 @@ mlir::Value fir::runtime::genMod(fir::FirOpBuilder &builder, mlir::Location loc,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedMod16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in MOD");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "MOD");
 
   auto funcTy = func.getFunctionType();
   auto sourceFile = fir::factory::locationToFilename(builder, loc);
@@ -337,9 +330,7 @@ mlir::Value fir::runtime::genNearest(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in NEAREST");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Nearest4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Nearest8)>(loc, builder);
@@ -348,7 +339,7 @@ mlir::Value fir::runtime::genNearest(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedNearest16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in NEAREST");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "NEAREST");
 
   auto funcTy = func.getFunctionType();
 
@@ -374,9 +365,7 @@ mlir::Value fir::runtime::genRRSpacing(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in RRSPACING");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(RRSpacing4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(RRSpacing8)>(loc, builder);
@@ -385,7 +374,7 @@ mlir::Value fir::runtime::genRRSpacing(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedRRSpacing16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in RRSPACING");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "RRSPACING");
 
   auto funcTy = func.getFunctionType();
   llvm::SmallVector<mlir::Value> args = {
@@ -401,9 +390,7 @@ mlir::Value fir::runtime::genScale(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in SCALE");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Scale4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Scale8)>(loc, builder);
@@ -412,7 +399,7 @@ mlir::Value fir::runtime::genScale(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedScale16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in SCALE");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "SCALE");
 
   auto funcTy = func.getFunctionType();
   auto args = fir::runtime::createArguments(builder, loc, funcTy, x, i);
@@ -480,9 +467,7 @@ mlir::Value fir::runtime::genSetExponent(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in FRACTION");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(SetExponent4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(SetExponent8)>(loc, builder);
@@ -491,7 +476,7 @@ mlir::Value fir::runtime::genSetExponent(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedSetExponent16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in FRACTION");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "SET_EXPONENT");
 
   auto funcTy = func.getFunctionType();
   auto args = fir::runtime::createArguments(builder, loc, funcTy, x, i);
@@ -505,9 +490,7 @@ mlir::Value fir::runtime::genSpacing(fir::FirOpBuilder &builder,
   mlir::func::FuncOp func;
   mlir::Type fltTy = x.getType();
 
-  if (fltTy.isF16())
-    TODO(loc, "support for REAL with KIND = 2 in SPACING");
-  else if (fltTy.isF32())
+  if (fltTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing4)>(loc, builder);
   else if (fltTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing8)>(loc, builder);
@@ -516,7 +499,7 @@ mlir::Value fir::runtime::genSpacing(fir::FirOpBuilder &builder,
   else if (fltTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedSpacing16>(loc, builder);
   else
-    fir::emitFatalError(loc, "unsupported REAL kind in SPACING");
+    fir::intrinsicTypeTODO(builder, fltTy, loc, "SPACING");
 
   auto funcTy = func.getFunctionType();
   llvm::SmallVector<mlir::Value> args = {
diff --git a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
index 9d47d65ece36013..fabbff818b6f0ef 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
@@ -11,7 +11,7 @@
 #include "flang/Optimizer/Builder/Character.h"
 #include "flang/Optimizer/Builder/FIRBuilder.h"
 #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
-#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Support/Utils.h"
 #include "flang/Runtime/reduction.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 
@@ -652,9 +652,7 @@ void fir::runtime::genMaxloc(fir::FirOpBuilder &builder, mlir::Location loc,
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   fir::factory::CharacterExprHelper charHelper{builder, loc};
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision MAXLOC");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocReal8)>(loc, builder);
@@ -675,7 +673,7 @@ void fir::runtime::genMaxloc(fir::FirOpBuilder &builder, mlir::Location loc,
   else if (charHelper.isCharacterScalar(eleTy))
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocCharacter)>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in MAXLOC");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXLOC");
   genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kind,
                     back);
 }
@@ -702,9 +700,7 @@ mlir::Value fir::runtime::genMaxval(fir::FirOpBuilder &builder,
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision MAXVAL");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalReal8)>(loc, builder);
@@ -723,7 +719,7 @@ mlir::Value fir::runtime::genMaxval(fir::FirOpBuilder &builder,
   else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
     func = fir::runtime::getRuntimeFunc<ForcedMaxvalInteger16>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in MAXVAL");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXVAL");
 
   auto fTy = func.getFunctionType();
   auto sourceFile = fir::factory::locationToFilename(builder, loc);
@@ -771,9 +767,7 @@ void fir::runtime::genMinloc(fir::FirOpBuilder &builder, mlir::Location loc,
   auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   fir::factory::CharacterExprHelper charHelper{builder, loc};
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision MINLOC");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocReal8)>(loc, builder);
@@ -794,7 +788,7 @@ void fir::runtime::genMinloc(fir::FirOpBuilder &builder, mlir::Location loc,
   else if (charHelper.isCharacterScalar(eleTy))
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocCharacter)>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in MINLOC");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "MINLOC");
   genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kind,
                     back);
 }
@@ -846,9 +840,7 @@ mlir::Value fir::runtime::genMinval(fir::FirOpBuilder &builder,
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision MINVAL");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalReal8)>(loc, builder);
@@ -867,7 +859,7 @@ mlir::Value fir::runtime::genMinval(fir::FirOpBuilder &builder,
   else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))
     func = fir::runtime::getRuntimeFunc<ForcedMinvalInteger16>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in MINVAL");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "MINVAL");
 
   auto fTy = func.getFunctionType();
   auto sourceFile = fir::factory::locationToFilename(builder, loc);
@@ -905,9 +897,7 @@ mlir::Value fir::runtime::genNorm2(fir::FirOpBuilder &builder,
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision NORM2");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2_4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2_8)>(loc, builder);
@@ -916,7 +906,7 @@ mlir::Value fir::runtime::genNorm2(fir::FirOpBuilder &builder,
   else if (eleTy.isF128())
     func = fir::runtime::getRuntimeFunc<ForcedNorm2Real16>(loc, builder);
   else
-    fir::emitFatalError(loc, "invalid type in NORM2");
+    fir::intrinsicTypeTODO(builder, eleTy, loc, "NORM2");
 
   auto fTy = func.getFunctionType();
   auto sourceFile = fir::factory::locationToFilename(builder, loc);
@@ -958,9 +948,7 @@ mlir::Value fir::runtime::genProduct(fir::FirOpBuilder &builder,
   auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy();
   auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
 
-  if (eleTy.isF16() || eleTy.isBF16())
-    TODO(loc, "half-precision PRODUCT");
-  else if (eleTy.isF32())
+  if (eleTy.isF32())
     func = fir::runtime::getRuntimeFunc<mkRTKey(ProductReal4)>(loc, builder);
   else if (eleTy.isF64())
     func = fir::runtime::getRuntimeFunc<mkRTKey(ProductReal8)>(loc, builder);
@@ -988,11 +976,8 @@ mlir::Value fir::runtime::genProd...
[truncated]

Copy link

github-actions bot commented Nov 29, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take care of the clang-format issue. LGTM otherwise, thanks!

Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG. Nice improvement to the NYI messages.

Checked with gfortran testsuite on AArch64, no issues.

@psteinfeld
Copy link
Contributor Author

LG. Nice improvement to the NYI messages.

Checked with gfortran testsuite on AArch64, no issues.

Thanks, Kiran!

@psteinfeld psteinfeld merged commit 04b1853 into llvm:main Nov 29, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:codegen flang:fir-hlfir flang:runtime flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants