[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@nvidia.com>
This commit is contained in:
parent
3abaefe64c
commit
f5b970c9ef
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -338,7 +338,8 @@ public:
|
|||
// 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 @@ public:
|
|||
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:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue
Block a user