From b3d1f073de971f7597ba937d8065dbba56cd8fc7 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Wed, 23 Feb 2022 08:27:10 +0100 Subject: [PATCH] [flang] Lower real constant This patch handles lowering of real constant. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: PeteSteinfeld Differential Revision: https://reviews.llvm.org/D120354 Co-authored-by: Eric Schweitz Co-authored-by: Jean Perier --- flang/lib/Lower/ConvertExpr.cpp | 31 ++++++++++++++++++++++++++++++- flang/lib/Lower/ConvertType.cpp | 2 +- flang/test/Lower/assignment.f90 | 29 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp index 76bee21..013adb7 100644 --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -15,6 +15,7 @@ #include "flang/Evaluate/real.h" #include "flang/Evaluate/traverse.h" #include "flang/Lower/AbstractConverter.h" +#include "flang/Lower/ConvertType.h" #include "flang/Lower/IntrinsicCall.h" #include "flang/Lower/SymbolMap.h" #include "flang/Lower/Todo.h" @@ -138,6 +139,14 @@ public: return builder.createBool(getLoc(), value); } + /// Generate a real constant with a value `value`. + template + mlir::Value genRealConstant(mlir::MLIRContext *context, + const llvm::APFloat &value) { + mlir::Type fltTy = Fortran::lower::convertReal(context, KIND); + return builder.createRealConstant(getLoc(), fltTy, value); + } + /// Returns a reference to a symbol or its box/boxChar descriptor if it has /// one. ExtValue gen(Fortran::semantics::SymbolRef sym) { @@ -350,7 +359,27 @@ public: } else if constexpr (TC == Fortran::common::TypeCategory::Logical) { return genBoolConstant(value.IsTrue()); } else if constexpr (TC == Fortran::common::TypeCategory::Real) { - TODO(getLoc(), "genval real constant"); + std::string str = value.DumpHexadecimal(); + if constexpr (KIND == 2) { + llvm::APFloat floatVal{llvm::APFloatBase::IEEEhalf(), str}; + return genRealConstant(builder.getContext(), floatVal); + } else if constexpr (KIND == 3) { + llvm::APFloat floatVal{llvm::APFloatBase::BFloat(), str}; + return genRealConstant(builder.getContext(), floatVal); + } else if constexpr (KIND == 4) { + llvm::APFloat floatVal{llvm::APFloatBase::IEEEsingle(), str}; + return genRealConstant(builder.getContext(), floatVal); + } else if constexpr (KIND == 10) { + llvm::APFloat floatVal{llvm::APFloatBase::x87DoubleExtended(), str}; + return genRealConstant(builder.getContext(), floatVal); + } else if constexpr (KIND == 16) { + llvm::APFloat floatVal{llvm::APFloatBase::IEEEquad(), str}; + return genRealConstant(builder.getContext(), floatVal); + } else { + // convert everything else to double + llvm::APFloat floatVal{llvm::APFloatBase::IEEEdouble(), str}; + return genRealConstant(builder.getContext(), floatVal); + } } else if constexpr (TC == Fortran::common::TypeCategory::Complex) { TODO(getLoc(), "genval complex constant"); } else /*constexpr*/ { diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp index 39424d3..429fae8 100644 --- a/flang/lib/Lower/ConvertType.cpp +++ b/flang/lib/Lower/ConvertType.cpp @@ -520,7 +520,7 @@ mlir::Type Fortran::lower::translateVariableToFIRType( } mlir::Type Fortran::lower::convertReal(mlir::MLIRContext *context, int kind) { - return genFIRType(context, kind); + return genRealType(context, kind); } mlir::Type Fortran::lower::getSequenceRefType(mlir::Type refType) { diff --git a/flang/test/Lower/assignment.f90 b/flang/test/Lower/assignment.f90 index ce9689a..26aa336 100644 --- a/flang/test/Lower/assignment.f90 +++ b/flang/test/Lower/assignment.f90 @@ -255,3 +255,32 @@ end ! CHECK: fir.store %[[DIV]] to %[[FCTRES]] : !fir.ref> ! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref> ! CHECK: return %[[RET]] : !fir.complex<4> + +subroutine real_constant() + real(2) :: a + real(4) :: b + real(8) :: c + real(10) :: d + real(16) :: e + a = 2.0_2 + b = 4.0_4 + c = 8.0_8 + d = 10.0_10 + e = 16.0_16 +end + +! CHECK: %[[A:.*]] = fir.alloca f16 +! CHECK: %[[B:.*]] = fir.alloca f32 +! CHECK: %[[C:.*]] = fir.alloca f64 +! CHECK: %[[D:.*]] = fir.alloca f80 +! CHECK: %[[E:.*]] = fir.alloca f128 +! CHECK: %[[C2:.*]] = arith.constant 2.000000e+00 : f16 +! CHECK: fir.store %[[C2]] to %[[A]] : !fir.ref +! CHECK: %[[C4:.*]] = arith.constant 4.000000e+00 : f32 +! CHECK: fir.store %[[C4]] to %[[B]] : !fir.ref +! CHECK: %[[C8:.*]] = arith.constant 8.000000e+00 : f64 +! CHECK: fir.store %[[C8]] to %[[C]] : !fir.ref +! CHECK: %[[C10:.*]] = arith.constant 1.000000e+01 : f80 +! CHECK: fir.store %[[C10]] to %[[D]] : !fir.ref +! CHECK: %[[C16:.*]] = arith.constant 1.600000e+01 : f128 +! CHECK: fir.store %[[C16]] to %[[E]] : !fir.ref -- 2.7.4