[flang-commits] [flang] f5b970c - [flang] Fix type mismatch in verification error

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Mon Jun 13 12:37:46 PDT 2022


Author: Eric Schweitz
Date: 2022-06-13T21:37:39+02:00
New Revision: f5b970c9ef87891b6c710110f4d645ae2892c23d

URL: https://github.com/llvm/llvm-project/commit/f5b970c9ef87891b6c710110f4d645ae2892c23d
DIFF: https://github.com/llvm/llvm-project/commit/f5b970c9ef87891b6c710110f4d645ae2892c23d.diff

LOG: [flang] Fix type mismatch in verification error

FIR models Fortran intrinsic types with deliberate KIND values. Like
Fortran, COMPLEX and REAL have related KINDs in FIR. Lowering now
converts REAL types to floating point (MLIR) up front. This patch moves
the code to convert from FIR RealType to MLIR FloatType out of codegen
and into the builder, allowing FIR ComplexTypes to have their element
type returned as an MLIR FloatType.

We should consider whether to replace fir::ComplexType with
mlir::ComplexType at some point. I believe these types are presently
used to convey distinctins in the target ABIs in the Tilikum bridge
however.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D127636

Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>

Added: 
    

Modified: 
    flang/include/flang/Optimizer/Dialect/FIRType.h
    flang/include/flang/Optimizer/Dialect/FIRTypes.td
    flang/lib/Optimizer/CodeGen/TypeConverter.h
    flang/lib/Optimizer/Dialect/FIROps.cpp
    flang/lib/Optimizer/Dialect/FIRType.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index 956ec218ec532..4c0085eab1cfd 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -16,6 +16,13 @@
 #include "mlir/IR/BuiltinAttributes.h"
 #include "mlir/IR/BuiltinTypes.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Type.h"
+
+namespace fir {
+class FIROpsDialect;
+class KindMapping;
+using KindTy = unsigned;
+} // namespace fir
 
 #define GET_TYPEDEF_CLASSES
 #include "flang/Optimizer/Dialect/FIROpsTypes.h.inc"
@@ -37,11 +44,6 @@ class ValueRange;
 } // namespace mlir
 
 namespace fir {
-
-class FIROpsDialect;
-
-using KindTy = unsigned;
-
 namespace detail {
 struct RecordTypeStorage;
 } // namespace detail
@@ -257,6 +259,14 @@ bool isCharacterProcedureTuple(mlir::Type type, bool acceptRawFunc = true);
 /// Returns null on error.
 mlir::Type applyPathToType(mlir::Type rootTy, mlir::ValueRange path);
 
+/// Does this function type have a result that requires binding the result value
+/// with storage in a fir.save_result operation in order to use the result?
+bool hasAbstractResult(mlir::FunctionType ty);
+
+/// Convert llvm::Type::TypeID to mlir::Type
+mlir::Type fromRealTypeID(mlir::MLIRContext *context, llvm::Type::TypeID typeID,
+                          fir::KindTy kind);
+
 } // namespace fir
 
 #endif // FORTRAN_OPTIMIZER_DIALECT_FIRTYPE_H

diff  --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
index 2152a056f0d53..165a3a614a5dd 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
@@ -153,6 +153,7 @@ def fir_ComplexType : FIR_Type<"Complex", "complex"> {
     using KindTy = unsigned;
 
     mlir::Type getElementType() const;
+    mlir::Type getEleType(const fir::KindMapping &kindMap) const;
   }];
 }
 

diff  --git a/flang/lib/Optimizer/CodeGen/TypeConverter.h b/flang/lib/Optimizer/CodeGen/TypeConverter.h
index e08add4851ab1..1c7ef9c0bc461 100644
--- a/flang/lib/Optimizer/CodeGen/TypeConverter.h
+++ b/flang/lib/Optimizer/CodeGen/TypeConverter.h
@@ -338,7 +338,8 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter {
   // convert a front-end kind value to either a std or LLVM IR dialect type
   // fir.real<n>  -->  llvm.anyfloat  where anyfloat is a kind mapping
   mlir::Type convertRealType(fir::KindTy kind) {
-    return fromRealTypeID(kindMapping.getRealTypeID(kind), kind);
+    return fir::fromRealTypeID(&getContext(), kindMapping.getRealTypeID(kind),
+                               kind);
   }
 
   // fir.array<c ... :any>  -->  llvm<"[...[c x any]]">
@@ -369,28 +370,6 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter {
         mlir::IntegerType::get(&getContext(), 8));
   }
 
