[Openmp-commits] [openmp] bafde6f - [Flang] Move builtin .mod generation into runtimes (Reapply #137828) (#171515)

via Openmp-commits openmp-commits at lists.llvm.org
Fri May 29 01:50:57 PDT 2026


Author: Michael Kruse
Date: 2026-05-29T10:50:52+02:00
New Revision: bafde6fbb860e9b2f887a649c19f3b3ebb168041

URL: https://github.com/llvm/llvm-project/commit/bafde6fbb860e9b2f887a649c19f3b3ebb168041
DIFF: https://github.com/llvm/llvm-project/commit/bafde6fbb860e9b2f887a649c19f3b3ebb168041.diff

LOG: [Flang] Move builtin .mod generation into runtimes (Reapply #137828) (#171515)

Reapplication of #137828 and #169638

Move building the .mod files from openmp/flang to openmp/flang-rt using
a shared mechanism. Motivations to do so are:

1. Most modules are target-dependent and need to be re-compiled for each
target separately, which is something the LLVM_ENABLE_RUNTIMES system
already does. Prime example is `iso_c_binding.mod` which encodes the
target's ABI. Constants such as `c_long_double` also have different
values).
Most other modules have `#ifdef`-enclosed code as well. For instance
this caused offload targets nvptx64-nvidia-cuda/amdgpu-amd-amdhsa to use
the modules files compiled for the host which may contrain uses of the
types REAL(10) or REAL(16) not available for nvptx/amdgpu.

2. CMake has support for Fortran that we should use. Among other things,
it automatically determines module dependencies so there is no need to
hardcode them in the CMakeLists.txt.

Currently the dependencies between builtin modules and `omp_lib.mod`
seem to be incorrect:
https://github.com/llvm/llvm-project/pull/174474#issuecomment-3880189581

3. It allows using Fortran itself to implement Flang-RT. Currently, only
`iso_fortran_env_impl.f90` emits object files that are needed by Fortran
applications (#89403). The workaround of #95388 could be reverted (PR
#169525).


If using Flang for cross-compilation or target-offloading, flang-rt must
now be compiled for each target not only for the library, but also to
get the target-specific module files. For instance in a bootstrapping
runtime build, this can be done by adding:
`-DLLVM_RUNTIME_TARGETS=default;nvptx64-nvidia-cuda;amdgpu-amd-amdhsa`.


Some new dependencies come into play:
* openmp depends on flang-rt for building `lib_omp.mod` and
`lib_omp_kinds.mod`. Currently, if flang-rt is not found then the
modules are not built.
* check-flang depends on flang-rt: If not found, the majority of tests
are disabled. If not building in a bootstrpping build, the location of
the module files can be pointed to using
`-DFLANG_INTRINSIC_MODULES_DIR=<path>`, e.g. in a flang-standalone
build. Alternatively, the test needing any of the intrinsic modules
could be marked with `REQUIRES: flangrt-modules`.
* check-flang depends on openmp: Not a change; tests requiring
`lib_omp.mod` and `lib_omp_kinds.mod` those are already marked with
`openmp_runtime`.

As intrinsic are now specific to the target, their location is moved
from `include/flang` to `<resource-dir>/finclude/flang/<triple>`. The
mechnism to compute the location have been moved from flang-rt
(previously used to compute the location of `libflang_rt.*.a`) to common
locations in `cmake/GetToolchainDirs.cmake` and
`runtimes/CMakeLists.txt` so they can be used by both, openmp and
flang-rt. Potentially the mechnism could also be shared by other
libraries such as compiler-rt.

`finclude` was chosen because `gfortran` uses it as well and avoids
misuse such as `#include <flang/iso_c_binding.mod>`. The search location
is now determined by `ToolChain` in the driver, instead of by the
frontend. Another subdirectory `flang` avoids accidental inclusion of
gfortran-modules which due to compression would result in
user-unfriendly errors. Now the driver adds `-fintrinsic-module-path`
for that location to the frontend call (Just like gfortran does).
Since the driver determines the location,
tests invoking `flang -fc1` and `bbc` must also be passed the location
by llvm-lit. This works like llvm-lit does for finding the include dirs
for Clang using `-print-file-name=...`.

Added: 
    flang-rt/cmake/modules/FlangRTIntrospection.cmake
    flang-rt/lib/runtime/__cuda_builtins.f90
    flang-rt/lib/runtime/__cuda_device.f90
    flang-rt/lib/runtime/__fortran_builtins.f90
    flang-rt/lib/runtime/__fortran_ieee_exceptions.f90
    flang-rt/lib/runtime/__fortran_type_info.f90
    flang-rt/lib/runtime/__ppc_intrinsics.f90
    flang-rt/lib/runtime/__ppc_types.f90
    flang-rt/lib/runtime/cooperative_groups.f90
    flang-rt/lib/runtime/cuda_runtime_api.f90
    flang-rt/lib/runtime/cudadevice.f90
    flang-rt/lib/runtime/flang_debug.f90
    flang-rt/lib/runtime/ieee_arithmetic.f90
    flang-rt/lib/runtime/ieee_exceptions.f90
    flang-rt/lib/runtime/ieee_features.f90
    flang-rt/lib/runtime/iso_c_binding.f90
    flang-rt/lib/runtime/iso_fortran_env.f90
    flang-rt/lib/runtime/iso_fortran_env_impl.f90
    flang-rt/lib/runtime/mma.f90

Modified: 
    clang/lib/Driver/ToolChains/AMDGPU.cpp
    clang/lib/Driver/ToolChains/HIPAMD.cpp
    flang-rt/CMakeLists.txt
    flang-rt/cmake/modules/AddFlangRT.cmake
    flang-rt/lib/CMakeLists.txt
    flang-rt/lib/runtime/CMakeLists.txt
    flang-rt/lib/runtime/iso_fortran_env_impl.cpp
    flang-rt/test/CMakeLists.txt
    flang-rt/test/Driver/compare_iso_fortran_env_symbols.f90
    flang-rt/test/Driver/iso_fortran_env_impl.f90
    flang-rt/test/lit.cfg.py
    flang-rt/test/lit.site.cfg.py.in
    flang/CMakeLists.txt
    flang/lib/Semantics/semantics.cpp
    flang/test/CMakeLists.txt
    flang/test/Driver/intrinsic-module-path_per_target.f90
    flang/test/Driver/pp-fixed-form.f90
    flang/test/Lower/OpenMP/simd_aarch64.f90
    flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90
    flang/test/Lower/where-loc.f90
    flang/test/Parser/bug2280.f90
    flang/test/Preprocessing/fixed-free.f
    flang/test/Preprocessing/no-pp-if.f90
    flang/test/Semantics/bug163242.f90
    flang/test/Semantics/bug164303.f90
    flang/test/Semantics/bug2021.f90
    flang/test/lit.cfg.py
    flang/test/lit.site.cfg.py.in
    flang/tools/CMakeLists.txt
    llvm/runtimes/CMakeLists.txt
    openmp/CMakeLists.txt
    openmp/cmake/modules/LibompHandleFlags.cmake
    openmp/module/CMakeLists.txt
    openmp/runtime/cmake/LibompExports.cmake
    openmp/runtime/test/lit.cfg
    openmp/runtime/test/lit.site.cfg.in
    runtimes/cmake/config-Fortran.cmake

Removed: 
    flang/module/.clang-format
    flang/module/__cuda_builtins.f90
    flang/module/__cuda_device.f90
    flang/module/__fortran_builtins.f90
    flang/module/__fortran_ieee_exceptions.f90
    flang/module/__fortran_type_info.f90
    flang/module/__ppc_intrinsics.f90
    flang/module/__ppc_types.f90
    flang/module/cooperative_groups.f90
    flang/module/cuda_runtime_api.f90
    flang/module/cudadevice.f90
    flang/module/flang_debug.f90
    flang/module/ieee_arithmetic.f90
    flang/module/ieee_exceptions.f90
    flang/module/ieee_features.f90
    flang/module/iso_c_binding.f90
    flang/module/iso_fortran_env.f90
    flang/module/iso_fortran_env_impl.f90
    flang/module/mma.f90
    flang/test/Driver/Inputs/resource_dir_with_per_target_subdir/finclude/flang/x86_64-unknown-linux-gnu/.keep
    flang/tools/f18/CMakeLists.txt
    flang/tools/f18/dump.cpp
    openmp/cmake/modules/LibompCheckFortranFlag.cmake


################################################################################
diff  --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 631eb0b98df7e..55c94823376b0 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -846,7 +846,7 @@ void AMDGPUToolChain::addClangTargetOptions(
   // TODO: remove the SPIR-V bypass once it can encode (hidden) visibility.
   if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
                          options::OPT_fvisibility_ms_compat) &&
-      !getEffectiveTriple().isSPIRV()) {
+      !getEffectiveTriple().isSPIRV() && !getDriver().IsFlangMode()) {
     CC1Args.push_back("-fvisibility=hidden");
     CC1Args.push_back("-fapply-global-visibility-to-externs");
   }

diff  --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index 9211803aa6a2f..98be4861276f8 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -261,7 +261,7 @@ void HIPAMDToolChain::addClangTargetOptions(
   // TODO: remove the SPIR-V bypass once it can encode (hidden) visibility.
   if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
                          options::OPT_fvisibility_ms_compat) &&
-      !getEffectiveTriple().isSPIRV()) {
+      !getEffectiveTriple().isSPIRV() && !getDriver().IsFlangMode()) {
     CC1Args.append({"-fvisibility=hidden"});
     CC1Args.push_back("-fapply-global-visibility-to-externs");
   }

diff  --git a/flang-rt/CMakeLists.txt b/flang-rt/CMakeLists.txt
index ab905cd46655e..0d9696e327259 100644
--- a/flang-rt/CMakeLists.txt
+++ b/flang-rt/CMakeLists.txt
@@ -69,6 +69,7 @@ include(GetToolchainDirs)
 include(FlangCommon)
 include(HandleCompilerRT)
 include(ExtendPath)
+include(FlangRTIntrospection)
 
 
 ############################
@@ -112,6 +113,11 @@ else ()
   option(FLANG_RT_ENABLE_SHARED "Build Flang-RT as a shared library." OFF)
 endif ()
 
+# Enable building Fortran modules if Fortran is enabled
+option(FLANG_RT_FORTRAN_MODULES "Build Flang-RT modules" "${RUNTIMES_FORTRAN_MODULES}")
+if (NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED AND NOT FLANG_RT_FORTRAN_MODULES)
+  message(WARNING "LLVM_ENABLE_RUNTIMES=flang-rt, but not building anything")
+endif ()
 
 # TODO: Support tests for the GPU target.
 set(FLANG_RT_INCLUDE_TESTS_default ${LLVM_INCLUDE_TESTS})
@@ -181,6 +187,10 @@ check_cxx_source_compiles(
   "
   HAVE_DECL_STRERROR_S)
 
+# Look for support of REAL(16), if not already defined via command
+# line via -DFORTRAN_SUPPORTS_REAL16=YES/NO
+check_fortran_quadmath_support()
+
 # Search for clang_rt.builtins library. Need in addition to msvcrt.
 if (WIN32)
   find_compiler_rt_library(builtins FLANG_RT_BUILTINS_LIBRARY)
@@ -194,7 +204,7 @@ if (UNIX AND CMAKE_SYSTEM_NAME MATCHES "AIX")
 endif ()
 
 # Indicates REAL(16) support via an external library (e.g. libquadmath).
