[flang] [llvm] [Flang/Flang-RT] Fix OldUnit tests on Windows (PR #150734)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 26 06:10:41 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-testing-tools

Author: Michael Kruse (Meinersbur)

<details>
<summary>Changes</summary>

Flang and Flang-RT have two flavours of unittests: 
1. GTest unittests, using lit's `lit.formats.GoogleTest` format ending with `Tests${CMAKE_EXECUTABLE_SUFFIX}`
2. "non-GTest" or "OldUnit" unittests, a plain executable ending with `.test${CMAKE_EXECUTABLE_SUFFIX}`

Both executables are emitted into the same unittests/ subdirectory. When running ...
1. `tests/Unit/lit.cfg.py`, only considers executable ending with `Tests` (or `Tests.exe` on Windows), hence skips the non-GTest tests.
2. `tests/NonGtestUnit/lit.cfg.py` considers all tests ending with `.test` or `.exe`. On Windows, The GTest unitests also end with `.exe`.

In Flang-RT, `.exe` is considered an extension for non-GTest unitests which causes tests such as Flang's `RuntimeTests.exe` to be executed for both on Windows. This particular test includes a file write test, using a hard-coded filename `ucsfile`. If the two instances are executed concurrently, they might interfere with each other reading/writing `ucsfile` which results in a [flaky test](https://lab.llvm.org/staging/#/builders/36/builds/21997).

This patch avoids the redundant execution by requiring the suffix `.test.exe` on Windows. lit has to be modified because it uses `os.path.splitext` the extract the extension, which would only recognize the last component.

In Flang, `.exe` is not considered a suffix for non-GTest unittests and hence they are not run at all. Fixing by also added `.test.exe` as valid suffix, like with Flang-RT.

Unfortunately, the ` Evaluate/real.test.exe` test was failing on Windows"
```
FAIL: flang-OldUnit :: Evaluate/real.test.exe (3592 of 3592)
******************** TEST 'flang-OldUnit :: Evaluate/real.test.exe' FAILED ********************
..\_src\flang\unittests\Evaluate\real.cpp:511: FAIL: FlagsToBits(prod.flags) == 0x18, not 0x10
        0 0x800001 * 0xbf7ffffe
..\_src\flang\unittests\Evaluate\real.cpp:511: FAIL: FlagsToBits(prod.flags) == 0x18, not 0x10
        0 0x800001 * 0x3f7ffffe
..\_src\flang\unittests\Evaluate\real.cpp:511: FAIL: FlagsToBits(prod.flags) == 0x18, not 0x10
        0 0x80800001 * 0xbf7ffffe
..\_src\flang\unittests\Evaluate\real.cpp:511: FAIL: FlagsToBits(prod.flags) == 0x18, not 0x10
        0 0x80800001 * 0x3f7ffffe
...
```
This is due to the `__x86_64__` macro not being set by Microsoft's cl.exe and hence floating point status flags not being read out. The equivalent macro for Microsofts compiler is [`_M_X64` (or `_M_X64`)](https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170).

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


6 Files Affected:

- (modified) flang-rt/test/NonGtestUnit/lit.cfg.py (+1-2) 
- (modified) flang/include/flang/Common/target-rounding.h (+1-1) 
- (modified) flang/include/flang/Testing/fp-testing.h (+1-1) 
- (modified) flang/lib/Testing/fp-testing.cpp (+4-4) 
- (modified) flang/test/NonGtestUnit/lit.cfg.py (+1-1) 
- (modified) llvm/utils/lit/lit/formats/base.py (+1-2) 


``````````diff
diff --git a/flang-rt/test/NonGtestUnit/lit.cfg.py b/flang-rt/test/NonGtestUnit/lit.cfg.py
index 4bee709b78f43..8da36adc74a22 100644
--- a/flang-rt/test/NonGtestUnit/lit.cfg.py
+++ b/flang-rt/test/NonGtestUnit/lit.cfg.py
@@ -8,8 +8,7 @@
 config.name = "flang-rt-OldUnit"
 
 # suffixes: A list of file extensions to treat as test files.
-# On Windows, ".exe" also matches the GTests and will execited redundantly.
-config.suffixes = [".test", ".exe"]
+config.suffixes = [".test", ".test.exe"]
 
 # test_source_root: The root path where unit test binaries are located.
 config.test_source_root = os.path.join(config.flangrt_binary_dir, "unittests")
diff --git a/flang/include/flang/Common/target-rounding.h b/flang/include/flang/Common/target-rounding.h
index f503b22930ed4..9041d74cf1b67 100644
--- a/flang/include/flang/Common/target-rounding.h
+++ b/flang/include/flang/Common/target-rounding.h
@@ -21,7 +21,7 @@ struct Rounding {
   // (viz., fail to set the Underflow flag when an inexact product of a
   // multiplication is rounded up to a normal number from a subnormal
   // in some rounding modes)
-#if __x86_64__ || __riscv || __loongarch__
+#if __x86_64__ || _M_X64 || __riscv || __loongarch__
   bool x86CompatibleBehavior{true};
 #else
   bool x86CompatibleBehavior{false};
diff --git a/flang/include/flang/Testing/fp-testing.h b/flang/include/flang/Testing/fp-testing.h
index c65766b8b47e8..5d7de3c3c5e24 100644
--- a/flang/include/flang/Testing/fp-testing.h
+++ b/flang/include/flang/Testing/fp-testing.h
@@ -27,7 +27,7 @@ class ScopedHostFloatingPointEnvironment {
 
 private:
   fenv_t originalFenv_;
-#if __x86_64__
+#if __x86_64__ || _M_X64
   unsigned int originalMxcsr;
 #endif
 };
diff --git a/flang/lib/Testing/fp-testing.cpp b/flang/lib/Testing/fp-testing.cpp
index 5e1728e8df5e4..56335f1b948bc 100644
--- a/flang/lib/Testing/fp-testing.cpp
+++ b/flang/lib/Testing/fp-testing.cpp
@@ -11,7 +11,7 @@
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
-#if __x86_64__
+#if __x86_64__ || _M_X64
 #include <xmmintrin.h>
 #endif
 
@@ -19,7 +19,7 @@ using Fortran::common::RealFlag;
 using Fortran::common::RoundingMode;
 
 ScopedHostFloatingPointEnvironment::ScopedHostFloatingPointEnvironment(
-#if __x86_64__
+#if __x86_64__ || _M_X64
     bool treatSubnormalOperandsAsZero, bool flushSubnormalResultsToZero
 #else
     bool, bool
@@ -38,7 +38,7 @@ ScopedHostFloatingPointEnvironment::ScopedHostFloatingPointEnvironment(
     std::abort();
   }
 
-#if __x86_64__
+#if __x86_64__ || _M_X64
   originalMxcsr = _mm_getcsr();
   unsigned int currentMxcsr{originalMxcsr};
   if (treatSubnormalOperandsAsZero) {
@@ -72,7 +72,7 @@ ScopedHostFloatingPointEnvironment::~ScopedHostFloatingPointEnvironment() {
         stderr, "fesetenv() failed: %s\n", llvm::sys::StrError(errno).c_str());
     std::abort();
   }
-#if __x86_64__
+#if __x86_64__ || _M_X64
   _mm_setcsr(originalMxcsr);
 #endif
 }
diff --git a/flang/test/NonGtestUnit/lit.cfg.py b/flang/test/NonGtestUnit/lit.cfg.py
index 39ae19fc164d6..407b393d5f93d 100644
--- a/flang/test/NonGtestUnit/lit.cfg.py
+++ b/flang/test/NonGtestUnit/lit.cfg.py
@@ -4,7 +4,7 @@
 
 config.name = "flang-OldUnit"
 
-config.suffixes = [".test"]
+config.suffixes = [".test", ".test.exe"]
 
 config.test_source_root = os.path.join(config.flang_obj_root, "unittests")
 config.test_exec_root = config.test_source_root
diff --git a/llvm/utils/lit/lit/formats/base.py b/llvm/utils/lit/lit/formats/base.py
index 27f7c7e69af4e..db5c1c3aba218 100644
--- a/llvm/utils/lit/lit/formats/base.py
+++ b/llvm/utils/lit/lit/formats/base.py
@@ -34,8 +34,7 @@ def getTestsForPath(self, testSuite, path_in_suite, litConfig, localConfig):
         if filename.startswith(".") or filename in localConfig.excludes:
             return
 
-        base, ext = os.path.splitext(filename)
-        if ext in localConfig.suffixes:
+        if any(filename.endswith(suffix) for suffix in localConfig.suffixes):
             yield lit.Test.Test(testSuite, path_in_suite, localConfig)
 
     def getTestsInDirectory(self, testSuite, path_in_suite, litConfig, localConfig):

``````````

</details>


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


More information about the llvm-commits mailing list