[flang-commits] [flang] [flang] Fix REAL(10) Read() endianness for big-endian hosts (PR #234842)

via flang-commits flang-commits at lists.llvm.org
Thu Oct 22 21:59:14 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Kelvin Li (kkwli)

<details>
<summary>Changes</summary>

On big-endian hosts (e.g. AIX), reinterpret_casting a uint128_t onto X87IntegerContainer misaligns the 80-bit x87 value, making every decimal-to-binary conversion return zero. Build Word via the Integer<> integer constructor instead, which uses SetLEPart() internally and is endian-portable. Also remove test expectations that reflected the bug.

https://github.com/llvm/llvm-project/pull/216958 exposes this bug and cause the following failures on AIX:
```
Failed Tests (3):
  flang-Unit :: Evaluate/./FlangEvaluateTests/RealValueKind/RealValueKind/AsFortran/REAL_10
  flang-Unit :: Evaluate/./FlangEvaluateTests/RealValueKind/RealValueKind/FromIntegerPowersOfTwo/REAL_10
  flang-Unit :: Evaluate/./FlangEvaluateTests/RealValueKind/RealValueKind/Read/REAL_10
```

https://lab.llvm.org/buildbot/#/builders/231/builds/2026

Assisted-by: IBM Bob

---
Full diff: https://github.com/llvm/llvm-project/pull/234842.diff


3 Files Affected:

- (modified) flang/lib/Evaluate/real.cpp (+13-2) 
- (modified) flang/test/Semantics/kinds04_q10.f90 (+1-4) 
- (modified) flang/test/Semantics/kinds04_q16.f90 (+1-4) 


``````````diff
diff --git a/flang/lib/Evaluate/real.cpp b/flang/lib/Evaluate/real.cpp
index b5413c9cb9129..f927cef7358d5 100644
--- a/flang/lib/Evaluate/real.cpp
+++ b/flang/lib/Evaluate/real.cpp
@@ -673,8 +673,19 @@ ValueWithRealFlags<Real<W, P>> Real<W, P>::Read(
     const char *&p, Rounding rounding) {
   auto converted{
       decimal::ConvertToBinary<P>(p, MapRoundingMode(rounding.mode))};
-  const auto *value{reinterpret_cast<Real<W, P> *>(&converted.binary)};
-  return {*value, MapFlags(converted.flags)};
+  // Building Word from lo/hi uint64_t halves via the Integer<> integer
+  // constructor is endian-portable
+  auto raw{converted.binary.raw()};
+  const std::uint64_t lo{static_cast<std::uint64_t>(raw)};
+  Word word{lo};
+  if constexpr (sizeof(typename decltype(converted.binary)::RawType) >
+      sizeof(std::uint64_t)) {
+    const std::uint64_t hi{static_cast<std::uint64_t>(raw >> 64)};
+    if (hi) {
+      word = word.IOR(Word{hi}.SHIFTL(64));
+    }
+  }
+  return {Real<W, P>{word}, MapFlags(converted.flags)};
 }
 
 template <typename W, int P> std::string Real<W, P>::DumpHexadecimal() const {
diff --git a/flang/test/Semantics/kinds04_q10.f90 b/flang/test/Semantics/kinds04_q10.f90
index 3bec7a386585b..118ce60071fcf 100644
--- a/flang/test/Semantics/kinds04_q10.f90
+++ b/flang/test/Semantics/kinds04_q10.f90
@@ -1,5 +1,5 @@
 ! RUN: not %flang_fc1 %s 2>%t.stderr
-! RUN: FileCheck %s --input-file=%t.stderr --check-prefixes=PORTABILITY,ERROR,WARNING%if system-aix %{,AIX_WARNING%}
+! RUN: FileCheck %s --input-file=%t.stderr --check-prefixes=PORTABILITY,ERROR,WARNING
 ! C716 If both kind-param and exponent-letter appear, exponent-letter
 ! shall be E. (As an extension we also allow an exponent-letter which matches
 ! the kind-param)
@@ -13,12 +13,10 @@ subroutine s(var)
   !PORTABILITY: Explicit kind parameter together with non-'E' exponent letter is not standard
   real :: realvar4 = 4.0D6_8
   !WARNING: Explicit kind parameter on real constant disagrees with exponent letter 'q'
-  !AIX_WARNING: underflow on REAL(10) to REAL(4) conversion
   real :: realvar5 = 4.0Q6_10
   !PORTABILITY: Explicit kind parameter together with non-'E' exponent letter is not standard
   real :: realvar6 = 4.0Q6_16
   real :: realvar7 = 4.0E6_8
-  !AIX_WARNING: underflow on REAL(10) to REAL(4) conversion
   real :: realvar8 = 4.0E6_10
   real :: realvar9 = 4.0E6_16
   !ERROR: Unsupported REAL(KIND=32)
@@ -32,7 +30,6 @@ subroutine s(var)
   !PORTABILITY: Explicit kind parameter together with non-'E' exponent letter is not standard
   double precision :: doublevar5 = 4.0Q6_16
   double precision :: doublevar6 = 4.0E6_8
-  !AIX_WARNING: underflow on REAL(10) to REAL(8) conversion
   double precision :: doublevar7 = 4.0E6_10
   double precision :: doublevar8 = 4.0E6_16
   !ERROR: Unsupported REAL(KIND=32)
diff --git a/flang/test/Semantics/kinds04_q16.f90 b/flang/test/Semantics/kinds04_q16.f90
index d440fa4d1402d..d18191a8366b3 100644
--- a/flang/test/Semantics/kinds04_q16.f90
+++ b/flang/test/Semantics/kinds04_q16.f90
@@ -1,5 +1,5 @@
 ! RUN: not %flang_fc1 %s 2>%t.stderr
-! RUN: FileCheck %s --input-file=%t.stderr --check-prefixes=%if system-aix %{"PORTABILITY","WARNING","ERROR","AIX_WARNING"%} %else %{"PORTABILITY","WARNING","ERROR"%}
+! RUN: FileCheck %s --input-file=%t.stderr --check-prefixes=PORTABILITY,WARNING,ERROR
 ! C716 If both kind-param and exponent-letter appear, exponent-letter
 ! shall be E. (As an extension we also allow an exponent-letter which matches
 ! the kind-param)
@@ -16,12 +16,10 @@ subroutine s(var)
   !PORTABILITY: Explicit kind parameter together with non-'E' exponent letter is not standard
   real :: realvar4 = 4.0D6_8
   !WARNING: Explicit kind parameter on real constant disagrees with exponent letter 'q'
-  !AIX_WARNING: underflow on REAL(10) to REAL(4) conversion
   real :: realvar5 = 4.0Q6_10
   !PORTABILITY: Explicit kind parameter together with non-'E' exponent letter is not standard
   real :: realvar6 = 4.0Q6_16
   real :: realvar7 = 4.0E6_8
-  !AIX_WARNING: underflow on REAL(10) to REAL(4) conversion
   real :: realvar8 = 4.0E6_10
   real :: realvar9 = 4.0E6_16
   !ERROR: Unsupported REAL(KIND=32)
@@ -35,7 +33,6 @@ subroutine s(var)
   !PORTABILITY: Explicit kind parameter together with non-'E' exponent letter is not standard
   double precision :: doublevar5 = 4.0Q6_16
   double precision :: doublevar6 = 4.0E6_8
-  !AIX_WARNING: underflow on REAL(10) to REAL(8) conversion
   double precision :: doublevar7 = 4.0E6_10
   double precision :: doublevar8 = 4.0E6_16
   !ERROR: Unsupported REAL(KIND=32)

``````````

</details>


https://github.com/llvm/llvm-project/pull/234842


More information about the flang-commits mailing list