-add_compile_definitions(FLANG_RT_SUPPORTS_REAL16=$<BOOL:${FLANG_RUNTIME_F128_MATH_LIB}>)
+add_compile_definitions(FLANG_RT_SUPPORTS_REAL16=$<BOOL:${FORTRAN_SUPPORTS_REAL16}>)
 
 # Check whether the compiler can undefine a macro using the "-Wp,-U" flag.
 # Aternatively, we could use

diff  --git a/flang-rt/cmake/modules/AddFlangRT.cmake b/flang-rt/cmake/modules/AddFlangRT.cmake
index 871524b47e0e0..265725ddec3dd 100644
--- a/flang-rt/cmake/modules/AddFlangRT.cmake
+++ b/flang-rt/cmake/modules/AddFlangRT.cmake
@@ -94,6 +94,10 @@ function (add_flangrt_library name)
     set(build_object ON)
   elseif (build_static AND build_shared)
     set(build_object ON)
+  elseif (NOT build_static AND NOT build_shared)
+    # If not building a library, still build the object files
+    # Needed to generate the .mod files as byproduct
+    set(build_object ON)
   endif ()
 
   # srctargets: targets that contain source files
@@ -172,14 +176,18 @@ function (add_flangrt_library name)
     if (BUILD_SHARED_LIBS)
       if (build_shared)
         set(default_target "${name_shared}")
-      else ()
+      elseif (build_static)
         set(default_target "${name_static}")
+      else ()
+        set(default_target "${name_object}")
       endif ()
     else ()
       if (build_static)
         set(default_target "${name_static}")
-      else ()
+      elseif (build_shared)
         set(default_target "${name_shared}")
+      else ()
+        set(default_target "${name_object}")
       endif ()
     endif ()
     add_library(${name}.default ALIAS "${default_target}")
@@ -194,6 +202,15 @@ function (add_flangrt_library name)
     endif ()
   endif ()
 
+  # An alias for the target that compiles the sources. When building a shared
+  # and static library at the same time, the sources are compiled in an object
+  # library, so there can be only one.
+  # Can be used to introspect and change the real target's properties, like:
+  #
+  # get_target_property(compile_target ${name}.compile ALIASED_TARGET)
+  # target_sources(${compile_target} more_sources.c)
+  add_library(${name}.compile ALIAS "${srctargets}")
+
   foreach (tgtname IN LISTS libtargets)
     if (NOT WIN32)
       # Use same stem name for .a and .so. Common in UNIX environments.
@@ -223,6 +240,16 @@ function (add_flangrt_library name)
     # Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else.
     target_compile_features(${tgtname} PRIVATE cxx_std_17)
 
+    if (CMAKE_Fortran_COMPILER_ID MATCHES "LLVM")
+      target_compile_options(${tgtname} PRIVATE
+        # Always enable preprocessor regardless of file extension
+        "$<$<COMPILE_LANGUAGE:Fortran>:-cpp>"
+
+        # Missing type descriptors are expected for intrinsic modules
+        "$<$<COMPILE_LANGUAGE:Fortran>:SHELL:-mmlir;SHELL:-ignore-missing-type-desc>"
+      )
+    endif ()
+
     # When building the flang runtime if LTO is enabled the archive file
     # contains LLVM IR rather than object code. Currently flang is not
     # LTO aware so cannot link this file to compiled Fortran code.
@@ -230,6 +257,10 @@ function (add_flangrt_library name)
       target_compile_options(${tgtname} PRIVATE -fno-lto)
     endif ()
 