-  /// Convert llvm::Type::TypeID to mlir::Type
-  mlir::Type fromRealTypeID(llvm::Type::TypeID typeID, fir::KindTy kind) {
-    switch (typeID) {
-    case llvm::Type::TypeID::HalfTyID:
-      return mlir::FloatType::getF16(&getContext());
-    case llvm::Type::TypeID::BFloatTyID:
-      return mlir::FloatType::getBF16(&getContext());
-    case llvm::Type::TypeID::FloatTyID:
-      return mlir::FloatType::getF32(&getContext());
-    case llvm::Type::TypeID::DoubleTyID:
-      return mlir::FloatType::getF64(&getContext());
-    case llvm::Type::TypeID::X86_FP80TyID:
-      return mlir::FloatType::getF80(&getContext());
-    case llvm::Type::TypeID::FP128TyID:
-      return mlir::FloatType::getF128(&getContext());
-    default:
-      mlir::emitError(mlir::UnknownLoc::get(&getContext()))
-          << "unsupported type: !fir.real<" << kind << ">";
-      return {};
-    }
-  }
-
   KindMapping &getKindMap() { return kindMapping; }
 
 private:

diff  --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 9e58afa74fadc..fc5d85886246a 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -14,6 +14,8 @@
 #include "flang/Optimizer/Dialect/FIRAttr.h"
 #include "flang/Optimizer/Dialect/FIROpsSupport.h"
 #include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Support/FIRContext.h"
+#include "flang/Optimizer/Support/KindMapping.h"
 #include "flang/Optimizer/Support/Utils.h"
 #include "mlir/Dialect/CommonFolders.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -3437,8 +3439,11 @@ mlir::Type fir::applyPathToType(mlir::Type eleTy, mlir::ValueRange path) {
                   return mlir::Type{};
                 })
                 .Case<fir::ComplexType>([&](fir::ComplexType ty) {
-                  if (fir::isa_integer((*i++).getType()))
-                    return ty.getElementType();
+                  auto x = *i;
+                  if (auto *op = (*i++).getDefiningOp())
+                    if (fir::isa_integer(x.getType()))
+                      return ty.getEleType(fir::getKindMapping(
+                          op->getParentOfType<mlir::ModuleOp>()));
                   return mlir::Type{};
                 })
                 .Case<mlir::ComplexType>([&](mlir::ComplexType ty) {

diff  --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index 834173be2dd81..3293cad6177a2 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -12,6 +12,7 @@
 
 #include "flang/Optimizer/Dialect/FIRType.h"
 #include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Support/KindMapping.h"
 #include "flang/Tools/PointerModels.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/BuiltinDialect.h"
@@ -483,6 +484,13 @@ mlir::Type fir::ComplexType::getElementType() const {
   return fir::RealType::get(getContext(), getFKind());
 }
 
+// Return the MLIR float type of the complex element type.
+mlir::Type fir::ComplexType::getEleType(const fir::KindMapping &kindMap) const {
+  auto fkind = getFKind();
+  auto realTypeID = kindMap.getRealTypeID(fkind);
+  return fir::fromRealTypeID(getContext(), realTypeID, fkind);
+}
+
 //===----------------------------------------------------------------------===//
 // HeapType
 //===----------------------------------------------------------------------===//
@@ -925,6 +933,37 @@ bool fir::isCharacterProcedureTuple(mlir::Type ty, bool acceptRawFunc) {
          fir::isa_integer(tuple.getType(1));
 }
 
+bool fir::hasAbstractResult(mlir::FunctionType ty) {
+  if (ty.getNumResults() == 0)
+    return false;
+  auto resultType = ty.getResult(0);
+  return resultType.isa<fir::SequenceType, fir::BoxType, fir::RecordType>();
+}
+
+/// Convert llvm::Type::TypeID to mlir::Type. \p kind is provided for error
+/// messages only.
+mlir::Type fir::fromRealTypeID(mlir::MLIRContext *context,
+                               llvm::Type::TypeID typeID, fir::KindTy kind) {
+  switch (typeID) {
+  case llvm::Type::TypeID::HalfTyID:
+    return mlir::FloatType::getF16(context);
+  case llvm::Type::TypeID::BFloatTyID:
+    return mlir::FloatType::getBF16(context);
+  case llvm::Type::TypeID::FloatTyID:
+    return mlir::FloatType::getF32(context);
+  case llvm::Type::TypeID::DoubleTyID:
+    return mlir::FloatType::getF64(context);
+  case llvm::Type::TypeID::X86_FP80TyID:
+    return mlir::FloatType::getF80(context);
+  case llvm::Type::TypeID::FP128TyID:
+    return mlir::FloatType::getF128(context);
+  default:
+    mlir::emitError(mlir::UnknownLoc::get(context))
+        << "unsupported type: !fir.real<" << kind << ">";
+    return {};
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // FIROpsDialect
 //===----------------------------------------------------------------------===//


        


More information about the flang-commits mailing list