[flang-commits] [flang] b3d1f07 - [flang] Lower real constant
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Tue Feb 22 23:28:08 PST 2022
Author: Valentin Clement
Date: 2022-02-23T08:27:54+01:00
New Revision: b3d1f073de971f7597ba937d8065dbba56cd8fc7
URL: https://github.com/llvm/llvm-project/commit/b3d1f073de971f7597ba937d8065dbba56cd8fc7
DIFF: https://github.com/llvm/llvm-project/commit/b3d1f073de971f7597ba937d8065dbba56cd8fc7.diff
LOG: [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 <eschweitz at nvidia.com>
Co-authored-by: Jean Perier <jperier at nvidia.com>
Added:
Modified:
flang/lib/Lower/ConvertExpr.cpp
flang/lib/Lower/ConvertType.cpp
flang/test/Lower/assignment.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index 76bee213c96b6..013adb797da93 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 @@ class ScalarExprLowering {
return builder.createBool(getLoc(), value);
}
+ /// Generate a real constant with a value `value`.
+ template <int KIND>
+ 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 @@ class ScalarExprLowering {
} 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<KIND>(builder.getContext(), floatVal);
+ } else if constexpr (KIND == 3) {
+ llvm::APFloat floatVal{llvm::APFloatBase::BFloat(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ } else if constexpr (KIND == 4) {
+ llvm::APFloat floatVal{llvm::APFloatBase::IEEEsingle(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ } else if constexpr (KIND == 10) {
+ llvm::APFloat floatVal{llvm::APFloatBase::x87DoubleExtended(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ } else if constexpr (KIND == 16) {
+ llvm::APFloat floatVal{llvm::APFloatBase::IEEEquad(), str};
+ return genRealConstant<KIND>(builder.getContext(), floatVal);
+ } else {
+ // convert everything else to double
+ llvm::APFloat floatVal{llvm::APFloatBase::IEEEdouble(), str};
+ return genRealConstant<KIND>(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 39424d3ff0b0a..429fae81e25cc 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<Fortran::common::TypeCategory::Real>(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 ce9689a708a8f..26aa33631d0e4 100644
--- a/flang/test/Lower/assignment.f90
+++ b/flang/test/Lower/assignment.f90
@@ -255,3 +255,32 @@ real function divf(a, b)
! CHECK: fir.store %[[DIV]] to %[[FCTRES]] : !fir.ref<!fir.complex<4>>
! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<!fir.complex<4>>
! 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<f16>
+! CHECK: %[[C4:.*]] = arith.constant 4.000000e+00 : f32
+! CHECK: fir.store %[[C4]] to %[[B]] : !fir.ref<f32>
+! CHECK: %[[C8:.*]] = arith.constant 8.000000e+00 : f64
+! CHECK: fir.store %[[C8]] to %[[C]] : !fir.ref<f64>
+! CHECK: %[[C10:.*]] = arith.constant 1.000000e+01 : f80
+! CHECK: fir.store %[[C10]] to %[[D]] : !fir.ref<f80>
+! CHECK: %[[C16:.*]] = arith.constant 1.600000e+01 : f128
+! CHECK: fir.store %[[C16]] to %[[E]] : !fir.ref<f128>
More information about the flang-commits
mailing list