+    if (FORTRAN_SUPPORTS_REAL16)
+      target_compile_definitions(${tgtname} PRIVATE FLANG_SUPPORT_R16=1)
+    endif ()
+
     # Use compiler-specific options to disable exceptions and RTTI.
     if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
       target_compile_options(${tgtname} PRIVATE

diff  --git a/flang-rt/cmake/modules/FlangRTIntrospection.cmake b/flang-rt/cmake/modules/FlangRTIntrospection.cmake
new file mode 100644
index 0000000000000..6ffa41e08cd72
--- /dev/null
+++ b/flang-rt/cmake/modules/FlangRTIntrospection.cmake
@@ -0,0 +1,30 @@
+include(CMakePushCheckState)
+include(CheckFortranSourceCompiles)
+
+# Check whether the Fortran compiler supports real(16)/quadmath types
+#
+# Implementation notes:
+#
+#  * FORTRAN_SUPPORTS_REAL16 can be set externally in a bootstrapping-runtimes
+#    build to ensure consistency of real(16) support between compiler and
+#    runtime.
+#
+#  * cmake_push_check_state/cmake_pop_check_state is insufficient to isolate
+#    a compiler introspection environment, see
+#    https://gitlab.kitware.com/cmake/cmake/-/issues/27419
+#    Additionally wrap it in a function namespace.
+#
+function (check_fortran_quadmath_support)
+  cmake_push_check_state(RESET)
+  set(CMAKE_REQUIRED_FLAGS "-ffree-form")
+  set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") # Skip link step
+  check_fortran_source_compiles([[
+      subroutine test_quadmath
+        real(16) :: var1
+      end
+    ]]
+    FORTRAN_SUPPORTS_REAL16
+  )
+  cmake_pop_check_state()
+endfunction ()
+

diff  --git a/flang-rt/lib/CMakeLists.txt b/flang-rt/lib/CMakeLists.txt
index 8738ae7b9c4b6..58a7a24c19e0c 100644
--- a/flang-rt/lib/CMakeLists.txt
+++ b/flang-rt/lib/CMakeLists.txt
@@ -12,7 +12,7 @@ if (FLANG_RT_ENABLE_STATIC OR FLANG_RT_ENABLE_SHARED)
   if (FLANG_RT_INCLUDE_CUF)
     add_subdirectory(cuda)
   endif()
-else ()
+elseif (FLANG_RT_FORTRAN_MODULES)
   # Generate modules files only, skip the libraries
   add_subdirectory(runtime)
 endif ()

diff  --git a/flang-rt/lib/runtime/CMakeLists.txt b/flang-rt/lib/runtime/CMakeLists.txt
index f596bbed6f47a..20aa3effeec94 100644
--- a/flang-rt/lib/runtime/CMakeLists.txt
+++ b/flang-rt/lib/runtime/CMakeLists.txt
@@ -12,6 +12,30 @@ find_package(Backtrace)
 set(HAVE_BACKTRACE ${Backtrace_FOUND})
 set(BACKTRACE_HEADER ${Backtrace_HEADER})
 
+# Module sources that are required by other modules
+set(intrinsics_sources
+  __fortran_builtins.f90
+  __cuda_builtins.f90
+)
+
+# Fortran sources for builtin .mod files
+set(module_sources
+  __fortran_ieee_exceptions.f90
+  __fortran_type_info.f90
+  flang_debug.f90
+  iso_fortran_env.f90
+  iso_fortran_env_impl.f90
+  ieee_arithmetic.f90
+  ieee_exceptions.f90
+  ieee_features.f90
+  iso_c_binding.f90
+
+  __cuda_device.f90
+  cooperative_groups.f90
+  cuda_runtime_api.f90
+  cudadevice.f90
+)
+
 # List of files that are buildable for all devices.
 set(supported_sources
   ${FLANG_SOURCE_DIR}/lib/Decimal/binary-to-decimal.cpp
@@ -190,6 +214,25 @@ file(GLOB_RECURSE private_headers
   "${FLANG_SOURCE_DIR}/lib/Common/*.h"
   )
 
+if (LLVM_TARGET_TRIPLE MATCHES "^ppc|^powerpc")
+  list(APPEND intrinsics_sources
+    __ppc_types.f90
+  )
+  list(APPEND module_sources
+    __ppc_intrinsics.f90
+    mma.f90
+  )
+endif ()
+
+# Compile as CUDA-Fortran, not directly supported by CMake
+set_property(SOURCE
+    __cuda_device.f90
+    cooperative_groups.f90
+    cuda_runtime_api.f90
+    cudadevice.f90
+  APPEND PROPERTY
+    COMPILE_OPTIONS --offload-host-only -xcuda
+)
 
 # Import changes from flang_rt.quadmath
 set(f128_sources "")
@@ -220,6 +263,56 @@ if (TARGET FortranFloat128MathILib)
   endif ()
 endif ()
 
+
+# When a target depends on an object library, CMake seems to try to only build
+# the object files that the target actual needs. If we are only interested
+# in the module files, nothing get is built at all. To ensure that the module
+# files are built, insert a custom target that is opaque to CMake so it cannot
+# apply this optimization. Dependees on module files must depend on this
+# barrier instead. An actual COMMAND (that does nothing) seems to be necessary
+# on Windows to work.
+function (add_module_barrier barriername objlib)
+  add_custom_target(${barriername}
+    COMMAND ${CMAKE_COMMAND} -E true
+  )
+  add_dependencies(${barriername} ${objlib})
+endfunction ()
+
+
+# Build module files if requested.
+# The object files written by Flang for these are unused. In the future parts
+# of flang-rt may itself be implemented in Fortran in which case these Fortran
+# sources need to be added to ${sources} to be included in
+# libflang_rt.runtime{.a/.so}. If they also provide an importable .mod, add them
+# to flang_module_target(... PUBLIC).
+if (FLANG_RT_FORTRAN_MODULES)
+  # CMake ignores intrinsic USE dependencies
+  # CMake has an option Fortran_BUILDING_INSTRINSIC_MODULES/Fortran_BUILDING_INTRINSIC_MODULES
+  # to disable this behavior, unfortunately it does not work with Ninja
+  # (https://gitlab.kitware.com/cmake/cmake/-/issues/26803)
+  # As a workaround, we build those intrinsic modules first such that the main
+  # runtime can depend on it.
+  add_flangrt_library(flang_rt.mod.intrinsics OBJECT
+    ${intrinsics_sources}
+  )
+  flang_module_target(flang_rt.mod.intrinsics PUBLIC)
+  add_module_barrier(flang_rt.mod.intrinsics.barrier flang_rt.mod.intrinsics)
+
+  # The modules themselves
+  add_flangrt_library(flang_rt.mod OBJECT
+    ${module_sources}
+  )
+  add_dependencies(flang_rt.mod flang_rt.mod.intrinsics.barrier)
+  flang_module_target(flang_rt.mod PUBLIC)
+  add_module_barrier(flang-rt-mod flang_rt.mod)
+endif ()
+
+
+# Skip building libraries if not requested
+if (NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED)
+  return ()
+endif ()
+
 if ("${LLVM_DEFAULT_TARGET_TRIPLE}" MATCHES "^amdgcn|^nvptx")
   set(sources ${gpu_sources})
 elseif(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")

diff  --git a/flang/module/__cuda_builtins.f90 b/flang-rt/lib/runtime/__cuda_builtins.f90
similarity index 100%
rename from flang/module/__cuda_builtins.f90
rename to flang-rt/lib/runtime/__cuda_builtins.f90

diff  --git a/flang/module/__cuda_device.f90 b/flang-rt/lib/runtime/__cuda_device.f90
similarity index 100%
rename from flang/module/__cuda_device.f90
rename to flang-rt/lib/runtime/__cuda_device.f90

diff  --git a/flang/module/__fortran_builtins.f90 b/flang-rt/lib/runtime/__fortran_builtins.f90
similarity index 99%
rename from flang/module/__fortran_builtins.f90
rename to flang-rt/lib/runtime/__fortran_builtins.f90
index c63c0f03214f3..4f9874a9bef29 100644
--- a/flang/module/__fortran_builtins.f90
+++ b/flang-rt/lib/runtime/__fortran_builtins.f90
@@ -6,7 +6,7 @@
 !
 !===------------------------------------------------------------------------===!
 
-#include '../include/flang/Runtime/magic-numbers.h'
+#include '../../../flang/include/flang/Runtime/magic-numbers.h'
 
 ! These naming shenanigans prevent names from Fortran intrinsic modules
 ! from being usable on INTRINSIC statements, and force the program

diff  --git a/flang/module/__fortran_ieee_exceptions.f90 b/flang-rt/lib/runtime/__fortran_ieee_exceptions.f90
similarity index 98%
rename from flang/module/__fortran_ieee_exceptions.f90
rename to flang-rt/lib/runtime/__fortran_ieee_exceptions.f90
index 3ac9b993186aa..ff5c6b44317f8 100644
--- a/flang/module/__fortran_ieee_exceptions.f90
+++ b/flang-rt/lib/runtime/__fortran_ieee_exceptions.f90
@@ -11,7 +11,7 @@
 ! here under another name so that IEEE_ARITHMETIC can USE it and export its
 ! declarations without clashing with a non-intrinsic module in a program.
 
-#include '../include/flang/Runtime/magic-numbers.h'
+#include '../../../flang/include/flang/Runtime/magic-numbers.h'
 
 module __fortran_ieee_exceptions
   use __fortran_builtins, only: &

diff  --git a/flang/module/__fortran_type_info.f90 b/flang-rt/lib/runtime/__fortran_type_info.f90
similarity index 100%
rename from flang/module/__fortran_type_info.f90
rename to flang-rt/lib/runtime/__fortran_type_info.f90

diff  --git a/flang/module/__ppc_intrinsics.f90 b/flang-rt/lib/runtime/__ppc_intrinsics.f90
similarity index 100%
rename from flang/module/__ppc_intrinsics.f90
rename to flang-rt/lib/runtime/__ppc_intrinsics.f90

diff  --git a/flang/module/__ppc_types.f90 b/flang-rt/lib/runtime/__ppc_types.f90
similarity index 100%
rename from flang/module/__ppc_types.f90
rename to flang-rt/lib/runtime/__ppc_types.f90

diff  --git a/flang/module/cooperative_groups.f90 b/flang-rt/lib/runtime/cooperative_groups.f90
similarity index 96%
rename from flang/module/cooperative_groups.f90
rename to flang-rt/lib/runtime/cooperative_groups.f90
index 8bb4af3afa791..5ca0c3aa1f3a5 100644
--- a/flang/module/cooperative_groups.f90
+++ b/flang-rt/lib/runtime/cooperative_groups.f90
@@ -11,6 +11,7 @@
 module cooperative_groups
 
 use, intrinsic :: __fortran_builtins, only: c_devptr => __builtin_c_devptr
+use :: cudadevice ! implicit dependency, made explicit for CMake
 
 implicit none
 

diff  --git a/flang/module/cuda_runtime_api.f90 b/flang-rt/lib/runtime/cuda_runtime_api.f90
similarity index 100%
rename from flang/module/cuda_runtime_api.f90
rename to flang-rt/lib/runtime/cuda_runtime_api.f90

diff  --git a/flang/module/cudadevice.f90 b/flang-rt/lib/runtime/cudadevice.f90
similarity index 100%
rename from flang/module/cudadevice.f90
rename to flang-rt/lib/runtime/cudadevice.f90

diff  --git a/flang/module/flang_debug.f90 b/flang-rt/lib/runtime/flang_debug.f90
similarity index 100%
rename from flang/module/flang_debug.f90
rename to flang-rt/lib/runtime/flang_debug.f90

diff  --git a/flang/module/ieee_arithmetic.f90 b/flang-rt/lib/runtime/ieee_arithmetic.f90
similarity index 99%
rename from flang/module/ieee_arithmetic.f90
rename to flang-rt/lib/runtime/ieee_arithmetic.f90
index 4e938a2daaa91..02cfae2dc6b18 100644
--- a/flang/module/ieee_arithmetic.f90
+++ b/flang-rt/lib/runtime/ieee_arithmetic.f90
@@ -8,7 +8,7 @@
 
 ! Fortran 2018 Clause 17
 
-#include '../include/flang/Runtime/magic-numbers.h'
+#include '../../../flang/include/flang/Runtime/magic-numbers.h'
 
 module ieee_arithmetic
   ! F18 Clause 17.1p1:

diff  --git a/flang/module/ieee_exceptions.f90 b/flang-rt/lib/runtime/ieee_exceptions.f90
similarity index 100%
rename from flang/module/ieee_exceptions.f90
rename to flang-rt/lib/runtime/ieee_exceptions.f90

diff  --git a/flang/module/ieee_features.f90 b/flang-rt/lib/runtime/ieee_features.f90
similarity index 100%
rename from flang/module/ieee_features.f90
rename to flang-rt/lib/runtime/ieee_features.f90

diff  --git a/flang/module/iso_c_binding.f90 b/flang-rt/lib/runtime/iso_c_binding.f90
similarity index 100%
rename from flang/module/iso_c_binding.f90
rename to flang-rt/lib/runtime/iso_c_binding.f90

diff  --git a/flang/module/iso_fortran_env.f90 b/flang-rt/lib/runtime/iso_fortran_env.f90
similarity index 98%
rename from flang/module/iso_fortran_env.f90
rename to flang-rt/lib/runtime/iso_fortran_env.f90
index 3729b95a339f3..2dc38bd1acfe5 100644
--- a/flang/module/iso_fortran_env.f90
+++ b/flang-rt/lib/runtime/iso_fortran_env.f90
@@ -8,7 +8,7 @@
 
 ! See Fortran 2023, subclause 16.10.2
 
-#include '../include/flang/Runtime/magic-numbers.h'
+#include '../../../flang/include/flang/Runtime/magic-numbers.h'
 
 module iso_fortran_env
 

diff  --git a/flang-rt/lib/runtime/iso_fortran_env_impl.cpp b/flang-rt/lib/runtime/iso_fortran_env_impl.cpp
index 144662f1262a8..70230d0f16c7a 100644
--- a/flang-rt/lib/runtime/iso_fortran_env_impl.cpp
+++ b/flang-rt/lib/runtime/iso_fortran_env_impl.cpp
@@ -109,15 +109,15 @@ static constexpr std::int32_t selectedBfloat16{3};
 static constexpr std::int32_t selectedReal32{4};
 static constexpr std::int32_t selectedReal64{8};
 
-#if HAS_FLOAT80
-static constexpr std::int32_t selectedReal80{10};
-#elif HAS_LDBL128 || FLANG_RT_SUPPORTS_REAL16
+#if FLANG_RT_SUPPORTS_REAL16
 static constexpr std::int32_t selectedReal80{16};
+#elif HAS_FLOAT80
+static constexpr std::int32_t selectedReal80{10};
 #else
 static constexpr std::int32_t selectedReal80{-3};
 #endif
 
-#if HAS_LDBL128 || FLANG_RT_SUPPORTS_REAL16
+#if FLANG_RT_SUPPORTS_REAL16
 static constexpr std::int32_t selectedReal64x2{16};
 static constexpr std::int32_t selectedReal128{16};
 #elif HAS_FLOAT80
@@ -245,7 +245,7 @@ extern const std::int32_t FORTRAN_NAMED_CONST(__builtin_real_kinds)[]{
 #if HAS_FLOAT80
     10,
 #endif
-#if HAS_LDBL128 || FLANG_RT_SUPPORTS_REAL16
+#if FLANG_RT_SUPPORTS_REAL16
     16,
 #endif
 };

diff  --git a/flang/module/iso_fortran_env_impl.f90 b/flang-rt/lib/runtime/iso_fortran_env_impl.f90
similarity index 100%
rename from flang/module/iso_fortran_env_impl.f90
rename to flang-rt/lib/runtime/iso_fortran_env_impl.f90

diff  --git a/flang/module/mma.f90 b/flang-rt/lib/runtime/mma.f90
similarity index 100%
rename from flang/module/mma.f90
rename to flang-rt/lib/runtime/mma.f90

diff  --git a/flang-rt/test/CMakeLists.txt b/flang-rt/test/CMakeLists.txt
index 054798d6ff535..1cf6269686bb8 100644
--- a/flang-rt/test/CMakeLists.txt
+++ b/flang-rt/test/CMakeLists.txt
@@ -10,10 +10,12 @@
 # for use by Lit, and delegates to LLVM's lit test handlers.
 
 llvm_canonicalize_cmake_booleans(
+  FLANG_RT_FORTRAN_MODULES
   FLANG_STANDALONE_BUILD
   LLVM_BUILD_EXAMPLES
   LLVM_BYE_LINK_INTO_TOOLS
   LLVM_ENABLE_PLUGINS
+  LLVM_TREE_AVAILABLE
 )
 
 configure_lit_site_cfg(

diff  --git a/flang-rt/test/Driver/compare_iso_fortran_env_symbols.f90 b/flang-rt/test/Driver/compare_iso_fortran_env_symbols.f90
index 8fbc1091f0e65..8e17fe4e88914 100644
--- a/flang-rt/test/Driver/compare_iso_fortran_env_symbols.f90
+++ b/flang-rt/test/Driver/compare_iso_fortran_env_symbols.f90
@@ -1,6 +1,7 @@
 ! UNSUPPORTED: offload-cuda, system-windows
+! REQUIRES: fortran-modules
 
-! RUN: %flang -c -funsigned %include/../module/iso_fortran_env_impl.f90 -o %t.f90.o
+! RUN: %flang -c -funsigned %S/../../lib/runtime/iso_fortran_env_impl.f90 -o %t.f90.o
 
 ! Extract defined symbol names and sizes from the Fortran object and the
 ! already-built runtime library (which was compiled with the correct CMake flags).

diff  --git a/flang-rt/test/Driver/iso_fortran_env_impl.f90 b/flang-rt/test/Driver/iso_fortran_env_impl.f90
index f9dac6f0a20bb..d856a9595ec41 100644
--- a/flang-rt/test/Driver/iso_fortran_env_impl.f90
+++ b/flang-rt/test/Driver/iso_fortran_env_impl.f90
@@ -2,6 +2,8 @@
 ! (iso_fortran_env_impl.cpp) match the Fortran module definitions.
 
 ! UNSUPPORTED: offload-cuda
+! REQUIRES: fortran-modules
+
 ! RUN: %flang %isysroot -L"%libdir" %s -o %t
 ! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t | FileCheck %s
 

diff  --git a/flang-rt/test/lit.cfg.py b/flang-rt/test/lit.cfg.py
index 067ca5e5f1142..5769943285a56 100644
--- a/flang-rt/test/lit.cfg.py
+++ b/flang-rt/test/lit.cfg.py
@@ -78,10 +78,17 @@ def shjoin(args, sep=" "):
     isysroot_flag = ["-isysroot", config.osx_sysroot]
 config.substitutions.append(("%isysroot", " ".join(isysroot_flag)))
 
+flang_args = []
+if not config.llvm_tree_available:
+    flang_args.append(
+        f"-fintrinsic-modules-path={config.flang_rt_output_resource_mod_dir}"
+    )
+
 tools = [
     ToolSubst(
         "%flang",
         command=config.flang,
+        extra_args=flang_args,
         unresolved="fatal",
     ),
     ToolSubst(
@@ -107,3 +114,6 @@ def shjoin(args, sep=" "):
 # For CUDA offloading, additional steps (device linking) and libraries (cudart) are needed.
 if config.flang_rt_experimental_offload_support == "CUDA":
     config.available_features.add("offload-cuda")
+
+if config.flang_rt_fortran_modules:
+    config.available_features.add("fortran-modules")

diff  --git a/flang-rt/test/lit.site.cfg.py.in b/flang-rt/test/lit.site.cfg.py.in
index db7132b73192e..8e3c902d4a3a6 100644
--- a/flang-rt/test/lit.site.cfg.py.in
+++ b/flang-rt/test/lit.site.cfg.py.in
@@ -3,11 +3,14 @@
 import sys
 
 config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.llvm_tree_available = @LLVM_TREE_AVAILABLE@
 config.flang_source_dir = "@FLANG_SOURCE_DIR@"
 config.flang_rt_source_dir = "@FLANG_RT_SOURCE_DIR@"
 config.flang_rt_binary_test_dir = os.path.dirname(__file__)
 config.flang_rt_output_resource_lib_dir = "@RUNTIMES_OUTPUT_RESOURCE_LIB_DIR@"
+config.flang_rt_output_resource_mod_dir = "@RUNTIMES_OUTPUT_RESOURCE_MOD_DIR@"
 config.flang_rt_experimental_offload_support = "@FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT@"
+config.flang_rt_fortran_modules = @FLANG_RT_FORTRAN_MODULES@
 config.cc = "@CMAKE_C_COMPILER@"
 config.flang = "@CMAKE_Fortran_COMPILER@"
 config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@")

diff  --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt
index be0b1f3d9b270..a8bd5e266aefa 100644
--- a/flang/CMakeLists.txt
+++ b/flang/CMakeLists.txt
@@ -273,7 +273,6 @@ set(FLANG_TOOLS_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH
     "Path for binary subdirectory (defaults to '${CMAKE_INSTALL_BINDIR}')")
 mark_as_advanced(FLANG_TOOLS_INSTALL_DIR)
 
-set(FLANG_INTRINSIC_MODULES_DIR ${CMAKE_BINARY_DIR}/include/flang)
 set(FLANG_INCLUDE_DIR ${FLANG_BINARY_DIR}/include)
 
 # TODO: Remove when libclangDriver is lifted out of Clang

diff  --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index 8bca853f01a24..cde714c584d94 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -660,12 +660,15 @@ bool Semantics::Perform() {
     const auto *frontModule{std::get_if<common::Indirection<parser::Module>>(
         &program_.v.front().u)};
     if (frontModule &&
-        (std::get<parser::Statement<parser::ModuleStmt>>(frontModule->value().t)
-                    .statement.v.source == "__fortran_builtins" ||
-            std::get<parser::Statement<parser::ModuleStmt>>(
-                frontModule->value().t)
-                    .statement.v.source == "__ppc_types")) {
+        std::get<parser::Statement<parser::ModuleStmt>>(frontModule->value().t)
+                .statement.v.source == "__fortran_builtins") {
       // Don't try to read the builtins module when we're actually building it.
+    } else if (frontModule &&
+        std::get<parser::Statement<parser::ModuleStmt>>(frontModule->value().t)
+                .statement.v.source == "__ppc_types") {
+      // Don't try to read the UsePPCBuiltinTypesModule() we are currently
+      // building, but __fortran_builtins is needed to build it.
+      context_.UseFortranBuiltinsModule();
     } else if (frontModule &&
         (std::get<parser::Statement<parser::ModuleStmt>>(frontModule->value().t)
                     .statement.v.source == "__ppc_intrinsics" ||

diff  --git a/flang/module/.clang-format b/flang/module/.clang-format
deleted file mode 100644
index e3845288a2aec..0000000000000
--- a/flang/module/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-DisableFormat: true

diff  --git a/flang/test/CMakeLists.txt b/flang/test/CMakeLists.txt
index d3da00c755cf8..f1b492ee6cdc0 100644
--- a/flang/test/CMakeLists.txt
+++ b/flang/test/CMakeLists.txt
@@ -2,11 +2,31 @@
 # for use by Lit, and delegates to LLVM's lit test handlers.
 add_subdirectory(lib)
 
+set(FLANG_TEST_Fortran_FLAGS "" CACHE STRING "Additional Fortran flags for running tests, such as -fintrinsic-modules-path=<path>")
+
+if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
+  set(FLANG_TEST_ENABLE_MODULES_default ON)
+else ()
+  set(FLANG_TEST_ENABLE_MODULES_default OFF)
+endif ()
+option(FLANG_TEST_ENABLE_MODULES "Force-enable tests that require intrinsic modules from Flang-RT" "${FLANG_TEST_ENABLE_MODULES_default}")
+
+
+if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES AND FLANG_TEST_ENABLE_MODULES AND NOT FLANG_STANDALONE_BUILD)
+  set(FLANG_TEST_ENABLE_OPENMP_default ON)
+else ()
+  set(FLANG_TEST_ENABLE_OPENMP_default OFF)
+endif ()
+option(FLANG_TEST_ENABLE_OPENMP "Force-enable tests that require modules from OpenMP" "${FLANG_TEST_ENABLE_OPENMP_default}")
+
+
 llvm_canonicalize_cmake_booleans(
   FLANG_STANDALONE_BUILD
   LLVM_BYE_LINK_INTO_TOOLS
   LLVM_ENABLE_PLUGINS
   LLVM_INCLUDE_EXAMPLES
+  FLANG_TEST_ENABLE_MODULES
+  FLANG_TEST_ENABLE_OPENMP
 )
 
 set(FLANG_TOOLS_DIR ${FLANG_BINARY_DIR}/bin)
@@ -59,7 +79,6 @@ set(FLANG_TEST_PARAMS
 
 set(FLANG_TEST_DEPENDS
   flang
-  module_files
   fir-opt
   tco
   bbc
@@ -101,8 +120,14 @@ if (LLVM_INCLUDE_EXAMPLES)
     )
 endif ()
 
-if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES AND NOT FLANG_STANDALONE_BUILD)
-  list(APPEND FLANG_TEST_DEPENDS "libomp-mod")
+if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES AND NOT FLANG_STANDALONE_BUILD)
+  # For intrinsic module files (in flang-rt/)
+  list(APPEND FLANG_TEST_DEPENDS "flang-rt-mod")
+
+  if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES)
+    # For omplib.mod and omplib_kinds.mod (in openmp/)
+    list(APPEND FLANG_TEST_DEPENDS "libomp-mod")
+  endif ()
 endif ()
 
 add_custom_target(flang-test-depends DEPENDS ${FLANG_TEST_DEPENDS})

diff  --git a/flang/test/Driver/Inputs/resource_dir_with_per_target_subdir/finclude/flang/x86_64-unknown-linux-gnu/.keep b/flang/test/Driver/Inputs/resource_dir_with_per_target_subdir/finclude/flang/x86_64-unknown-linux-gnu/.keep
deleted file mode 100644
index e69de29bb2d1d..0000000000000

diff  --git a/flang/test/Driver/intrinsic-module-path_per_target.f90 b/flang/test/Driver/intrinsic-module-path_per_target.f90
index c32ff0c3185cb..b0a2ac9c7c6b4 100644
--- a/flang/test/Driver/intrinsic-module-path_per_target.f90
+++ b/flang/test/Driver/intrinsic-module-path_per_target.f90
@@ -1,5 +1,4 @@
 ! Ensure argument -fintrinsic-modules-path works as expected.
-! REQUIRES: x86-registered-target
 
 !-----------------------------------------
 ! FLANG DRIVER
@@ -8,15 +7,15 @@
 !       or lower priority than -fintrinsic-modules-path added here. Using
 !       basictestmoduleone.mod from Inputs/module-dir/ will trigger an error.
 
-! RUN:     %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -### 2>&1 | FileCheck %s --check-prefix=DEFAULTPATH
+! RUN:     %flang -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefix=DEFAULTPATH
 
-! RUN:     %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_DEFAULT
-! RUN: not %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTONE 2>&1 | FileCheck %s --check-prefix=NOINPUTONE
-! RUN: not %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTTWO 2>&1 | FileCheck %s --check-prefix=NOINPUTTWO
-! RUN:     %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/
-! RUN:     %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTONE -fintrinsic-modules-path=%S/Inputs/module-dir-one/
-! RUN:     %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir-one/ -fintrinsic-modules-path=%S/Inputs/module-dir/
-! RUN: not %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/ -fintrinsic-modules-path=%S/Inputs/module-dir-one/ 2>&1 | FileCheck %s --check-prefix=WRONGINPUTONE
+! RUN:     %flang -fsyntax-only %s -cpp -DINTRINSICS_DEFAULT
+! RUN: not %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTONE 2>&1 | FileCheck %s --check-prefix=NOINPUTONE
+! RUN: not %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTTWO 2>&1 | FileCheck %s --check-prefix=NOINPUTTWO
+! RUN:     %flang -fsyntax-only %s -cpp -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/
+! RUN:     %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTONE -fintrinsic-modules-path=%S/Inputs/module-dir-one/
+! RUN:     %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir-one/ -fintrinsic-modules-path=%S/Inputs/module-dir/
+! RUN: not %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/ -fintrinsic-modules-path=%S/Inputs/module-dir-one/ 2>&1 | FileCheck %s --check-prefix=WRONGINPUTONE
 
 
 !-----------------------------------------
@@ -42,8 +41,8 @@
 
 !-----------------------------------------
 
-! DEFAULTPATH:      -fc1
-! DEFAULTPATH-SAME: -fintrinsic-modules-path" "{{.*(\\\\|/)}}resource_dir_with_per_target_subdir{{(\\\\|/)}}finclude{{(\\\\|/)}}flang{{(\\\\|/)}}x86_64-unknown-linux-gnu"
+! DEFAULTPATH:      "-fc1"
+! DEFAULTPATH-SAME: "-fintrinsic-modules-path" "{{.*(\\\\|/)}}finclude{{(\\\\|/)}}flang{{(\\\\|/)}}{{[^/\]+}}"
 
 ! NOINPUTONE: Source file 'basictestmoduleone.mod' was not found
 ! NOINPUTTWO: Source file 'basictestmoduletwo.mod' was not found

diff  --git a/flang/test/Driver/pp-fixed-form.f90 b/flang/test/Driver/pp-fixed-form.f90
index bb869cd3341a7..bdeb80497c312 100644
--- a/flang/test/Driver/pp-fixed-form.f90
+++ b/flang/test/Driver/pp-fixed-form.f90
@@ -8,12 +8,12 @@
 
 !RUN: %flang -save-temps -### -ffree-form %S/Inputs/free-form-test.f90  2>&1 | FileCheck %s --check-prefix=FREE-FLAG
 FREE-FLAG:           "-fc1" {{.*}} "-o" "free-form-test.i" {{.*}} "-x" "f95" "{{.*}}/free-form-test.f90"
-FREE-FLAG-NEXT:      "-fc1" {{.*}} "-emit-llvm-bc" "-ffree-form"
+FREE-FLAG-NEXT:      "-fc1" {{.*}} "-emit-llvm-bc"{{.*}}"-ffree-form"
 FREE-FLAG-NOT:       "-ffixed-form"
 FREE-FLAG-SAME:      "-x" "f95-cpp-input" "free-form-test.i"
 
 !RUN: %flang -save-temps -### -ffixed-form %S/Inputs/fixed-form-test.f  2>&1 | FileCheck %s --check-prefix=FIXED-FLAG
 FIXED-FLAG:          "-fc1" {{.*}} "-o" "fixed-form-test.i" {{.*}} "-x" "f95" "{{.*}}/fixed-form-test.f"
-FIXED-FLAG-NEXT:     "-fc1" {{.*}} "-emit-llvm-bc" "-ffixed-form"
+FIXED-FLAG-NEXT:     "-fc1" {{.*}} "-emit-llvm-bc"{{.*}}"-ffixed-form"
 FIXED-FLAG-NOT:      "-ffixed-form"
 FIXED-FLAG-SAME:     "-x" "f95-cpp-input" "fixed-form-test.i"

diff  --git a/flang/test/Lower/OpenMP/simd_aarch64.f90 b/flang/test/Lower/OpenMP/simd_aarch64.f90
index 735237223bcb5..20dd50d3ac918 100644
--- a/flang/test/Lower/OpenMP/simd_aarch64.f90
+++ b/flang/test/Lower/OpenMP/simd_aarch64.f90
@@ -1,6 +1,10 @@
-! Tests for 2.9.3.1 Simd and target dependent defult alignment for AArch64
+! Tests for 2.9.3.1 Simd and target dependent default alignment for AArch64
 ! The default alignment for AARCH64 is 0 so we do not emit aligned clause
 ! REQUIRES: aarch64-registered-target
+
+! Requires aarch64 iso_c_binding.mod which currently is only available if your host is also aarch64
+! REQUIRES: aarch64-host
+
 ! RUN: %flang_fc1 -triple aarch64-unknown-linux-gnu -emit-hlfir -fopenmp %s -o - | FileCheck  %s
 subroutine simdloop_aligned_cptr(A)
     use iso_c_binding

diff  --git a/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90 b/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90
index d3f287addc2e7..1bd49333b3068 100644
--- a/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90
+++ b/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90
@@ -1,7 +1,7 @@
 ! This test checks the lowering and application of default map types for the target enter/exit data constructs and map clauses
 
-!RUN: %flang -fc1 -emit-fir -fopenmp -fopenmp-version=52 -o - %s | FileCheck %s --check-prefix=CHECK-52
-!RUN: not %flang -fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-51
+!RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-version=52 -o - %s | FileCheck %s --check-prefix=CHECK-52
+!RUN: not %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-51
 
 module test
   real, allocatable :: A

diff  --git a/flang/test/Lower/where-loc.f90 b/flang/test/Lower/where-loc.f90
index 75d1452da9df2..033a6fc74c86f 100644
--- a/flang/test/Lower/where-loc.f90
+++ b/flang/test/Lower/where-loc.f90
@@ -1,5 +1,5 @@
 ! Test line location lowering of WHERE statements.
-! RUN: %flang -fc1 -emit-hlfir -mmlir -mlir-print-debuginfo -mmlir --mlir-print-local-scope -o - %s | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -mmlir -mlir-print-debuginfo -mmlir --mlir-print-local-scope -o - %s | FileCheck %s
 
 ! CHECK-LABEL: func.func @_QPtest_where_construct
 subroutine test_where_construct(mask, m2, x, y)

diff  --git a/flang/test/Parser/bug2280.f90 b/flang/test/Parser/bug2280.f90
index d24b26ddeb0d8..2de644e159bda 100644
--- a/flang/test/Parser/bug2280.f90
+++ b/flang/test/Parser/bug2280.f90
@@ -1,4 +1,4 @@
-!RUN: %flang -fc1 -fdebug-unparse %s | FileCheck %s
+!RUN: %flang_fc1 -fdebug-unparse %s | FileCheck %s
 !CHECK: 1 FORMAT(1X)
 1 format(1x)
 !CHECK: 2 FORMAT(1X)

diff  --git a/flang/test/Preprocessing/fixed-free.f b/flang/test/Preprocessing/fixed-free.f
index 95f63a4d71e4c..7140bc6aec360 100644
--- a/flang/test/Preprocessing/fixed-free.f
+++ b/flang/test/Preprocessing/fixed-free.f
@@ -1,5 +1,5 @@
 !RUN: %flang -E %s 2>&1 | FileCheck %s
-!RUN: %flang -fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
+!RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
 !CHECK-NOT: dir$
 !CHECK-NOT: error:
 !dir$ fixed

diff  --git a/flang/test/Preprocessing/no-pp-if.f90 b/flang/test/Preprocessing/no-pp-if.f90
index 3e49df3deb251..ab08a4f838a90 100644
--- a/flang/test/Preprocessing/no-pp-if.f90
+++ b/flang/test/Preprocessing/no-pp-if.f90
@@ -1,4 +1,4 @@
-!RUN: %flang -fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
+!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
 !CHECK-NOT: ERROR STOP
 !CHECK: CONTINUE
 #if defined UNDEFINED

diff  --git a/flang/test/Semantics/bug163242.f90 b/flang/test/Semantics/bug163242.f90
index 5e020aeb4dc0d..3c0a2b6b32229 100644
--- a/flang/test/Semantics/bug163242.f90
+++ b/flang/test/Semantics/bug163242.f90
@@ -1,4 +1,4 @@
-!RUN: %flang -fc1 -fsyntax-only %s | FileCheck --allow-empty %s
+!RUN: %flang_fc1 -fsyntax-only %s | FileCheck --allow-empty %s
 !CHECK-NOT: error:
 character(0), allocatable :: ch
 allocate(character(-1) :: ch)

diff  --git a/flang/test/Semantics/bug164303.f90 b/flang/test/Semantics/bug164303.f90
index c356c07392577..39af27e914248 100644
--- a/flang/test/Semantics/bug164303.f90
+++ b/flang/test/Semantics/bug164303.f90
@@ -1,4 +1,4 @@
-!RUN: %flang -fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
+!RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
 module foo_mod
   use, intrinsic :: iso_fortran_env
   use, intrinsic :: iso_c_binding

diff  --git a/flang/test/Semantics/bug2021.f90 b/flang/test/Semantics/bug2021.f90
index f5214bce946a9..4d914f34e9a53 100644
--- a/flang/test/Semantics/bug2021.f90
+++ b/flang/test/Semantics/bug2021.f90
@@ -1,4 +1,4 @@
-!RUN: %flang -fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s
+!RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s
 !CHECK-NOT: warning: Value of uninitialized local variable 'b' is used but never defined [-Wused-undefined-variable]
 real :: a, b
 pointer(p,a)

diff  --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index 3a87f9ea06803..92278a220cec0 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -140,18 +140,92 @@
 if config.default_sysroot:
     config.available_features.add("default_sysroot")
 
+host_triple = config.host_triple.split("-")
+config.available_features.add(f"{host_triple[0]}-host")
+
+flang_exe = lit.util.which("flang", config.flang_llvm_tools_dir)
+if not flang_exe:
+    lit_config.fatal(f"Could not identify flang executable")
+
+# Intrinsic paths that are added implicitly by the `flang` driver, but have to be added manually when invoking the frontend `flang -fc1`.
+flang_driver_search_args = []
+
+# Intrinsic paths that are added to `flang` as well as `flang -fc1`.
+flang_extra_search_args = list(config.flang_test_fortran_flags)
+
+
+def get_resource_module_intrinsic_dir(modfile):
+    # Determine the intrinsic module search path that is added by the driver. If
+    # skipping the driver using -fc1, we need to append the path manually.
+    flang_intrinsics_dir = subprocess.check_output(
+        [flang_exe, *config.flang_test_fortran_flags, f"-print-file-name={modfile}"],
+        text=True,
+    ).strip()
+    flang_intrinsics_dir = os.path.dirname(flang_intrinsics_dir)
+    return flang_intrinsics_dir or None
+
+
+intrinsics_mod_path = get_resource_module_intrinsic_dir("__fortran_builtins.mod")
+if intrinsics_mod_path:
+    flang_driver_search_args += [f"-fintrinsic-modules-path={intrinsics_mod_path}"]
+
+openmp_mod_path = get_resource_module_intrinsic_dir("omp_lib.mod")
+if openmp_mod_path and openmp_mod_path != intrinsics_mod_path:
+    flang_driver_search_args += [f"-fintrinsic-modules-path={openmp_mod_path}"]
+
+
+# If intrinsic modules are not available, disable tests unless they are marked as 'module-independent'.
+config.available_features.add("module-independent")
+if config.flang_test_enable_modules or intrinsics_mod_path:
+    config.available_features.add("flangrt-modules")
+else:
+    lit_config.warning(
+        f"Intrinsic modules not in driver default paths: disabling most tests; Use FLANG_TEST_ENABLE_MODULES=ON to force-enable"
+    )
+    config.limit_to_features.add("module-independent")
+
+# Determine if OpenMP runtime was built (enable OpenMP tests via REQUIRES in test file)
+if config.flang_test_enable_openmp or openmp_mod_path:
+    config.available_features.add("openmp_runtime")
+
+    # Search path for omp_lib.h with LLVM_ENABLE_RUNTIMES=openmp
+    # FIXME: In a bootstrapping build, openmp should write this file into a
+    #        shared directory
+    flang_extra_search_args += [
+        "-I",
+        f"{config.flang_obj_root}/../../runtimes/runtimes-bins/openmp/runtime/src",
+    ]
+else:
+    lit_config.warning(
+        f"OpenMP modules found not in driver default paths: OpenMP tests disabled; Use FLANG_TEST_ENABLE_OPENMP=ON to force-enable"
+    )
+
+
+lit_config.note(f"using flang: {flang_exe}")
+lit_config.note(
+    f"using flang implicit search paths: {' '.join(flang_driver_search_args)}"
+)
+lit_config.note(f"using flang extra search paths: {' '.join(flang_extra_search_args)}")
+
 # For each occurrence of a flang tool name, replace it with the full path to
 # the build directory holding that tool.
 tools = [
+    ToolSubst(
+        "bbc",
+        command=FindTool("bbc"),
+        extra_args=flang_driver_search_args + flang_extra_search_args,
+        unresolved="fatal",
+    ),
     ToolSubst(
         "%flang",
-        command=FindTool("flang"),
+        command=flang_exe,
+        extra_args=flang_extra_search_args,
         unresolved="fatal",
     ),
     ToolSubst(
         "%flang_fc1",
-        command=FindTool("flang"),
-        extra_args=["-fc1"],
+        command=flang_exe,
+        extra_args=["-fc1"] + flang_driver_search_args + flang_extra_search_args,
         unresolved="fatal",
     ),
 ]
@@ -194,16 +268,7 @@
 if result:
     config.environment["LIBPGMATH"] = True
 
-# Determine if OpenMP runtime was built (enable OpenMP tests via REQUIRES in test file)
-openmp_flags_substitution = "-fopenmp"
-if config.have_openmp_rtl:
-    config.available_features.add("openmp_runtime")
-    # For the enabled OpenMP tests, add a substitution that is needed in the tests to find
-    # the omp_lib.{h,mod} files, depending on whether the OpenMP runtime was built as a
-    # project or runtime.
-    if config.openmp_module_dir:
-        openmp_flags_substitution += f" -J {config.openmp_module_dir}"
-config.substitutions.append(("%openmp_flags", openmp_flags_substitution))
+config.substitutions.append(("%openmp_flags", "-fopenmp"))
 
 # Add features and substitutions to test F128 math support.
 # %f128-lib substitution may be used to generate check prefixes

diff  --git a/flang/test/lit.site.cfg.py.in b/flang/test/lit.site.cfg.py.in
index 2b66dd64b8c13..74c3e07e0a402 100644
--- a/flang/test/lit.site.cfg.py.in
+++ b/flang/test/lit.site.cfg.py.in
@@ -13,10 +13,12 @@ config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
 config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@"
 config.flang_obj_root = "@FLANG_BINARY_DIR@"
 config.flang_tools_dir = lit_config.substitute("@FLANG_TOOLS_DIR@")
-config.flang_intrinsic_modules_dir = "@FLANG_INTRINSIC_MODULES_DIR@"
 config.flang_headers_dir = "@HEADER_BINARY_DIR@"
 config.flang_llvm_tools_dir = "@CMAKE_BINARY_DIR@/bin"
 config.flang_test_triple = "@FLANG_TEST_TARGET_TRIPLE@"
+config.flang_test_fortran_flags = "@FLANG_TEST_Fortran_FLAGS@".split()
+config.flang_test_enable_modules = @FLANG_TEST_ENABLE_MODULES@
+config.flang_test_enable_openmp = @FLANG_TEST_ENABLE_OPENMP@
 config.flang_examples = @LLVM_INCLUDE_EXAMPLES@
 config.python_executable = "@PYTHON_EXECUTABLE@"
 config.flang_standalone_build = @FLANG_STANDALONE_BUILD@
@@ -25,11 +27,6 @@ config.linked_bye_extension = @LLVM_BYE_LINK_INTO_TOOLS@
 config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@")
 config.targets_to_build = "@TARGETS_TO_BUILD@"
 config.default_sysroot = "@DEFAULT_SYSROOT@"
-config.have_openmp_rtl = ("@LLVM_TOOL_OPENMP_BUILD@" == "TRUE") or ("openmp" in "@LLVM_ENABLE_RUNTIMES@".lower().split(";"))
-if "openmp" in "@LLVM_ENABLE_RUNTIMES@".lower().split(";"):
-    config.openmp_module_dir = "@CMAKE_BINARY_DIR@/runtimes/runtimes-bins/openmp/runtime/src"
-else:
-    config.openmp_module_dir = None
 config.flang_runtime_f128_math_lib = "@FLANG_RUNTIME_F128_MATH_LIB@"
 config.have_ldbl_mant_dig_113 = "@HAVE_LDBL_MANT_DIG_113@"
 

diff  --git a/flang/tools/CMakeLists.txt b/flang/tools/CMakeLists.txt
index 1d2d2c608faf9..1b297af74cae7 100644
--- a/flang/tools/CMakeLists.txt
+++ b/flang/tools/CMakeLists.txt
@@ -7,7 +7,6 @@
 #===------------------------------------------------------------------------===#
 
 add_subdirectory(bbc)
-add_subdirectory(f18)
 add_subdirectory(flang-driver)
 add_subdirectory(tco)
 add_subdirectory(f18-parse-demo)

diff  --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt
deleted file mode 100644
index 900b341e85c58..0000000000000
--- a/flang/tools/f18/CMakeLists.txt
+++ /dev/null
@@ -1,160 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  FrontendOpenACC
-  FrontendOpenMP
-  Support
-  )
-
-# Define the list of Fortran module files for which it is
-# sufficient to generate the module file via -fsyntax-only.
-set(MODULES
-  "__fortran_builtins"
-  "__fortran_ieee_exceptions"
-  "__fortran_type_info"
-  "__ppc_types"
-  "__ppc_intrinsics"
-  "mma"
-  "__cuda_builtins"
-  "__cuda_device"
-  "cooperative_groups"
-  "cuda_runtime_api"
-  "cudadevice"
-  "ieee_arithmetic"
-  "ieee_exceptions"
-  "ieee_features"
-  "iso_c_binding"
-  "iso_fortran_env"
-  "iso_fortran_env_impl"
-  "flang_debug"
-)
-
-# Check if 128-bit float computations can be done via long double.
-check_cxx_source_compiles(
-  "#include <cfloat>
-   #if LDBL_MANT_DIG != 113
-   #error LDBL_MANT_DIG != 113
-   #endif
-   int main() { return 0; }
-  "
-  HAVE_LDBL_MANT_DIG_113)
-
-# Figure out whether we can support REAL(KIND=16)
-if (FLANG_RUNTIME_F128_MATH_LIB)
-  set(FLANG_SUPPORT_R16 "1")
-elseif (HAVE_LDBL_MANT_DIG_113)
-  set(FLANG_SUPPORT_R16 "1")
-else()
-  set(FLANG_SUPPORT_R16 "0")
-endif()
-
-# Init variable to hold extra object files coming from the Fortran modules;
-# these module files will be contributed from the CMakeLists in flang/tools/f18.
-set(module_objects "")
-
-# Create module files directly from the top-level module source directory.
-# If CMAKE_CROSSCOMPILING, then the newly built flang executable was
-# cross compiled, and thus can't be executed on the build system and thus
-# can't be used for generating module files.
-if (NOT CMAKE_CROSSCOMPILING)
-  foreach(filename ${MODULES})
-    set(depends "")
-    set(opts "")
-    if(${filename} STREQUAL "__fortran_builtins" OR
-       ${filename} STREQUAL "__ppc_types")
-    elseif(${filename} STREQUAL "__ppc_intrinsics" OR
-           ${filename} STREQUAL "mma")
-      set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__ppc_types.mod)
-    elseif(${filename} STREQUAL "__cuda_device" OR
-           ${filename} STREQUAL "cudadevice" OR
-           ${filename} STREQUAL "cooperative_groups" OR
-           ${filename} STREQUAL "cuda_runtime_api")
-      set(opts -fc1 -xcuda)
-      if(${filename} STREQUAL "__cuda_device")
-        set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__cuda_builtins.mod)
-      elseif(${filename} STREQUAL "cudadevice")
-        set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__cuda_device.mod)
-      elseif(${filename} STREQUAL "cooperative_groups")
-        set(depends ${FLANG_INTRINSIC_MODULES_DIR}/cudadevice.mod)
-      endif()
-    else()
-      set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_builtins.mod)
-      if(${filename} STREQUAL "iso_fortran_env")
-        set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/iso_fortran_env_impl.mod)
-      endif()
-      if(${filename} STREQUAL "ieee_arithmetic" OR
-         ${filename} STREQUAL "ieee_exceptions")
-        set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_ieee_exceptions.mod)
-      endif()
-    endif()
-    if(NOT ${filename} STREQUAL "__fortran_type_info" AND NOT ${filename} STREQUAL "__fortran_builtins")
-      set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_type_info.mod)
-    endif()
-
-    # The module contains PPC vector types that needs the PPC target.
-    if(${filename} STREQUAL "__ppc_intrinsics" OR
-       ${filename} STREQUAL "mma")
-      if (PowerPC IN_LIST LLVM_TARGETS_TO_BUILD)
-        set(opts "--target=ppc64le")
-      else()
-        # Do not compile PPC module if the target is not available.
-        continue()
-      endif()
-    endif()
-
-    set(decls "")
-    if (FLANG_SUPPORT_R16)
-      set(decls "-DFLANG_SUPPORT_R16")
-    endif()
-
-    # Some modules have an implementation part that needs to be added to the
-    # flang_rt.runtime library.
-    set(compile_with "-fsyntax-only")
-    set(object_output "")
-    set(include_in_link FALSE)
-
-    set(base ${FLANG_INTRINSIC_MODULES_DIR}/${filename})
-    # TODO: We may need to flag this with conditional, in case Flang is built w/o OpenMP support
-    add_custom_command(OUTPUT ${base}.mod ${object_output}
-      COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR}
-      COMMAND flang ${opts} ${decls} -cpp ${compile_with} -module-dir ${FLANG_INTRINSIC_MODULES_DIR}
-        ${FLANG_SOURCE_DIR}/module/${filename}.f90
-      DEPENDS flang ${FLANG_SOURCE_DIR}/module/${filename}.f90 ${FLANG_SOURCE_DIR}/module/__fortran_builtins.f90 ${depends}
-    )
-    list(APPEND MODULE_FILES ${base}.mod)
-    install(FILES ${base}.mod DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang" COMPONENT flang-module-interfaces)
-
-    # If a module has been compiled into an object file, add the file to
-    # the link line for the flang_rt.runtime library.
-    if(include_in_link)
-      list(APPEND module_objects ${object_output})
-    endif()
-  endforeach()
-
-  # Set a CACHE variable that is visible to the CMakeLists.txt in runtime/, so that
-  # the compiled Fortran modules can be added to the link line of the flang_rt.runtime
-  # library.
-  set(FORTRAN_MODULE_OBJECTS ${module_objects} CACHE INTERNAL "" FORCE)
-
-  # Special case for omp_lib.mod, because its source comes from openmp/runtime/src/include.
-  # It also produces two module files: omp_lib.mod and omp_lib_kinds.mod.  Compile these
-  # files only if OpenMP support has been configured.
-  if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES)
-    message(STATUS "OpenMP runtime support enabled via LLVM_ENABLE_RUNTIMES, assuming omp_lib.mod is built there")
-  else()
-    message(WARNING "Not building omp_lib.mod, no OpenMP runtime in either LLVM_ENABLE_PROJECTS or LLVM_ENABLE_RUNTIMES")
-  endif()
-  add_custom_target(flang-module-interfaces ALL DEPENDS module_files)
-  add_llvm_install_targets(install-flang-module-interfaces
-    COMPONENT flang-module-interfaces)
-  add_dependencies(install-flang-module-interfaces flang-module-interfaces)
-endif()
-
-add_custom_target(module_files ALL DEPENDS ${MODULE_FILES})
-set_target_properties(module_files PROPERTIES FOLDER "Flang/Resources")
-
-# TODO Move this to a more suitable location
-# Copy the generated omp_lib.h header file, if OpenMP support has been configured.
-if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES)
-  message(STATUS "OpenMP runtime support enabled via LLVM_ENABLE_RUNTIMES, assuming omp_lib.h is built there")
-else()
-  message(STATUS "Not copying omp_lib.h, no OpenMP runtime in either LLVM_ENABLE_PROJECTS or LLVM_ENABLE_RUNTIMES")
-endif()

