From 39377d52273edb53a371f32a862df82f6b7f239d Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Fri, 1 Jul 2022 08:29:19 +0200 Subject: [PATCH] [flang] Fix APFloat conversion cases This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: PeteSteinfeld Differential Revision: https://reviews.llvm.org/D128935 Co-authored-by: Eric Schweitz Co-authored-by: Peter Steinfeld --- flang/lib/Lower/Allocatable.cpp | 6 +- flang/lib/Lower/Bridge.cpp | 32 +++++----- flang/lib/Lower/CallInterface.cpp | 2 +- flang/lib/Lower/ConvertExpr.cpp | 63 ++++++++++++------- flang/lib/Lower/ConvertType.cpp | 16 +++-- flang/lib/Lower/ConvertVariable.cpp | 4 +- flang/lib/Lower/CustomIntrinsicCall.cpp | 3 +- flang/lib/Lower/IO.cpp | 2 +- flang/lib/Optimizer/CodeGen/TargetRewrite.cpp | 2 +- 9 files changed, 72 insertions(+), 58 deletions(-) diff --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp index 0bd2cb250ef9..01a13b8555fa 100644 --- a/flang/lib/Lower/Allocatable.cpp +++ b/flang/lib/Lower/Allocatable.cpp @@ -462,13 +462,13 @@ private: } void genSourceAllocation(const Allocation &, const fir::MutableBoxValue &) { - TODO(loc, "SOURCE allocation lowering"); + TODO(loc, "SOURCE allocation"); } void genMoldAllocation(const Allocation &, const fir::MutableBoxValue &) { - TODO(loc, "MOLD allocation lowering"); + TODO(loc, "MOLD allocation"); } void genSetType(const Allocation &, const fir::MutableBoxValue &) { - TODO(loc, "polymorphic entity allocation lowering"); + TODO(loc, "polymorphic entity allocation"); } /// Returns a pointer to the DeclTypeSpec if a type-spec is provided in the diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index b61660fccca3..05fbf3aa4c1e 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -773,7 +773,7 @@ private: Fortran::lower::SymbolBox resultSymBox = lookupSymbol(resultSym); mlir::Location loc = toLocation(); if (!resultSymBox) { - mlir::emitError(loc, "failed lowering function return"); + mlir::emitError(loc, "internal error when processing function return"); return; } mlir::Value resultVal = resultSymBox.match( @@ -1857,56 +1857,56 @@ private: void genFIR(const Fortran::parser::BlockConstruct &blockConstruct) { setCurrentPositionAt(blockConstruct); - TODO(toLocation(), "BlockConstruct lowering"); + TODO(toLocation(), "BlockConstruct implementation"); } void genFIR(const Fortran::parser::BlockStmt &) { - TODO(toLocation(), "BlockStmt lowering"); + TODO(toLocation(), "BlockStmt implementation"); } void genFIR(const Fortran::parser::EndBlockStmt &) { - TODO(toLocation(), "EndBlockStmt lowering"); + TODO(toLocation(), "EndBlockStmt implementation"); } void genFIR(const Fortran::parser::ChangeTeamConstruct &construct) { - TODO(toLocation(), "ChangeTeamConstruct lowering"); + TODO(toLocation(), "ChangeTeamConstruct implementation"); } void genFIR(const Fortran::parser::ChangeTeamStmt &stmt) { - TODO(toLocation(), "ChangeTeamStmt lowering"); + TODO(toLocation(), "ChangeTeamStmt implementation"); } void genFIR(const Fortran::parser::EndChangeTeamStmt &stmt) { - TODO(toLocation(), "EndChangeTeamStmt lowering"); + TODO(toLocation(), "EndChangeTeamStmt implementation"); } void genFIR(const Fortran::parser::CriticalConstruct &criticalConstruct) { setCurrentPositionAt(criticalConstruct); - TODO(toLocation(), "CriticalConstruct lowering"); + TODO(toLocation(), "CriticalConstruct implementation"); } void genFIR(const Fortran::parser::CriticalStmt &) { - TODO(toLocation(), "CriticalStmt lowering"); + TODO(toLocation(), "CriticalStmt implementation"); } void genFIR(const Fortran::parser::EndCriticalStmt &) { - TODO(toLocation(), "EndCriticalStmt lowering"); + TODO(toLocation(), "EndCriticalStmt implementation"); } void genFIR(const Fortran::parser::SelectRankConstruct &selectRankConstruct) { setCurrentPositionAt(selectRankConstruct); - TODO(toLocation(), "SelectRankConstruct lowering"); + TODO(toLocation(), "SelectRankConstruct implementation"); } void genFIR(const Fortran::parser::SelectRankStmt &) { - TODO(toLocation(), "SelectRankStmt lowering"); + TODO(toLocation(), "SelectRankStmt implementation"); } void genFIR(const Fortran::parser::SelectRankCaseStmt &) { - TODO(toLocation(), "SelectRankCaseStmt lowering"); + TODO(toLocation(), "SelectRankCaseStmt implementation"); } void genFIR(const Fortran::parser::SelectTypeConstruct &selectTypeConstruct) { setCurrentPositionAt(selectTypeConstruct); - TODO(toLocation(), "SelectTypeConstruct lowering"); + TODO(toLocation(), "SelectTypeConstruct implementation"); } void genFIR(const Fortran::parser::SelectTypeStmt &) { - TODO(toLocation(), "SelectTypeStmt lowering"); + TODO(toLocation(), "SelectTypeStmt implementation"); } void genFIR(const Fortran::parser::TypeGuardStmt &) { - TODO(toLocation(), "TypeGuardStmt lowering"); + TODO(toLocation(), "TypeGuardStmt implementation"); } //===--------------------------------------------------------------------===// diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp index 18911e865ce6..34b7e978ac12 100644 --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -792,7 +792,7 @@ private: if (cat == Fortran::common::TypeCategory::Derived) { if (dynamicType.IsPolymorphic()) TODO(interface.converter.getCurrentLocation(), - "[translateDynamicType] polymorphic types"); + "support for polymorphic types"); return getConverter().genType(dynamicType.GetDerivedTypeSpec()); } // CHARACTER with compile time constant length. diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp index 8f4b5ae96c58..ebc2a3c62006 100644 --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -387,8 +387,7 @@ static fir::ExtendedValue genLoad(fir::FirOpBuilder &builder, [&](const fir::BoxValue &box) -> fir::ExtendedValue { if (box.isUnlimitedPolymorphic()) fir::emitFatalError( - loc, - "lowering attempting to load an unlimited polymorphic entity"); + loc, "attempting to load an unlimited polymorphic entity"); return genLoad(builder, loc, fir::factory::readBoxValue(builder, loc, box)); }, @@ -1398,23 +1397,24 @@ public: } else if constexpr (TC == Fortran::common::TypeCategory::Real) { std::string str = value.DumpHexadecimal(); if constexpr (KIND == 2) { - llvm::APFloat floatVal{llvm::APFloatBase::IEEEhalf(), str}; + auto floatVal = consAPFloat(llvm::APFloatBase::IEEEhalf(), str); return genRealConstant(builder.getContext(), floatVal); } else if constexpr (KIND == 3) { - llvm::APFloat floatVal{llvm::APFloatBase::BFloat(), str}; + auto floatVal = consAPFloat(llvm::APFloatBase::BFloat(), str); return genRealConstant(builder.getContext(), floatVal); } else if constexpr (KIND == 4) { - llvm::APFloat floatVal{llvm::APFloatBase::IEEEsingle(), str}; + auto floatVal = consAPFloat(llvm::APFloatBase::IEEEsingle(), str); return genRealConstant(builder.getContext(), floatVal); } else if constexpr (KIND == 10) { - llvm::APFloat floatVal{llvm::APFloatBase::x87DoubleExtended(), str}; + auto floatVal = + consAPFloat(llvm::APFloatBase::x87DoubleExtended(), str); return genRealConstant(builder.getContext(), floatVal); } else if constexpr (KIND == 16) { - llvm::APFloat floatVal{llvm::APFloatBase::IEEEquad(), str}; + auto floatVal = consAPFloat(llvm::APFloatBase::IEEEquad(), str); return genRealConstant(builder.getContext(), floatVal); } else { // convert everything else to double - llvm::APFloat floatVal{llvm::APFloatBase::IEEEdouble(), str}; + auto floatVal = consAPFloat(llvm::APFloatBase::IEEEdouble(), str); return genRealConstant(builder.getContext(), floatVal); } } else if constexpr (TC == Fortran::common::TypeCategory::Complex) { @@ -1431,6 +1431,23 @@ public: } } + /// Convert string, \p s, to an APFloat value. Recognize and handle Inf and + /// NaN strings as well. \p s is assumed to not contain any spaces. + static llvm::APFloat consAPFloat(const llvm::fltSemantics &fsem, + llvm::StringRef s) { + assert(s.find(' ') == llvm::StringRef::npos); + if (s.compare_insensitive("-inf") == 0) + return llvm::APFloat::getInf(fsem, /*negative=*/true); + if (s.compare_insensitive("inf") == 0 || s.compare_insensitive("+inf") == 0) + return llvm::APFloat::getInf(fsem); + // TODO: Add support for quiet and signaling NaNs. + if (s.compare_insensitive("-nan") == 0) + return llvm::APFloat::getNaN(fsem, /*negative=*/true); + if (s.compare_insensitive("nan") == 0 || s.compare_insensitive("+nan") == 0) + return llvm::APFloat::getNaN(fsem); + return {fsem, s}; + } + /// Generate a raw literal value and store it in the rawVals vector. template void @@ -1448,18 +1465,19 @@ public: } else if constexpr (TC == Fortran::common::TypeCategory::Real) { std::string str = value.DumpHexadecimal(); inInitializer->rawType = converter.genType(TC, KIND); - llvm::APFloat floatVal{builder.getKindMap().getFloatSemantics(KIND), str}; + auto floatVal = + consAPFloat(builder.getKindMap().getFloatSemantics(KIND), str); val = builder.getFloatAttr(inInitializer->rawType, floatVal); } else if constexpr (TC == Fortran::common::TypeCategory::Complex) { std::string strReal = value.REAL().DumpHexadecimal(); std::string strImg = value.AIMAG().DumpHexadecimal(); inInitializer->rawType = converter.genType(TC, KIND); - llvm::APFloat realVal{builder.getKindMap().getFloatSemantics(KIND), - strReal}; + auto realVal = + consAPFloat(builder.getKindMap().getFloatSemantics(KIND), strReal); val = builder.getFloatAttr(inInitializer->rawType, realVal); inInitializer->rawVals.push_back(val); - llvm::APFloat imgVal{builder.getKindMap().getFloatSemantics(KIND), - strImg}; + auto imgVal = + consAPFloat(builder.getKindMap().getFloatSemantics(KIND), strImg); val = builder.getFloatAttr(inInitializer->rawType, imgVal); } inInitializer->rawVals.push_back(val); @@ -1685,8 +1703,7 @@ public: template ExtValue genval(const Fortran::evaluate::ArrayConstructor &) { - fir::emitFatalError(getLoc(), - "array constructor: lowering should not reach here"); + fir::emitFatalError(getLoc(), "array constructor: should not reach here"); } ExtValue gen(const Fortran::evaluate::ComplexPart &x) { @@ -1867,7 +1884,7 @@ public: return genval(*sub); return genIntegerConstant<8>(builder.getContext(), 1); } - TODO(getLoc(), "non explicit semantics::Bound lowering"); + TODO(getLoc(), "non explicit semantics::Bound implementation"); } static bool isSlice(const Fortran::evaluate::ArrayRef &aref) { @@ -1997,7 +2014,7 @@ public: loc, "internal: BoxValue in dim-collapsed fir.coordinate_of"); }, [&](const auto &) -> ExtValue { - fir::emitFatalError(loc, "internal: array lowering failed"); + fir::emitFatalError(loc, "internal: array processing failed"); }); } @@ -2579,9 +2596,9 @@ public: bool callingImplicitInterface = caller.canBeCalledViaImplicitInterface(); for (auto [fst, snd] : llvm::zip(caller.getInputs(), funcType.getInputs())) { - // When passing arguments to a procedure that can be called an implicit - // interface, allow character actual arguments to be passed to dummy - // arguments of any type and vice versa + // When passing arguments to a procedure that can be called by implicit + // interface, allow any character actual arguments to be passed to dummy + // arguments of any type and vice versa. mlir::Value cast; auto *context = builder.getContext(); if (snd.isa() && @@ -2994,7 +3011,7 @@ public: } const auto *expr = actual->UnwrapExpr(); if (!expr) - TODO(loc, "assumed type actual argument lowering"); + TODO(loc, "assumed type actual argument"); if (arg.passBy == PassBy::Value) { ExtValue argVal = genval(*expr); @@ -4832,7 +4849,7 @@ private: // a potentially absent argument to something else than a value (apart // from character MAX/MIN that are handled elsewhere.) if (argRules.lowerAs != Fortran::lower::LowerIntrinsicArgAs::Value) - TODO(loc, "lowering non trivial optional elemental intrinsic array " + TODO(loc, "non trivial optional elemental intrinsic array " "argument"); PushSemantics(ConstituentSemantics::RefTransparent); operands.emplace_back(genarrForwardOptionalArgumentToCall(*expr)); @@ -4905,7 +4922,7 @@ private: } const auto *expr = actual->UnwrapExpr(); if (!expr) - TODO(loc, "assumed type actual argument lowering"); + TODO(loc, "assumed type actual argument"); LLVM_DEBUG(expr->AsFortran(llvm::dbgs() << "argument: " << arg.firArgument << " = [") diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp index f32504d67f3c..783019dfdb47 100644 --- a/flang/lib/Lower/ConvertType.cpp +++ b/flang/lib/Lower/ConvertType.cpp @@ -160,8 +160,7 @@ struct TypeBuilder { // Use unknown extents. int rank = expr.Rank(); if (rank < 0) - TODO(converter.getCurrentLocation(), - "assumed rank expression type lowering"); + TODO(converter.getCurrentLocation(), "assumed rank expression types"); for (int dim = 0; dim < rank; ++dim) shape.emplace_back(fir::SequenceType::getUnknownExtent()); } @@ -207,7 +206,7 @@ struct TypeBuilder { using T = std::decay_t; static_assert(!Fortran::common::HasMember< T, Fortran::evaluate::TypelessExpression>, - "missing typeless expr handling in type lowering"); + "missing typeless expr handling"); llvm::report_fatal_error("not a typeless expression"); }, }, @@ -235,7 +234,7 @@ struct TypeBuilder { translateLenParameters(params, tySpec->category(), ultimate); ty = genFIRType(context, tySpec->category(), kind, params); } else if (type->IsPolymorphic()) { - TODO(loc, "[genSymbolType] polymorphic types"); + TODO(loc, "support for polymorphic types"); } else if (const Fortran::semantics::DerivedTypeSpec *tySpec = type->AsDerived()) { ty = genDerivedType(*tySpec); @@ -249,7 +248,7 @@ struct TypeBuilder { auto shapeExpr = Fortran::evaluate::GetShapeHelper{ converter.getFoldingContext()}(ultimate); if (!shapeExpr) - TODO(loc, "assumed rank symbol type lowering"); + TODO(loc, "assumed rank symbol type"); fir::SequenceType::Shape shape; translateShape(shape, std::move(*shapeExpr)); ty = fir::SequenceType::get(shape, ty); @@ -302,7 +301,7 @@ struct TypeBuilder { // Catch any situations where this is not true for now. if (componentHasNonDefaultLowerBounds(field)) TODO(converter.genLocation(field.name()), - "lowering derived type components with non default lower bounds"); + "derived type components with non default lower bounds"); if (IsProcedure(field)) TODO(converter.genLocation(field.name()), "procedure components"); mlir::Type ty = genSymbolType(field); @@ -328,7 +327,7 @@ struct TypeBuilder { if (!ps.empty()) { // This type is a PDT (parametric derived type). Create the functions to // use for allocation, dereferencing, and address arithmetic here. - TODO(loc, "parameterized derived types lowering"); + TODO(loc, "parameterized derived types"); } LLVM_DEBUG(llvm::dbgs() << "derived type: " << rec << '\n'); @@ -364,8 +363,7 @@ struct TypeBuilder { if (category == Fortran::common::TypeCategory::Character) params.push_back(getCharacterLength(exprOrSym)); else if (category == Fortran::common::TypeCategory::Derived) - TODO(converter.getCurrentLocation(), - "lowering derived type length parameters"); + TODO(converter.getCurrentLocation(), "derived type length parameters"); return; } Fortran::lower::LenParameterTy diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index b5430f9a1f27..1f66594d3f7e 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -123,7 +123,7 @@ static fir::GlobalOp declareGlobal(Fortran::lower::AbstractConverter &converter, const Fortran::semantics::Symbol &ultimate = sym.GetUltimate(); if (!ultimate.has() && !Fortran::semantics::IsProcedurePointer(ultimate)) - mlir::emitError(loc, "lowering global declaration: symbol '") + mlir::emitError(loc, "processing global declaration: symbol '") << toStringRef(sym.name()) << "' has unexpected details\n"; return builder.createGlobal(loc, converter.genType(var), globalName, linkage, mlir::Attribute{}, isConstant(ultimate)); @@ -1410,7 +1410,7 @@ void Fortran::lower::mapSymbolAttributes( auto expr = Fortran::lower::SomeExpr{*low}; lb = builder.createConvert(loc, idxTy, genValue(expr)); } else { - TODO(loc, "assumed rank lowering"); + TODO(loc, "support for assumed rank entities"); } lbounds.emplace_back(lb); diff --git a/flang/lib/Lower/CustomIntrinsicCall.cpp b/flang/lib/Lower/CustomIntrinsicCall.cpp index 1127e2841b04..043b1ccf7474 100644 --- a/flang/lib/Lower/CustomIntrinsicCall.cpp +++ b/flang/lib/Lower/CustomIntrinsicCall.cpp @@ -92,8 +92,7 @@ static void prepareMinOrMaxArguments( mlir::Type resultType = *retTy; mlir::Location loc = converter.getCurrentLocation(); if (fir::isa_char(resultType)) - TODO(loc, - "CHARACTER MIN and MAX lowering with dynamically optional arguments"); + TODO(loc, "CHARACTER MIN and MAX with dynamically optional arguments"); for (auto arg : llvm::enumerate(procRef.arguments())) { const auto *expr = Fortran::evaluate::UnwrapExpr(arg.value()); diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp index b3bc3a92edde..fdf001dde451 100644 --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -1538,7 +1538,7 @@ getBuffer(Fortran::lower::AbstractConverter &converter, mlir::Location loc, if (auto *var = std::get_if(&iounit->u)) if (auto *expr = Fortran::semantics::GetExpr(*var)) return genBuffer(converter, loc, *expr, strTy, lenTy, stmtCtx); - llvm::report_fatal_error("failed to get IoUnit expr in lowering"); + llvm::report_fatal_error("failed to get IoUnit expr"); } static mlir::Value genIOUnitNumber(Fortran::lower::AbstractConverter &converter, diff --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp index f1e58d42779e..cc1e5ed3ceee 100644 --- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp +++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp @@ -119,7 +119,7 @@ public: auto m = specifics->complexReturnType(loc, ty.getElementType()); // Currently targets mandate COMPLEX is a single aggregate or packed // scalar, including the sret case. - assert(m.size() == 1 && "target lowering of complex return not supported"); + assert(m.size() == 1 && "target of complex return not supported"); auto resTy = std::get(m[0]); auto attr = std::get(m[0]); if (attr.isSRet()) {