From 0ff322246bcd5c20fdda5e6d1215ee961db2abdc Mon Sep 17 00:00:00 2001 From: PeixinQiao Date: Thu, 14 Apr 2022 21:28:30 +0800 Subject: [PATCH] [flang] Fix float-number representation bug The float number is represented as (-1)^s * 1.f * 2^(-127) for 32-bit, where s is the signed flag, f is the mantissa. When the exponent bits are all zeros, the float number is represented as (-1)^s * 0.f *2^(-126) for 32-bit, in which case, the intPart is '0'. Reviewed By: Jean Perier https://reviews.llvm.org/D123673 --- flang/lib/Evaluate/real.cpp | 3 +++ flang/test/Lower/Intrinsics/real.f90 | 20 ++++++++++++++++++++ flang/unittests/Evaluate/real.cpp | 4 ++-- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 flang/test/Lower/Intrinsics/real.f90 diff --git a/flang/lib/Evaluate/real.cpp b/flang/lib/Evaluate/real.cpp index eb6bd14..b8ce0ff 100644 --- a/flang/lib/Evaluate/real.cpp +++ b/flang/lib/Evaluate/real.cpp @@ -639,6 +639,9 @@ template std::string Real::DumpHexadecimal() const { } result += 'p'; int exponent = Exponent() - exponentBias; + if (intPart == '0') { + exponent += 1; + } result += Integer<32>{exponent}.SignedDecimal(); return result; } diff --git a/flang/test/Lower/Intrinsics/real.f90 b/flang/test/Lower/Intrinsics/real.f90 new file mode 100644 index 0000000..7b9fab8 --- /dev/null +++ b/flang/test/Lower/Intrinsics/real.f90 @@ -0,0 +1,20 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +! Tests REAL lowering +subroutine test_real() + real(4) :: r4 + real(8) :: r8 + + r4 = real(z'40', kind=4) + r8 = real(z'40', kind=8) + +end subroutine + +! CHECK-LABEL: func @_QPtest_real() { +! CHECK: %[[VAL_0:.*]] = fir.alloca f32 {bindc_name = "r4", uniq_name = "_QFtest_realEr4"} +! CHECK: %[[VAL_1:.*]] = fir.alloca f64 {bindc_name = "r8", uniq_name = "_QFtest_realEr8"} +! CHECK: %[[CST_0:.*]] = arith.constant 8.968310e-44 : f32 +! CHECK: fir.store %[[CST_0]] to %[[VAL_0]] : !fir.ref +! CHECK: %[[CST_1:.*]] = arith.constant 3.162020e-322 : f64 +! CHECK: fir.store %[[CST_1]] to %[[VAL_1]] : !fir.ref +! CHECK: return diff --git a/flang/unittests/Evaluate/real.cpp b/flang/unittests/Evaluate/real.cpp index af06e7a..1974f42 100644 --- a/flang/unittests/Evaluate/real.cpp +++ b/flang/unittests/Evaluate/real.cpp @@ -35,8 +35,8 @@ void dumpTest() { {0x3f000000, "0x1.0p-1"}, {0x7f7fffff, "0x1.fffffep127"}, {0x00800000, "0x1.0p-126"}, - {0x00400000, "0x0.8p-127"}, - {0x00000001, "0x0.000002p-127"}, + {0x00400000, "0x0.8p-126"}, + {0x00000001, "0x0.000002p-126"}, {0, nullptr}, }; for (int j{0}; table[j].expected != nullptr; ++j) { -- 2.7.4