diff  --git a/flang/tools/f18/dump.cpp b/flang/tools/f18/dump.cpp
deleted file mode 100644
index f11b5aedf4c6a..0000000000000
--- a/flang/tools/f18/dump.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- tools/f18/dump.cpp ------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// This file defines Dump routines available for calling from the debugger.
-// Each is based on operator<< for that type. There are overloadings for
-// reference and pointer, and for dumping to a provided raw_ostream or errs().
-
-#ifdef DEBUGF18
-
-#include "llvm/Support/raw_ostream.h"
-
-#define DEFINE_DUMP(ns, name) \
-  namespace ns { \
-  class name; \
-  llvm::raw_ostream &operator<<(llvm::raw_ostream &, const name &); \
-  } \
-  void Dump(llvm::raw_ostream &os, const ns::name &x) { os << x << '\n'; } \
-  void Dump(llvm::raw_ostream &os, const ns::name *x) { \
-    if (x == nullptr) \
-      os << "null\n"; \
-    else \
-      Dump(os, *x); \
-  } \
-  void Dump(const ns::name &x) { Dump(llvm::errs(), x); } \
-  void Dump(const ns::name *x) { Dump(llvm::errs(), *x); }
-
-namespace Fortran {
-DEFINE_DUMP(parser, Name)
-DEFINE_DUMP(parser, CharBlock)
-DEFINE_DUMP(semantics, Symbol)
-DEFINE_DUMP(semantics, Scope)
-DEFINE_DUMP(semantics, IntrinsicTypeSpec)
-DEFINE_DUMP(semantics, DerivedTypeSpec)
-DEFINE_DUMP(semantics, DeclTypeSpec)
-} // namespace Fortran
-
-#endif

