[flang][FIR] remove fir.complex type and its fir.real element type (#111025)

Final patch of
https://discourse.llvm.org/t/rfc-flang-replace-usages-of-fir-complex-by-mlir-complex-type/82292

Since fir.real was only still used as fir.complex element type, this
patch removes it at the same time.
This commit is contained in:
jeanPerier 2024-10-04 09:57:03 +02:00 committed by GitHub
parent bba3849b81
commit 1753de2d95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 46 additions and 305 deletions

View File

@ -89,25 +89,10 @@ public:
// fir.char<k,n> --> llvm.array<n x "ix">
mlir::Type convertCharType(fir::CharacterType charTy) const;
// Use the target specifics to figure out how to map complex to LLVM IR. The
// use of complex values in function signatures is handled before conversion
// to LLVM IR dialect here.
//
// fir.complex<T> | std.complex<T> --> llvm<"{t,t}">
template <typename C>
mlir::Type convertComplexType(C cmplx) const {
auto eleTy = cmplx.getElementType();
return convertType(specifics->complexMemoryType(eleTy));
}
template <typename A> mlir::Type convertPointerLike(A &ty) const {
return mlir::LLVM::LLVMPointerType::get(ty.getContext());
}
// 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) const;
// fir.array<c ... :any> --> llvm<"[...[c x any]]">
mlir::Type convertSequenceType(SequenceType seq) const;

View File

@ -2735,8 +2735,8 @@ def fir_ConvertOp : fir_SimpleOneResultOp<"convert", [NoMemoryEffect]> {
}
def FortranTypeAttr : Attr<And<[CPred<"mlir::isa<mlir::TypeAttr>($_self)">,
Or<[CPred<"mlir::isa<fir::CharacterType, fir::ComplexType, "
"fir::IntegerType, fir::LogicalType, fir::RealType, "
Or<[CPred<"mlir::isa<fir::CharacterType, fir::IntegerType,"
"fir::LogicalType, mlir::FloatType, mlir::ComplexType,"
"fir::RecordType>(mlir::cast<mlir::TypeAttr>($_self).getValue())"
>]>]>, "Fortran surface type"> {
let storageType = [{ ::mlir::TypeAttr }];

View File

@ -159,10 +159,8 @@ mlir::Type dyn_cast_ptrEleTy(mlir::Type t);
/// `t` is not a memory reference or box type, then returns a null `Type`.
mlir::Type dyn_cast_ptrOrBoxEleTy(mlir::Type t);
/// Is `t` a FIR Real or MLIR Float type?
inline bool isa_real(mlir::Type t) {
return mlir::isa<fir::RealType, mlir::FloatType>(t);
}
/// Is `t` a real type?
inline bool isa_real(mlir::Type t) { return mlir::isa<mlir::FloatType>(t); }
/// Is `t` an integral type?
inline bool isa_integer(mlir::Type t) {

View File

@ -158,26 +158,6 @@ def fir_ClassType : FIR_Type<"Class", "class", [], "BaseBoxType"> {
let assemblyFormat = "`<` $eleTy `>`";
}
def fir_ComplexType : FIR_Type<"Complex", "complex"> {
let summary = "Complex type";
let description = [{
Model of a Fortran COMPLEX intrinsic type, including the KIND type
parameter. COMPLEX is a floating point type with a real and imaginary
member.
}];
let parameters = (ins "KindTy":$fKind);
let hasCustomAssemblyFormat = 1;
let extraClassDeclaration = [{
using KindTy = unsigned;
mlir::Type getElementType() const;
mlir::Type getEleType(const fir::KindMapping &kindMap) const;
}];
}
def fir_FieldType : FIR_Type<"Field", "field"> {
let summary = "A field (in a RecordType) argument's type";
@ -313,26 +293,6 @@ def fir_PointerType : FIR_Type<"Pointer", "ptr"> {
}];
}
def fir_RealType : FIR_Type<"Real", "real"> {
let summary = "FIR real type";
let description = [{
Model of a Fortran REAL (and DOUBLE PRECISION) intrinsic type, including the
KIND type parameter.
}];
let parameters = (ins "KindTy":$fKind);
let hasCustomAssemblyFormat = 1;
let extraClassDeclaration = [{
using KindTy = unsigned;
// Get MLIR float type with same semantics.
mlir::Type getFloatType(const fir::KindMapping &kindMap) const;
}];
let genVerifyDecl = 1;
}
def fir_RecordType : FIR_Type<"Record", "type"> {
let summary = "FIR derived type";
@ -597,8 +557,7 @@ def AnyIntegerLike : TypeConstraint<Or<[SignlessIntegerLike.predicate,
AnySignedInteger.predicate, fir_IntegerType.predicate]>, "any integer">;
def AnyLogicalLike : TypeConstraint<Or<[BoolLike.predicate,
fir_LogicalType.predicate]>, "any logical">;
def AnyRealLike : TypeConstraint<Or<[FloatLike.predicate,
fir_RealType.predicate]>, "any real">;
def AnyRealLike : TypeConstraint<FloatLike.predicate, "any real">;
def AnyIntegerType : Type<AnyIntegerLike.predicate, "any integer">;
def AnyFirComplexLike : TypeConstraint<CPred<"::fir::isa_complex($_self)">,

View File

@ -93,7 +93,7 @@ def AnyFortranVariable : Type<IsFortranVariablePred, "any HLFIR variable type">;
def AnyFortranValue : TypeConstraint<Or<[AnyLogicalLike.predicate,
AnyIntegerLike.predicate, AnyRealLike.predicate,
fir_ComplexType.predicate, AnyComplex.predicate,
AnyFirComplexLike.predicate,
hlfir_ExprType.predicate]>, "any Fortran value type">;

View File

@ -5710,10 +5710,6 @@ private:
fir::applyPathToType(seqTy.getEleTy(), components.suffixComponents);
if (!eleTy)
fir::emitFatalError(loc, "slicing path is ill-formed");
if (auto realTy = mlir::dyn_cast<fir::RealType>(eleTy))
eleTy = Fortran::lower::convertReal(realTy.getContext(),
realTy.getFKind());
// create the type of the projected array.
arrTy = fir::SequenceType::get(seqTy.getShape(), eleTy);
LLVM_DEBUG(llvm::dbgs()

View File

@ -150,8 +150,6 @@ mlir::Value
fir::FirOpBuilder::createRealConstant(mlir::Location loc, mlir::Type fltTy,
llvm::APFloat::integerPart val) {
auto apf = [&]() -> llvm::APFloat {
if (auto ty = mlir::dyn_cast<fir::RealType>(fltTy))
return llvm::APFloat(kindMap.getFloatSemantics(ty.getFKind()), val);
if (fltTy.isF16())
return llvm::APFloat(llvm::APFloat::IEEEhalf(), val);
if (fltTy.isBF16())

View File

@ -589,9 +589,7 @@ struct CallOpConversion : public fir::FIROpConversion<fir::CallOp> {
} // namespace
static mlir::Type getComplexEleTy(mlir::Type complex) {
if (auto cc = mlir::dyn_cast<mlir::ComplexType>(complex))
return cc.getElementType();
return mlir::cast<fir::ComplexType>(complex).getElementType();
return mlir::cast<mlir::ComplexType>(complex).getElementType();
}
namespace {

View File

@ -41,8 +41,6 @@ llvm::StringRef Attributes::getIntExtensionAttrName() const {
static const llvm::fltSemantics &floatToSemantics(const KindMapping &kindMap,
mlir::Type type) {
assert(isa_real(type));
if (auto ty = mlir::dyn_cast<fir::RealType>(type))
return kindMap.getFloatSemantics(ty.getFKind());
return mlir::cast<mlir::FloatType>(type).getFloatSemantics();
}
@ -356,7 +354,7 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> {
else
current = ArgClass::Integer;
})
.template Case<mlir::FloatType, fir::RealType>([&](mlir::Type floatTy) {
.template Case<mlir::FloatType>([&](mlir::Type floatTy) {
const auto *sem = &floatToSemantics(kindMap, floatTy);
if (sem == &llvm::APFloat::x87DoubleExtended()) {
Lo = ArgClass::X87;
@ -540,9 +538,16 @@ struct TargetX86_64 : public GenericTarget<TargetX86_64> {
if (typeList.size() != 1)
return {};
mlir::Type fieldType = typeList[0].second;
if (mlir::isa<mlir::FloatType, mlir::IntegerType, fir::RealType,
fir::CharacterType, fir::LogicalType>(fieldType))
if (mlir::isa<mlir::FloatType, mlir::IntegerType, fir::LogicalType>(
fieldType))
return fieldType;
if (mlir::isa<fir::CharacterType>(fieldType)) {
// Only CHARACTER(1) are expected in BIND(C) contexts, which is the only
// contexts where derived type may be passed in registers.
assert(mlir::cast<fir::CharacterType>(fieldType).getLen() == 1 &&
"fir.type value arg character components must have length 1");
return fieldType;
}
// Complex field that needs to be split, or array.
return {};
}

View File

@ -351,11 +351,6 @@ public:
if (fnTy.getResults().size() == 1) {
mlir::Type ty = fnTy.getResult(0);
llvm::TypeSwitch<mlir::Type>(ty)
.template Case<fir::ComplexType>([&](fir::ComplexType cmplx) {
wrap = rewriteCallComplexResultType(loc, cmplx, newResTys,
newInTyAndAttrs, newOpers,
savedStackPtr);
})
.template Case<mlir::ComplexType>([&](mlir::ComplexType cmplx) {
wrap = rewriteCallComplexResultType(loc, cmplx, newResTys,
newInTyAndAttrs, newOpers,
@ -414,10 +409,6 @@ public:
}
}
})
.template Case<fir::ComplexType>([&](fir::ComplexType cmplx) {
rewriteCallComplexInputType(loc, cmplx, oper, newInTyAndAttrs,
newOpers, savedStackPtr);
})
.template Case<mlir::ComplexType>([&](mlir::ComplexType cmplx) {
rewriteCallComplexInputType(loc, cmplx, oper, newInTyAndAttrs,
newOpers, savedStackPtr);
@ -538,10 +529,10 @@ public:
}
}
// Result type fixup for fir::ComplexType and mlir::ComplexType
template <typename A, typename B>
// Result type fixup for ComplexType.
template <typename Ty>
void lowerComplexSignatureRes(
mlir::Location loc, A cmplx, B &newResTys,
mlir::Location loc, mlir::ComplexType cmplx, Ty &newResTys,
fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs) {
if (noComplexConversion) {
newResTys.push_back(cmplx);
@ -557,10 +548,9 @@ public:
}
}
// Argument type fixup for fir::ComplexType and mlir::ComplexType
template <typename A>
// Argument type fixup for ComplexType.
void lowerComplexSignatureArg(
mlir::Location loc, A cmplx,
mlir::Location loc, mlir::ComplexType cmplx,
fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs) {
if (noComplexConversion) {
newInTyAndAttrs.push_back(fir::CodeGenSpecifics::getTypeAndAttr(cmplx));
@ -602,9 +592,6 @@ public:
auto loc = addrOp.getLoc();
for (mlir::Type ty : addrTy.getResults()) {
llvm::TypeSwitch<mlir::Type>(ty)
.Case<fir::ComplexType>([&](fir::ComplexType ty) {
lowerComplexSignatureRes(loc, ty, newResTys, newInTyAndAttrs);
})
.Case<mlir::ComplexType>([&](mlir::ComplexType ty) {
lowerComplexSignatureRes(loc, ty, newResTys, newInTyAndAttrs);
})
@ -628,9 +615,6 @@ public:
}
}
})
.Case<fir::ComplexType>([&](fir::ComplexType ty) {
lowerComplexSignatureArg(loc, ty, newInTyAndAttrs);
})
.Case<mlir::ComplexType>([&](mlir::ComplexType ty) {
lowerComplexSignatureArg(loc, ty, newInTyAndAttrs);
})
@ -766,12 +750,6 @@ public:
// Convert return value(s)
for (auto ty : funcTy.getResults())
llvm::TypeSwitch<mlir::Type>(ty)
.Case<fir::ComplexType>([&](fir::ComplexType cmplx) {
if (noComplexConversion)
newResTys.push_back(cmplx);
else
doComplexReturn(func, cmplx, newResTys, newInTyAndAttrs, fixups);
})
.Case<mlir::ComplexType>([&](mlir::ComplexType cmplx) {
if (noComplexConversion)
newResTys.push_back(cmplx);
@ -835,9 +813,6 @@ public:
}
}
})
.Case<fir::ComplexType>([&](fir::ComplexType cmplx) {
doComplexArg(func, cmplx, newInTyAndAttrs, fixups);
})
.Case<mlir::ComplexType>([&](mlir::ComplexType cmplx) {
doComplexArg(func, cmplx, newInTyAndAttrs, fixups);
})
@ -1090,10 +1065,11 @@ public:
/// Convert a complex return value. This can involve converting the return
/// value to a "hidden" first argument or packing the complex into a wide
/// GPR.
template <typename A, typename B, typename C>
void doComplexReturn(mlir::func::FuncOp func, A cmplx, B &newResTys,
template <typename Ty, typename FIXUPS>
void doComplexReturn(mlir::func::FuncOp func, mlir::ComplexType cmplx,
Ty &newResTys,
fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs,
C &fixups) {
FIXUPS &fixups) {
if (noComplexConversion) {
newResTys.push_back(cmplx);
return;
@ -1194,10 +1170,10 @@ public:
/// Convert a complex argument value. This can involve storing the value to
/// a temporary memory location or factoring the value into two distinct
/// arguments.
template <typename A, typename B>
void doComplexArg(mlir::func::FuncOp func, A cmplx,
template <typename FIXUPS>
void doComplexArg(mlir::func::FuncOp func, mlir::ComplexType cmplx,
fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs,
B &fixups) {
FIXUPS &fixups) {
if (noComplexConversion) {
newInTyAndAttrs.push_back(fir::CodeGenSpecifics::getTypeAndAttr(cmplx));
return;

View File

@ -57,8 +57,6 @@ LLVMTypeConverter::LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
[&](fir::ClassType classTy) { return convertBoxType(classTy); });
addConversion(
[&](fir::CharacterType charTy) { return convertCharType(charTy); });
addConversion(
[&](fir::ComplexType cmplx) { return convertComplexType(cmplx); });
addConversion([&](fir::FieldType field) {
// Convert to i32 because of LLVM GEP indexing restriction.
return mlir::IntegerType::get(field.getContext(), 32);
@ -86,8 +84,6 @@ LLVMTypeConverter::LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
[&](fir::RecordType derived, llvm::SmallVectorImpl<mlir::Type> &results) {
return convertRecordType(derived, results);
});
addConversion(
[&](fir::RealType real) { return convertRealType(real.getFKind()); });
addConversion(
[&](fir::ReferenceType ref) { return convertPointerLike(ref); });
addConversion([&](fir::SequenceType sequence) {
@ -277,13 +273,6 @@ mlir::Type LLVMTypeConverter::convertCharType(fir::CharacterType charTy) const {
return mlir::LLVM::LLVMArrayType::get(iTy, charTy.getLen());
}
// 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 LLVMTypeConverter::convertRealType(fir::KindTy kind) const {
return fir::fromRealTypeID(&getContext(), kindMapping.getRealTypeID(kind),
kind);
}
// fir.array<c ... :any> --> llvm<"[...[c x any]]">
mlir::Type LLVMTypeConverter::convertSequenceType(SequenceType seq) const {
auto baseTy = convertType(seq.getEleTy());

View File

@ -1347,7 +1347,7 @@ bool fir::ConvertOp::isIntegerCompatible(mlir::Type ty) {
}
bool fir::ConvertOp::isFloatCompatible(mlir::Type ty) {
return mlir::isa<mlir::FloatType, fir::RealType>(ty);
return mlir::isa<mlir::FloatType>(ty);
}
bool fir::ConvertOp::isPointerCompatible(mlir::Type ty) {
@ -1533,8 +1533,6 @@ llvm::LogicalResult fir::CoordinateOp::verify() {
} else if (auto t = mlir::dyn_cast<fir::RecordType>(eleTy)) {
// FIXME: This is the same as the tuple case.
return mlir::success();
} else if (auto t = mlir::dyn_cast<fir::ComplexType>(eleTy)) {
eleTy = t.getElementType();
} else if (auto t = mlir::dyn_cast<mlir::ComplexType>(eleTy)) {
eleTy = t.getElementType();
} else if (auto t = mlir::dyn_cast<fir::CharacterType>(eleTy)) {
@ -4389,14 +4387,6 @@ mlir::Type fir::applyPathToType(mlir::Type eleTy, mlir::ValueRange path) {
return ty.getType(fir::toInt(off));
return mlir::Type{};
})
.Case<fir::ComplexType>([&](fir::ComplexType ty) {
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) {
if (fir::isa_integer((*i++).getType()))
return ty.getElementType();

View File

@ -441,7 +441,6 @@ unsigned getBoxRank(mlir::Type boxTy) {
/// Return the ISO_C_BINDING intrinsic module value of type \p ty.
int getTypeCode(mlir::Type ty, const fir::KindMapping &kindMap) {
unsigned width = 0;
if (mlir::IntegerType intTy = mlir::dyn_cast<mlir::IntegerType>(ty)) {
switch (intTy.getWidth()) {
case 8:
@ -485,21 +484,12 @@ int getTypeCode(mlir::Type ty, const fir::KindMapping &kindMap) {
}
llvm_unreachable("unsupported real type");
}
if (fir::isa_complex(ty)) {
if (mlir::ComplexType complexTy = mlir::dyn_cast<mlir::ComplexType>(ty)) {
mlir::FloatType floatTy =
mlir::cast<mlir::FloatType>(complexTy.getElementType());
if (floatTy.isBF16())
return CFI_type_bfloat_Complex;
width = floatTy.getWidth();
} else if (fir::ComplexType complexTy =
mlir::dyn_cast<fir::ComplexType>(ty)) {
auto FKind = complexTy.getFKind();
if (FKind == 3)
return CFI_type_bfloat_Complex;
width = kindMap.getRealBitsize(FKind);
}
switch (width) {
switch (floatTy.getWidth()) {
case 16:
return CFI_type_half_float_Complex;
case 32:
@ -545,14 +535,10 @@ std::string getTypeAsString(mlir::Type ty, const fir::KindMapping &kindMap,
name << 'i' << ty.getIntOrFloatBitWidth();
} else if (mlir::isa<mlir::FloatType>(ty)) {
name << 'f' << ty.getIntOrFloatBitWidth();
} else if (fir::isa_complex(ty)) {
} else if (auto cplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(ty)) {
name << 'z';
if (auto cplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(ty)) {
auto floatTy = mlir::cast<mlir::FloatType>(cplxTy.getElementType());
name << floatTy.getWidth();
} else if (auto cplxTy = mlir::dyn_cast_or_null<fir::ComplexType>(ty)) {
name << kindMap.getRealBitsize(cplxTy.getFKind());
}
} else if (auto logTy = mlir::dyn_cast_or_null<fir::LogicalType>(ty)) {
name << 'l' << kindMap.getLogicalBitsize(logTy.getFKind());
} else {
@ -778,34 +764,11 @@ fir::ClassType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
if (mlir::isa<fir::RecordType, fir::SequenceType, fir::HeapType,
fir::PointerType, mlir::NoneType, mlir::IntegerType,
mlir::FloatType, fir::CharacterType, fir::LogicalType,
fir::ComplexType, mlir::ComplexType>(eleTy))
mlir::ComplexType>(eleTy))
return mlir::success();
return emitError() << "invalid element type\n";
}
//===----------------------------------------------------------------------===//
// ComplexType
//===----------------------------------------------------------------------===//
mlir::Type fir::ComplexType::parse(mlir::AsmParser &parser) {
return parseKindSingleton<fir::ComplexType>(parser);
}
void fir::ComplexType::print(mlir::AsmPrinter &printer) const {
printer << "<" << getFKind() << '>';
}
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
//===----------------------------------------------------------------------===//
@ -875,32 +838,6 @@ llvm::LogicalResult fir::PointerType::verify(
return mlir::success();
}
//===----------------------------------------------------------------------===//
// RealType
//===----------------------------------------------------------------------===//
// `real` `<` kind `>`
mlir::Type fir::RealType::parse(mlir::AsmParser &parser) {
return parseKindSingleton<fir::RealType>(parser);
}
void fir::RealType::print(mlir::AsmPrinter &printer) const {
printer << "<" << getFKind() << '>';
}
llvm::LogicalResult
fir::RealType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
KindTy fKind) {
// TODO
return mlir::success();
}
mlir::Type fir::RealType::getFloatType(const fir::KindMapping &kindMap) const {
auto fkind = getFKind();
auto realTypeID = kindMap.getRealTypeID(fkind);
return fir::fromRealTypeID(getContext(), realTypeID, fkind);
}
//===----------------------------------------------------------------------===//
// RecordType
//===----------------------------------------------------------------------===//
@ -1367,10 +1304,10 @@ bool fir::BaseBoxType::isAssumedRank() const {
void FIROpsDialect::registerTypes() {
addTypes<BoxType, BoxCharType, BoxProcType, CharacterType, ClassType,
fir::ComplexType, FieldType, HeapType, fir::IntegerType, LenType,
LogicalType, LLVMPointerType, PointerType, RealType, RecordType,
ReferenceType, SequenceType, ShapeType, ShapeShiftType, ShiftType,
SliceType, TypeDescType, fir::VectorType, fir::DummyScopeType>();
FieldType, HeapType, fir::IntegerType, LenType, LogicalType,
LLVMPointerType, PointerType, RecordType, ReferenceType,
SequenceType, ShapeType, ShapeShiftType, ShiftType, SliceType,
TypeDescType, fir::VectorType, fir::DummyScopeType>();
fir::ReferenceType::attachInterface<
OpenMPPointerLikeModel<fir::ReferenceType>>(*getContext());
fir::ReferenceType::attachInterface<
@ -1401,19 +1338,6 @@ fir::getTypeSizeAndAlignment(mlir::Location loc, mlir::Type ty,
unsigned short alignment = dl.getTypeABIAlignment(ty);
return std::pair{size, alignment};
}
if (auto firCmplx = mlir::dyn_cast<fir::ComplexType>(ty)) {
auto result =
getTypeSizeAndAlignment(loc, firCmplx.getEleType(kindMap), dl, kindMap);
if (!result)
return result;
auto [floatSize, floatAlign] = *result;
return std::pair{llvm::alignTo(floatSize, floatAlign) + floatSize,
floatAlign};
}
if (auto real = mlir::dyn_cast<fir::RealType>(ty))
return getTypeSizeAndAlignment(loc, real.getFloatType(kindMap), dl,
kindMap);
if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(ty)) {
auto result = getTypeSizeAndAlignment(loc, seqTy.getEleTy(), dl, kindMap);
if (!result)

View File

@ -380,9 +380,7 @@ llvm::LogicalResult hlfir::DesignateOp::verify() {
// length may differ because of substrings.
if (resultElementType != outputElementType &&
!(mlir::isa<fir::CharacterType>(resultElementType) &&
mlir::isa<fir::CharacterType>(outputElementType)) &&
!(mlir::isa<mlir::FloatType>(resultElementType) &&
mlir::isa<fir::RealType>(outputElementType)))
mlir::isa<fir::CharacterType>(outputElementType)))
return emitOpError(
"result element type is not consistent with operands, expected ")
<< outputElementType;

View File

@ -494,10 +494,6 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
} else if (mlir::isa<mlir::FloatType>(Ty)) {
return genBasicType(context, mlir::StringAttr::get(context, "real"),
Ty.getIntOrFloatBitWidth(), llvm::dwarf::DW_ATE_float);
} else if (auto realTy = mlir::dyn_cast_or_null<fir::RealType>(Ty)) {
return genBasicType(context, mlir::StringAttr::get(context, "real"),
kindMapping.getRealBitsize(realTy.getFKind()),
llvm::dwarf::DW_ATE_float);
} else if (auto logTy = mlir::dyn_cast_or_null<fir::LogicalType>(Ty)) {
return genBasicType(context,
mlir::StringAttr::get(context, logTy.getMnemonic()),

View File

@ -7,15 +7,6 @@ func.func @x() -> !fir.char<1,3> {
return %1 : !fir.char<1,3>
}
// CHECK-LABEL: define x86_fp80 @y()
func.func @y() -> !fir.real<10> {
%c1 = arith.constant 42.4 :f32
%0 = fir.convert %c1 : (f32) -> !fir.real<10>
// CHECK: ret x86_fp80 0xK4004A9999A0000000000
// TODO: What's that number?
return %0 : !fir.real<10>
}
// CHECK-LABEL: define i16 @z()
func.func @z() -> !fir.logical<2> {
%1 = arith.constant true

View File

@ -4,14 +4,12 @@
// Fortran Intrinsic types
// CHECK-LABEL: func private @it1() -> !fir.int<4>
// CHECK-LABEL: func private @it2() -> !fir.real<8>
// CHECK-LABEL: func private @it3() -> complex<f64>
// CHECK-LABEL: func private @it4() -> !fir.logical<1>
// CHECK-LABEL: func private @it5() -> !fir.char<1>
// CHECK-LABEL: func private @it6() -> !fir.char<2,10>
// CHECK-LABEL: func private @it7() -> !fir.char<4,?>
func.func private @it1() -> !fir.int<4>
func.func private @it2() -> !fir.real<8>
func.func private @it3() -> complex<f64>
func.func private @it4() -> !fir.logical<1>
func.func private @it5() -> !fir.char<1>

View File

@ -27,11 +27,6 @@ func.func private @it6() -> !fir.char<2, >
// -----
// expected-error@+1 {{expected integer value}}
func.func private @it3() -> !fir.complex<>
// -----
// expected-error@+1 {{expected non-function type}}
func.func private @mem3() -> !fir.heap<>
@ -52,11 +47,6 @@ func.func private @mem3() -> !fir.ptr<>
// -----
// expected-error@+1 {{expected integer value}}
func.func private @mem3() -> !fir.real<>
// -----
// expected-error@+1 {{expected valid keyword}}
func.func private @mem3() -> !fir.type<>

View File

@ -10,9 +10,8 @@
func.func @gen4() -> complex<f32> {
%1 = fir.undefined complex<f32>
%2 = arith.constant 2.0 : f32
%3 = fir.convert %2 : (f32) -> !fir.real<4>
%c0 = arith.constant 0 : i32
%4 = fir.insert_value %1, %3, [0 : index] : (complex<f32>, !fir.real<4>) -> complex<f32>
%4 = fir.insert_value %1, %2, [0 : index] : (complex<f32>, f32) -> complex<f32>
%c1 = arith.constant 1 : i32
%5 = arith.constant -42.0 : f32
%6 = fir.insert_value %4, %5, [1 : index] : (complex<f32>, f32) -> complex<f32>

View File

@ -329,30 +329,6 @@ func.func private @foo10(%arg0: !fir.vector<30:i64>)
// CHECK-LABEL: foo10
// CHECK-SAME: vector<30xi64>
func.func private @foo11(%arg0: !fir.vector<2:!fir.real<2>>)
// CHECK-LABEL: foo11
// CHECK-SAME: vector<2xf16>
func.func private @foo12(%arg0: !fir.vector<2:!fir.real<3>>)
// CHECK-LABEL: foo12
// CHECK-SAME: vector<2xbf16>
func.func private @foo13(%arg0: !fir.vector<2:!fir.real<4>>)
// CHECK-LABEL: foo13
// CHECK-SAME: vector<2xf32>
func.func private @foo14(%arg0: !fir.vector<2:!fir.real<8>>)
// CHECK-LABEL: foo14
// CHECK-SAME: vector<2xf64>
func.func private @foo15(%arg0: !fir.vector<2:!fir.real<10>>)
// CHECK-LABEL: foo15
// CHECK-SAME: vector<2xf80>
func.func private @foo16(%arg0: !fir.vector<2:!fir.real<16>>)
// CHECK-LABEL: foo16
// CHECK-SAME: vector<2xf128>
// -----
// Test `!fir.boxchar<n>` conversion

View File

@ -1,25 +0,0 @@
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s -o - | FileCheck %s
// This test checks that debug information for fir.real type works ok.
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
func.func @_QPfn1(%arg0: !fir.ref<complex<f64>> {fir.bindc_name = "a"} ) {
%0 = fir.declare %arg0 {uniq_name = "_QFfn1Ea"} : (!fir.ref<complex<f64>>) -> !fir.ref<complex<f64>>
%1 = fir.alloca f32 {bindc_name = "abserror", uniq_name = "_QFfn1Eabserror"}
%2 = fir.declare %1 {uniq_name = "_QFfn1Eabserror"} : (!fir.ref<f32>) -> !fir.ref<f32>
%3 = fir.load %0 : !fir.ref<complex<f64>>
%4 = fir.extract_value %3, [0 : i32] : (complex<f64>) -> !fir.real<8>
%5 = fir.extract_value %3, [1 : i32] : (complex<f64>) -> !fir.real<8>
%6 = fir.call @cabs(%4, %5) : (!fir.real<8>, !fir.real<8>) -> f64
%7 = fir.convert %6 : (f64) -> f32
fir.store %7 to %2 : !fir.ref<f32>
return
} loc(#loc1)
func.func private @cabs(!fir.real<8>, !fir.real<8>) -> f64 attributes {fir.bindc_name = "cabs", fir.runtime}
} loc(#loc)
#loc1 = loc("test.f90":5:1)
#loc = loc("test.f90":0:0)
// CHECK-DAG: #[[TY:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 64, encoding = DW_ATE_float>
// CHECK-DAG: #[[TY1:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[TY]], #[[TY]], #[[TY]]>
// CHECK-DAG: #{{.*}} = #llvm.di_subprogram<{{.*}}name = "cabs", linkageName = "cabs"{{.*}}, type = #[[TY1]]>