diff  --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt
index 0905f09c8b79f..686089efa9639 100644
--- a/llvm/runtimes/CMakeLists.txt
+++ b/llvm/runtimes/CMakeLists.txt
@@ -287,6 +287,10 @@ function(runtime_default_target)
       endif ()
     endif ()
   endif ()
+  if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
+    # The target flang-rt-mod is a dependee of check-flang.
+    list(APPEND extra_targets "flang-rt-mod")
+  endif ()
 
   if(LLVM_INCLUDE_TESTS)
     set_property(GLOBAL APPEND PROPERTY LLVM_ALL_LIT_TESTSUITES "@${LLVM_BINARY_DIR}/runtimes/runtimes-bins/lit.tests")
@@ -581,22 +585,7 @@ if(build_runtimes)
       endif()
     endforeach()
   endif()
-  # Allow openmp to see the Fortran compiler
-  if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES AND "flang" IN_LIST LLVM_ENABLE_PROJECTS)
-    list(APPEND extra_args ENABLE_FORTRAN)
-  endif()
   if("openmp" IN_LIST LLVM_ENABLE_RUNTIMES OR "offload" IN_LIST LLVM_ENABLE_RUNTIMES)
-    if (${LLVM_TOOL_FLANG_BUILD})
-      message(STATUS "Configuring build of omp_lib.mod and omp_lib_kinds.mod via flang")
-      set(LIBOMP_FORTRAN_MODULES_COMPILER "${CMAKE_BINARY_DIR}/bin/flang")
-      set(LIBOMP_MODULES_INSTALL_PATH "${CMAKE_INSTALL_INCLUDEDIR}/flang")
-      # TODO: This is a workaround until flang becomes a first-class project
-      # in llvm/CMakeList.txt.  Until then, this line ensures that flang is
-      # built before "openmp" is built as a runtime project.  Besides "flang"
-      # to build the compiler, we also need to add "module_files" to make sure
-      # that all .mod files are also properly build.
-      list(APPEND extra_deps "flang" "module_files")
-    endif()
     foreach(dep opt llvm-link llvm-extract clang llvm-offload-binary clang-nvlink-wrapper)
       if(TARGET ${dep})
         list(APPEND extra_deps ${dep})
@@ -621,12 +610,18 @@ if(build_runtimes)
   if(LLVM_LIBC_FULL_BUILD)
     list(APPEND extra_cmake_args "-DLLVM_LIBC_FULL_BUILD=ON")
   endif()
-  if("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
-    list(APPEND extra_args ENABLE_FORTRAN)
-    if (${LLVM_TOOL_FLANG_BUILD})
-      list(APPEND extra_deps "flang" "module_files")
+  if("flang" IN_LIST LLVM_ENABLE_PROJECTS)
+    # Allow runtimes that can use it to access the Flang compiler
+    if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES OR "flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
+      list(APPEND extra_args ENABLE_FORTRAN)
     endif()
-  endif ()
+    # Ensure REAL(16) support in runtimes to be consistent with compiler
+    if(FLANG_RUNTIME_F128_MATH_LIB OR HAVE_LDBL_MANT_DIG_113)
+      list(APPEND extra_cmake_args "-DFORTRAN_SUPPORTS_REAL16=1")
+    else()
+      list(APPEND extra_cmake_args "-DFORTRAN_SUPPORTS_REAL16=0")
+    endif()
+  endif()
 
   if(NOT LLVM_RUNTIME_TARGETS)
     runtime_default_target(

diff  --git a/openmp/CMakeLists.txt b/openmp/CMakeLists.txt
index 512bd41f8a9e7..08546dfaf249a 100644
--- a/openmp/CMakeLists.txt
+++ b/openmp/CMakeLists.txt
@@ -106,7 +106,7 @@ math(EXPR LIBOMP_VERSION_BUILD_MONTH_DAY "${LIBOMP_VERSION_BUILD}%10000")
 set(LIBOMP_BUILD_DATE "No_Timestamp")
 
 
-set(LIBOMP_FORTRAN_MODULES FALSE CACHE BOOL
+set(LIBOMP_FORTRAN_MODULES "${RUNTIMES_FORTRAN_MODULES}" CACHE BOOL
   "Create Fortran module files? (requires fortran compiler)")
 
 option(LIBOMP_FORTRAN_MODULES_ONLY
@@ -122,6 +122,8 @@ set(OPENMP_TEST_FLAGS "" CACHE STRING
   "Extra compiler flags to send to the test compiler.")
 set(OPENMP_TEST_OPENMP_FLAGS ${OPENMP_TEST_COMPILER_OPENMP_FLAGS} CACHE STRING
   "OpenMP compiler flag to use for testing OpenMP runtime libraries.")
+set(OPENMP_TEST_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" CACHE STRING
+  "Additional compiler flags to use for testing Fortran programs (e.g. additional module search paths via -fintrinsic-modules-path )")
 
 set(ENABLE_LIBOMPTARGET ON)
 # Currently libomptarget cannot be compiled on Windows or MacOS X.
@@ -158,13 +160,15 @@ add_custom_target(install-openmp-stripped
 add_dependencies(install-openmp openmp)
 add_dependencies(install-openmp-stripped openmp)
 
+if(LIBOMP_FORTRAN_MODULES)
+  add_subdirectory(module)
+endif()
+
 # Use the current compiler target to determine the appropriate runtime to build.
 if("${LLVM_DEFAULT_TARGET_TRIPLE}" MATCHES "^amdgcn|^nvptx|^spirv64" OR
    "${CMAKE_CXX_COMPILER_TARGET}" MATCHES "^amdgcn|^nvptx|^spirv64")
   add_subdirectory(device)
 else()
-  add_subdirectory(module)
-
   # Build host runtime library, after LIBOMPTARGET variables are set since they
   # are needed to enable time profiling support in the OpenMP runtime.
   if(NOT LIBOMP_FORTRAN_MODULES_ONLY)

diff  --git a/openmp/cmake/modules/LibompCheckFortranFlag.cmake b/openmp/cmake/modules/LibompCheckFortranFlag.cmake
deleted file mode 100644
index 344389f989388..0000000000000
--- a/openmp/cmake/modules/LibompCheckFortranFlag.cmake
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-#//===----------------------------------------------------------------------===//
-#//
-#// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-#// See https://llvm.org/LICENSE.txt for license information.
-#// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-#//
-#//===----------------------------------------------------------------------===//
-#
-
-# Checking a fortran compiler flag
-# There is no real trivial way to do this in CMake, so we implement it here
-# this will have ${boolean} = TRUE if the flag succeeds, otherwise false.
-function(libomp_check_fortran_flag flag boolean)
-  if(NOT DEFINED "${boolean}")
-    set(retval TRUE)
-    set(fortran_source
-"      program hello
-           print *, \"Hello World!\"
-      end program hello")
-
-    # Compiling as a part of runtimes introduces ARCH-unknown-linux-gnu as a
-    # part of a working directory.  So adding a guard for unknown.
-    set(failed_regexes "[Ee]rror;[Uu]nknown[^-];[Ss]kipping")
-    include(CheckFortranSourceCompiles)
-    check_fortran_source_compiles("${fortran_source}" ${boolean} FAIL_REGEX "${failed_regexes}")
-    set(${boolean} ${${boolean}} PARENT_SCOPE)
-  endif()
-endfunction()

diff  --git a/openmp/cmake/modules/LibompHandleFlags.cmake b/openmp/cmake/modules/LibompHandleFlags.cmake
index 980a62166deed..5d6558cc8ffcf 100644
--- a/openmp/cmake/modules/LibompHandleFlags.cmake
+++ b/openmp/cmake/modules/LibompHandleFlags.cmake
@@ -161,17 +161,6 @@ function(libomp_get_libflags libflags)
   set(${libflags} ${libflags_local_list} PARENT_SCOPE)
 endfunction()
 
-# Fortran flags
-function(libomp_get_fflags fflags)
-  set(fflags_local)
-  if(CMAKE_SIZEOF_VOID_P EQUAL 4)
-    libomp_append(fflags_local -m32 LIBOMP_HAVE_M32_FORTRAN_FLAG)
-  endif()
-  set(fflags_local ${fflags_local} ${LIBOMP_FFLAGS})
-  libomp_setup_flags(fflags_local)
-  set(${fflags} ${fflags_local} PARENT_SCOPE)
-endfunction()
-
 # Python generate-defs.py flags (For Windows only)
 function(libomp_get_gdflags gdflags)
   set(gdflags_local)

diff  --git a/openmp/module/CMakeLists.txt b/openmp/module/CMakeLists.txt
index 9265e70dd78cb..c0a873f9be552 100644
--- a/openmp/module/CMakeLists.txt
+++ b/openmp/module/CMakeLists.txt
@@ -6,87 +6,33 @@
 #//
 #//===----------------------------------------------------------------------===//
 
-include(LibompCheckFortranFlag)
+# Build the module files if a Fortran compiler is available.
 
-set(LIBOMP_FFLAGS "" CACHE STRING
-  "Appended user specified Fortran compiler flags.  These are only used if LIBOMP_FORTRAN_MODULES==TRUE.")
-
-# Enabling Fortran if it is needed
-if (LIBOMP_FORTRAN_MODULES)
-  enable_language(Fortran)
-
-  libomp_check_fortran_flag(-m32 LIBOMP_HAVE_M32_FORTRAN_FLAG)
-endif ()
-
-# Building the Fortran module files
-# One compilation step creates both omp_lib.mod and omp_lib_kinds.mod
-configure_file(omp_lib.F90.var omp_lib.F90 @ONLY)
+configure_file(omp_lib.F90.var "${CMAKE_CURRENT_BINARY_DIR}/omp_lib.F90" @ONLY)
 configure_file(omp_lib.h.var "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.h" @ONLY)
 
-set(BUILD_FORTRAN_MODULES False)
-if (LIBOMP_FORTRAN_MODULES_COMPILER)
-  # If libomp is built as an LLVM runtime and the flang compiler is available,
-  # compile the Fortran module files.
-  message(STATUS "configuring openmp to build Fortran module files using '${LIBOMP_FORTRAN_MODULES_COMPILER}'")
-  set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.F90)
-  # omp_lib_kinds uses iso_c_binding, which depends on these intrinsic modules.
-  # List them so omp_lib.mod is regenerated when intrinsic modules change; otherwise
-  # stale omp_lib.mod can reference an incompatible iso_c_binding.mod (see flang
-  # tests that load omp_lib.mod with -J).
-  set(_libomp_flang_intrinsic_mod_deps "")
-  if(LLVM_BINARY_DIR)
-    set(_flang_intrinsic_mod_dir "${LLVM_BINARY_DIR}/include/flang")
-    list(APPEND _libomp_flang_intrinsic_mod_deps
-      "${_flang_intrinsic_mod_dir}/__fortran_builtins.mod"
-      "${_flang_intrinsic_mod_dir}/__fortran_type_info.mod"
-      "${_flang_intrinsic_mod_dir}/iso_c_binding.mod"
-    )
-  endif()
-  add_custom_target(libomp-mod ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod" "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod")
-  add_custom_command(
-    OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod" "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod"
-    COMMAND ${LIBOMP_FORTRAN_MODULES_COMPILER} -cpp -fsyntax-only ${LIBOMP_FORTRAN_SOURCE_FILE} "-J${CMAKE_CURRENT_BINARY_DIR}/../runtime/src"
-    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_FORTRAN_SOURCE_FILE}" ${_libomp_flang_intrinsic_mod_deps}
-  )
-  set(BUILD_FORTRAN_MODULES True)
-elseif (LIBOMP_FORTRAN_MODULES)
-  # The following requests explicit building of the Fortran module files
-  # Workaround for gfortran to build modules with the
-  # omp_sched_monotonic integer parameter
-  if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
-    set(ADDITIONAL_Fortran_FLAGS "-fno-range-check")
-  endif ()
-  add_custom_target(libomp-mod ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod" "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod")
-  set_target_properties(libomp-mod PROPERTIES FOLDER "OpenMP/Misc")
-  libomp_get_fflags(LIBOMP_CONFIGURED_FFLAGS)
-  if (CMAKE_Fortran_COMPILER_SUPPORTS_F90)
-    set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.F90)
-  else ()
-    message(FATAL_ERROR "Fortran module build requires Fortran 90 compiler")
-  endif ()
-  add_custom_command(
-    OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod" "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod"
-    COMMAND ${CMAKE_Fortran_COMPILER} -c ${ADDITIONAL_Fortran_FLAGS}
-            ${LIBOMP_CONFIGURED_FFLAGS} ${LIBOMP_FORTRAN_SOURCE_FILE} "-J${CMAKE_CURRENT_BINARY_DIR}/../runtime/src"
-    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_FORTRAN_SOURCE_FILE}"
-  )
-  set_property(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src" PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "omp_lib${CMAKE_C_OUTPUT_EXTENSION}")
-  set(BUILD_FORTRAN_MODULES True)
+# One compilation step creates both, omp_lib.mod and omp_lib_kinds.mod. Only
+# these files are used, the object file itself can be discarded.
+# TODO: Adding it to libomp ($<TARGET_OBJECTS:libomp-mod>) would allow implementing Fortran API in Fortran
+add_library(libomp-mod OBJECT
+  "${CMAKE_CURRENT_BINARY_DIR}/omp_lib.F90"
+)
+set_target_properties(libomp-mod PROPERTIES FOLDER "OpenMP/Fortran Modules")
+
+# The following requests explicit building of the Fortran module files
+# Workaround for gfortran to build modules with the
+# omp_sched_monotonic integer parameter
+if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
+  target_compile_options(libomp-mod PRIVATE -fno-range-check)
 endif ()
 
+flang_module_target(libomp-mod PUBLIC)
+add_dependencies(libomp-mod ${RUNTIMES_FORTRAN_BUILD_DEPS})
 
-if (BUILD_FORTRAN_MODULES)
-  set(destination "${LIBOMP_HEADERS_INSTALL_PATH}")
-  if (LIBOMP_MODULES_INSTALL_PATH)
-    set(destination "${LIBOMP_MODULES_INSTALL_PATH}")
-  endif ()
-  install(FILES
-    "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod"
-    "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod"
-    "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.h"
-    DESTINATION ${destination}
+install(FILES
+  "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.h"
+  DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH}
     COMPONENT openmp
-  )
-endif ()
+)
 
 openmp_register_meta_dep(libomp-mod)

diff  --git a/openmp/runtime/cmake/LibompExports.cmake b/openmp/runtime/cmake/LibompExports.cmake
index 7a0fe51d96982..805f128ebef2e 100644
--- a/openmp/runtime/cmake/LibompExports.cmake
+++ b/openmp/runtime/cmake/LibompExports.cmake
@@ -56,8 +56,8 @@ set(LIBOMP_EXPORTS_LIB_DIR "${LIBOMP_EXPORTS_DIR}/${libomp_platform}${libomp_suf
 # Put headers in exports/ directory post build
 add_custom_command(TARGET omp POST_BUILD
   COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBOMP_EXPORTS_CMN_DIR}
-  COMMAND ${CMAKE_COMMAND} -E copy omp.h ${LIBOMP_EXPORTS_CMN_DIR}
-  COMMAND ${CMAKE_COMMAND} -E copy ompx.h ${LIBOMP_EXPORTS_CMN_DIR}
+  COMMAND ${CMAKE_COMMAND} -E copy "${LIBOMP_HEADERS_INTDIR}/omp.h" ${LIBOMP_EXPORTS_CMN_DIR}
+  COMMAND ${CMAKE_COMMAND} -E copy "${LIBOMP_HEADERS_INTDIR}/ompx.h" ${LIBOMP_EXPORTS_CMN_DIR}
 )
 if(LIBOMP_OMPT_SUPPORT)
   add_custom_command(TARGET omp POST_BUILD
@@ -69,8 +69,8 @@ if(LIBOMP_FORTRAN_MODULES)
   # to omp and ensure that libomp-mod is built before by adding a dependency
   add_custom_command(TARGET omp POST_BUILD
     COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBOMP_EXPORTS_MOD_DIR}
-    COMMAND ${CMAKE_COMMAND} -E copy omp_lib.mod ${LIBOMP_EXPORTS_MOD_DIR}
-    COMMAND ${CMAKE_COMMAND} -E copy omp_lib_kinds.mod ${LIBOMP_EXPORTS_MOD_DIR}
+    COMMAND ${CMAKE_COMMAND} -E copy "${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}/omp_lib.mod" ${LIBOMP_EXPORTS_MOD_DIR}
+    COMMAND ${CMAKE_COMMAND} -E copy "${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}/omp_lib_kinds.mod" ${LIBOMP_EXPORTS_MOD_DIR}
   )
   add_dependencies(omp libomp-mod)
   add_custom_command(TARGET omp POST_BUILD

diff  --git a/openmp/runtime/test/lit.cfg b/openmp/runtime/test/lit.cfg
index 4885f4e2cfbe3..6a63fce1b1692 100644
--- a/openmp/runtime/test/lit.cfg
+++ b/openmp/runtime/test/lit.cfg
@@ -3,6 +3,7 @@
 
 import os
 import re
+import shlex
 import subprocess
 import lit.formats
 from lit.llvm.subst import ToolSubst
@@ -51,6 +52,7 @@ if config.test_fortran_compiler:
         ToolSubst(
             "%flang",
             command=config.test_fortran_compiler,
+            extra_args=shlex.split(config.test_fortran_flags),
             unresolved="fatal",
         ),
     ], [config.llvm_tools_dir])

diff  --git a/openmp/runtime/test/lit.site.cfg.in b/openmp/runtime/test/lit.site.cfg.in
index a4d7c8d8b205e..da8a12b23808b 100644
--- a/openmp/runtime/test/lit.site.cfg.in
+++ b/openmp/runtime/test/lit.site.cfg.in
@@ -7,6 +7,7 @@ config.test_compiler_features = @OPENMP_TEST_COMPILER_FEATURES@
 config.test_filecheck = "@OPENMP_FILECHECK_EXECUTABLE@"
 config.test_not = "@OPENMP_NOT_EXECUTABLE@"
 config.test_openmp_flags = "@OPENMP_TEST_OPENMP_FLAGS@"
+config.test_fortran_flags = "@OPENMP_TEST_Fortran_FLAGS@"
 config.test_extra_flags = "@OPENMP_TEST_FLAGS@"
 config.libomp_obj_root = "@CMAKE_CURRENT_BINARY_DIR@"
 config.library_dir = "@LIBOMP_LIBRARY_DIR@"

diff  --git a/runtimes/cmake/config-Fortran.cmake b/runtimes/cmake/config-Fortran.cmake
index f5cea1fc67e29..74fd15021f0a0 100644
--- a/runtimes/cmake/config-Fortran.cmake
+++ b/runtimes/cmake/config-Fortran.cmake
@@ -11,18 +11,18 @@
 # compiled. Contains the build targets for intrinsic modules, if necessary.
 # Otherweise, it is empty.
 #
-# RUNTIMES_ENABLE_FLANG_MODULES - Whether to build Flang modules and emit them
+# RUNTIMES_FORTRAN_MODULES - Whether to build Flang modules and emit them
 # into Flang's search path. This is a CMake CACHE option defined in
 # config-Fortran.cmake and default to ON iff the Fortran compiler is detected
 # for be a (compatible) version of Flang. In the OFF setting, modules are still
 # built, but not installed or emitted into a default path.
 #
 # RUNTIMES_OUTPUT_RESOURCE_MOD_DIR - Where to emit intrinsic module files in
-# the build directory. Most relevant when RUNTIMES_ENABLE_FLANG_MODULES is ON.
+# the build directory. Most relevant when RUNTIMES_FORTRAN_MODULES is ON.
 #
 # RUNTIMES_INSTALL_RESOURCE_MOD_PATH - Where to install intrinsic module files
 # in the install prefix. Relative to CMAKE_INSTALL_PREFIX. Only used when
-# RUNTIMES_ENABLE_FLANG_MODULES is ON.
+# RUNTIMES_FORTRAN_MODULES is ON.
 
 
 # Check whether the Fortran compiler already has access to builtin modules. Sets
@@ -180,17 +180,14 @@ endif ()
 
 
 # Check whether modules files are compatible with our version of Flang.
-set(RUNTIMES_ENABLE_FLANG_MODULES_default OFF)
-if (CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
-  set(RUNTIMES_ENABLE_FLANG_MODULES_default ON)
-else ()
-  set(RUNTIMES_ENABLE_FLANG_MODULES_default OFF)
+set(RUNTIMES_FORTRAN_MODULES_default OFF)
+if (RUNTIMES_ENABLE_FORTRAN AND CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
+  set(RUNTIMES_FORTRAN_MODULES_default ON)
 endif ()
-option(RUNTIMES_ENABLE_FLANG_MODULES "Make Fortran .mod files available to Flang; should only be enabled if compiling with a matching version of Flang" "${RUNTIMES_ENABLE_FLANG_MODULES_default}")
-
+option(RUNTIMES_FORTRAN_MODULES "Make Fortran .mod files available to Flang; should only be enabled if compiling with a matching version of Flang" "${RUNTIMES_FORTRAN_MODULES_default}")
 
 # Determine the paths for Fortran .mod files.
-if (RUNTIMES_ENABLE_FLANG_MODULES)
+if (RUNTIMES_FORTRAN_MODULES)
   # Flang expects its builtin modules in Clang's resource directory.
   get_toolchain_module_subdir(toolchain_mod_subdir)
   extend_path(RUNTIMES_OUTPUT_RESOURCE_MOD_DIR "${RUNTIMES_OUTPUT_RESOURCE_DIR}" "${toolchain_mod_subdir}")
@@ -261,7 +258,15 @@ function (flang_module_target tgtname)
         Fortran_MODULE_DIRECTORY "${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}"
     )
   else ()
-    # Keep non-public modules where CMake would put them normally;
-    # Modules of 
diff erent target must not overwrite each other.
+    # Modules of 
diff erent targets must not overwrite each other.
+    # Ideally, we would use $<TARGET_PROPERTY:${tgtname},BINARY_DIR> but
+    # Fortran_MODULE_DIRECTORY does not support generator expressions.
+    # Not defining Fortran_MODULE_DIRECTORY at all would but it into
+    # ${CMAKE_CURRENT_BINARY_DIR} where modules with the same name but compiled
+    # by 
diff erent targets would clash.
+    set_target_properties(${tgtname}
+      PROPERTIES
+        Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${tgtname}.dir/${CMAKE_CFG_INTDIR}"
+    )
   endif ()
 endfunction ()


        


More information about the Openmp-commits mailing list