[llvm-branch-commits] [clang] [flang] [llvm] [Flang] LLVM_ENABLE_RUNTIMES=flang-rt (PR #110217)

Michael Kruse via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jan 24 10:43:16 PST 2025


https://github.com/Meinersbur updated https://github.com/llvm/llvm-project/pull/110217

>From f67081627ea71065635f5dd84172bcd68904f4f6 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Fri, 24 Jan 2025 16:50:07 +0100
Subject: [PATCH] [Flang] LLVM_ENABLE_RUNTIMES=flang-rt

---
 clang/lib/Driver/ToolChains/Flang.cpp         |  14 +-
 flang-rt/.clang-tidy                          |   2 +
 flang-rt/CMakeLists.txt                       | 248 ++++++++++++++++++
 flang-rt/CODE_OWNERS.TXT                      |  14 +
 flang-rt/LICENSE.TXT                          | 234 +++++++++++++++++
 flang-rt/README.md                            | 188 +++++++++++++
 flang-rt/cmake/modules/AddFlangRT.cmake       | 186 +++++++++++++
 .../cmake/modules/AddFlangRTOffload.cmake     | 101 +++++++
 flang-rt/cmake/modules/GetToolchainDirs.cmake | 125 +++++++++
 flang-rt/lib/CMakeLists.txt                   |  18 ++
 .../lib/FortranFloat128Math/CMakeLists.txt    | 136 ++++++++++
 flang-rt/lib/Testing/CMakeLists.txt           |  20 ++
 flang-rt/lib/flang_rt/CMakeLists.txt          | 213 +++++++++++++++
 flang-rt/lib/flang_rt/CUDA/CMakeLists.txt     |  33 +++
 flang-rt/lib/flang_rt/io-api-minimal.cpp      |   2 +-
 flang-rt/test/CMakeLists.txt                  |  59 +++++
 flang-rt/test/Driver/ctofortran.f90           |  29 +-
 flang-rt/test/Driver/exec.f90                 |   8 +-
 flang-rt/test/NonGtestUnit/lit.cfg.py         |  22 ++
 flang-rt/test/NonGtestUnit/lit.site.cfg.py.in |  14 +
 flang-rt/test/Runtime/no-cpp-dep.c            |   5 +-
 flang-rt/test/Unit/lit.cfg.py                 |  21 ++
 flang-rt/test/Unit/lit.site.cfg.py.in         |  15 ++
 flang-rt/test/lit.cfg.py                      | 102 +++++++
 flang-rt/test/lit.site.cfg.py.in              |  19 ++
 flang-rt/unittests/CMakeLists.txt             | 111 ++++++++
 flang-rt/unittests/Evaluate/CMakeLists.txt    |  21 ++
 flang-rt/unittests/Runtime/CMakeLists.txt     |  48 ++++
 .../unittests/Runtime/CUDA/CMakeLists.txt     |  18 ++
 flang/CMakeLists.txt                          |  53 ++--
 flang/cmake/modules/FlangCommon.cmake         |  43 +++
 flang/docs/GettingStarted.md                  | 108 ++++----
 flang/docs/ReleaseNotes.md                    |   8 +-
 flang/module/iso_fortran_env_impl.f90         |   2 +-
 flang/test/lit.cfg.py                         |  20 --
 flang/test/lit.site.cfg.py.in                 |   3 -
 llvm/CMakeLists.txt                           |   8 +-
 .../modules/LLVMExternalProjectUtils.cmake    |  16 +-
 llvm/projects/CMakeLists.txt                  |   4 +-
 llvm/runtimes/CMakeLists.txt                  |  25 +-
 runtimes/CMakeLists.txt                       |   2 +-
 41 files changed, 2169 insertions(+), 149 deletions(-)
 create mode 100644 flang-rt/.clang-tidy
 create mode 100644 flang-rt/CMakeLists.txt
 create mode 100644 flang-rt/CODE_OWNERS.TXT
 create mode 100644 flang-rt/LICENSE.TXT
 create mode 100644 flang-rt/README.md
 create mode 100644 flang-rt/cmake/modules/AddFlangRT.cmake
 create mode 100644 flang-rt/cmake/modules/AddFlangRTOffload.cmake
 create mode 100644 flang-rt/cmake/modules/GetToolchainDirs.cmake
 create mode 100644 flang-rt/lib/CMakeLists.txt
 create mode 100644 flang-rt/lib/FortranFloat128Math/CMakeLists.txt
 create mode 100644 flang-rt/lib/Testing/CMakeLists.txt
 create mode 100644 flang-rt/lib/flang_rt/CMakeLists.txt
 create mode 100644 flang-rt/lib/flang_rt/CUDA/CMakeLists.txt
 create mode 100644 flang-rt/test/CMakeLists.txt
 create mode 100644 flang-rt/test/NonGtestUnit/lit.cfg.py
 create mode 100644 flang-rt/test/NonGtestUnit/lit.site.cfg.py.in
 create mode 100644 flang-rt/test/Unit/lit.cfg.py
 create mode 100644 flang-rt/test/Unit/lit.site.cfg.py.in
 create mode 100644 flang-rt/test/lit.cfg.py
 create mode 100644 flang-rt/test/lit.site.cfg.py.in
 create mode 100644 flang-rt/unittests/CMakeLists.txt
 create mode 100644 flang-rt/unittests/Evaluate/CMakeLists.txt
 create mode 100644 flang-rt/unittests/Runtime/CMakeLists.txt
 create mode 100644 flang-rt/unittests/Runtime/CUDA/CMakeLists.txt
 create mode 100644 flang/cmake/modules/FlangCommon.cmake

diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 68a17edf8ca341..17a8a4dd8d0a87 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -342,11 +342,15 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args,
                                     ArgStringList &CmdArgs) {
   assert(TC.getTriple().isKnownWindowsMSVCEnvironment() &&
          "can only add VS runtime library on Windows!");
-  // if -fno-fortran-main has been passed, skip linking Fortran_main.a
-  if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
-    CmdArgs.push_back(Args.MakeArgString(
-        "--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins")));
-  }
+
+  // Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI
+  // should only depend on msv(u)crt. LLVM still emits libgcc/compiler-rt
+  // functions in some cases like 128-bit integer math (__udivti3, __modti3,
+  // __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a
+  // dependency to Compiler-RT's builtin library where these are implemented.
+  CmdArgs.push_back(Args.MakeArgString(
+      "--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins")));
+
   unsigned RTOptionID = options::OPT__SLASH_MT;
   if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
     RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
diff --git a/flang-rt/.clang-tidy b/flang-rt/.clang-tidy
new file mode 100644
index 00000000000000..ee3a0ab2201bf3
--- /dev/null
+++ b/flang-rt/.clang-tidy
@@ -0,0 +1,2 @@
+Checks: '-llvm-include-order,readability-braces-around-statements,-readability-identifier-naming,-clang-diagnostic-*'
+InheritParentConfig: true
diff --git a/flang-rt/CMakeLists.txt b/flang-rt/CMakeLists.txt
new file mode 100644
index 00000000000000..655d0a55b40044
--- /dev/null
+++ b/flang-rt/CMakeLists.txt
@@ -0,0 +1,248 @@
+#===-- CMakeLists.txt ------------------------------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+#
+# Build instructions for the flang-rt library. This is file is intended to be
+# included using the LLVM_ENABLE_RUNTIMES mechanism.
+#
+#===------------------------------------------------------------------------===#
+
+if (NOT LLVM_RUNTIMES_BUILD)
+  message(FATAL_ERROR "Use this CMakeLists.txt from LLVM's runtimes build system.
+      Example:
+        cmake <llvm-project>/runtimes -DLLVM_ENABLE_RUNTIMES=flang-rt
+    ")
+endif ()
+
+set(LLVM_SUBPROJECT_TITLE "Flang-RT")
+set(FLANG_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+set(FLANG_RT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+set(FLANG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../flang")
+
+# CMake 3.24 is the first version of CMake that directly recognizes Flang.
+# LLVM's requirement is only CMake 3.20, teach CMake 3.20-3.23 how to use Flang.
+if (CMAKE_VERSION VERSION_LESS "3.24")
+  cmake_path(GET CMAKE_Fortran_COMPILER STEM _Fortran_COMPILER_STEM)
+  if (_Fortran_COMPILER_STEM STREQUAL "flang-new" OR _Fortran_COMPILER_STEM STREQUAL "flang")
+    include(CMakeForceCompiler)
+    CMAKE_FORCE_Fortran_COMPILER("${CMAKE_Fortran_COMPILER}" "LLVMFlang")
+
+    set(CMAKE_Fortran_COMPILER_ID "LLVMFlang")
+    set(CMAKE_Fortran_COMPILER_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}")
+
+    set(CMAKE_Fortran_SUBMODULE_SEP "-")
+    set(CMAKE_Fortran_SUBMODULE_EXT ".mod")
+
+    set(CMAKE_Fortran_PREPROCESS_SOURCE
+      "<CMAKE_Fortran_COMPILER> -cpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+
+    set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
+    set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
+
+    set(CMAKE_Fortran_MODDIR_FLAG "-module-dir")
+
+    set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
+    set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")
+    set(CMAKE_Fortran_POSTPROCESS_FLAG "-ffixed-line-length-72")
+
+    set(CMAKE_Fortran_COMPILE_OPTIONS_TARGET "--target=")
+
+    set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")
+    set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",")
+  endif ()
+endif ()
+enable_language(Fortran)
+
+
+list(APPEND CMAKE_MODULE_PATH
+    "${FLANG_RT_SOURCE_DIR}/cmake/modules"
+    "${FLANG_SOURCE_DIR}/cmake/modules"
+  )
+include(AddFlangRT)
+include(GetToolchainDirs)
+include(FlangCommon)
+include(HandleCompilerRT)
+include(ExtendPath)
+
+
+############################
+# Build Mode Introspection #
+############################
+
+# Determine whether we are in the runtimes/runtimes-bins directory of a
+# bootstrap build.
+set(LLVM_TREE_AVAILABLE OFF)
+if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION)
+  set(LLVM_TREE_AVAILABLE ON)
+endif()
+
+# Path to LLVM development tools (FileCheck, llvm-lit, not, ...)
+set(LLVM_TOOLS_DIR "${LLVM_BINARY_DIR}/bin")
+
+# Determine build and install paths.
+# The build path is absolute, but the install dir is relative, CMake's install
+# command has to apply CMAKE_INSTALL_PREFIX itself.
+get_toolchain_library_subdir(toolchain_lib_subdir)
+if (LLVM_TREE_AVAILABLE)
+  # In a bootstrap build emit the libraries into a default search path in the
+  # build directory of the just-built compiler. This allows using the
+  # just-built compiler without specifying paths to runtime libraries.
+  #
+  # Despite Clang in the name, get_clang_resource_dir does not depend on Clang
+  # being added to the build. Flang uses the same resource dir as clang.
+  include(GetClangResourceDir)
+  get_clang_resource_dir(FLANG_RT_OUTPUT_RESOURCE_DIR PREFIX "${LLVM_LIBRARY_OUTPUT_INTDIR}/..")
+  get_clang_resource_dir(FLANG_RT_INSTALL_RESOURCE_PATH)
+
+  extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "${toolchain_lib_subdir}")
+else ()
+  # In a standalone runtimes build, do not write into LLVM_BINARY_DIR. It may be
+  # read-only and/or shared by multiple runtimes with different build
+  # configurations (e.g. Debug/Release). Use the runtime's own lib dir like any
+  # non-toolchain library.
+  # For the install prefix, still use the resource dir assuming that Flang will
+  # be installed there using the same prefix. This is to not have a difference
+  # between bootstrap and standalone runtimes builds.
+  set(FLANG_RT_OUTPUT_RESOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+  set(FLANG_RT_INSTALL_RESOURCE_PATH "lib${LLVM_LIBDIR_SUFFIX}/clang/${LLVM_VERSION_MAJOR}")
+
+  extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "lib${LLVM_LIBDIR_SUFFIX}")
+endif ()
+extend_path(FLANG_RT_INSTALL_RESOURCE_LIB_PATH "${FLANG_RT_INSTALL_RESOURCE_PATH}" "${toolchain_lib_subdir}")
+cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_DIR)
+cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_PATH)
+cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_LIB_DIR)
+cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_LIB_PATH)
+
+
+#################
+# Build Options #
+#################
+
+# Important: flang-rt user options must be prefixed with "FLANG_RT_". Variables
+# with this prefix will be forwarded in bootstrap builds.
+
+option(FLANG_RT_INCLUDE_TESTS "Generate build targets for the flang-rt unit and regression-tests." "${LLVM_INCLUDE_TESTS}")
+
+
+set(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT "" CACHE STRING "Compile Flang-RT with GPU support (CUDA or OpenMP)")
+set_property(CACHE FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT PROPERTY STRINGS
+    ""
+    CUDA
+    OpenMP
+  )
+if (NOT FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT)
+  # Support for GPUs disabled
+elseif (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
+  # Support for CUDA
+  set(FLANG_RT_LIBCUDACXX_PATH "" CACHE PATH "Path to libcu++ package installation")
+  option(FLANG_RT_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS "Do not compile global variables' definitions when producing PTX library" OFF)
+elseif (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")
+  # Support for OpenMP offloading
+  set(FLANG_RT_DEVICE_ARCHITECTURES "all" CACHE STRING
+      "List of OpenMP device architectures to be used to compile the Fortran runtime (e.g. 'gfx1103;sm_90')"
+    )
+
+  if (FLANG_RT_DEVICE_ARCHITECTURES STREQUAL "all")
+    # TODO: support auto detection on the build system.
+    set(all_amdgpu_architectures
+      "gfx700;gfx701;gfx801;gfx803;gfx900;gfx902;gfx906"
+      "gfx908;gfx90a;gfx90c;gfx940;gfx1010;gfx1030"
+      "gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036"
+      "gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151"
+      "gfx1152;gfx1153")
+    set(all_nvptx_architectures
+      "sm_35;sm_37;sm_50;sm_52;sm_53;sm_60;sm_61;sm_62"
+      "sm_70;sm_72;sm_75;sm_80;sm_86;sm_89;sm_90")
+    set(all_gpu_architectures
+      "${all_amdgpu_architectures};${all_nvptx_architectures}")
+      set(FLANG_RT_DEVICE_ARCHITECTURES ${all_gpu_architectures})
+  endif()
+  list(REMOVE_DUPLICATES FLANG_RT_DEVICE_ARCHITECTURES)
+else ()
+  message(FATAL_ERROR "Invalid value '${FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT}' for FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT; must be empty, 'CUDA', or 'OpenMP'")
+endif ()
+
+
+option(FLANG_RT_ENABLE_CUF "Compile CUDA Fortran runtime sources" OFF)
+if (FLANG_RT_ENABLE_CUF)
+  find_package(CUDAToolkit REQUIRED)
+endif()
+
+
+########################
+# System Introspection #
+########################
+
+include(CheckCXXSymbolExists)
+include(CheckCXXSourceCompiles)
+check_cxx_symbol_exists(strerror_r string.h HAVE_STRERROR_R)
+# Can't use symbol exists here as the function is overloaded in C++
+check_cxx_source_compiles(
+  "#include <string.h>
+   int main() {
+     char buf[4096];
+     return strerror_s(buf, 4096, 0);
+   }
+  "
+  HAVE_DECL_STRERROR_S)
+
+
+# Search for clang_rt.builtins library. Need in addition to msvcrt.
+if (WIN32)
+  find_compiler_rt_library(builtins FLANG_RT_BUILTINS_LIBRARY)
+endif ()
+
+
+# Check whether the compiler can undefine a macro using the "-U" flag.
+# Aternatively, we could use
+#   CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU"
+# but some older versions of CMake don't define it for GCC itself.
+check_cxx_compiler_flag("-UTESTFLAG" FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
+
+
+#####################
+# Build Preparation #
+#####################
+
+if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT AND FLANG_RT_INCLUDE_TESTS)
+  # If Fortran runtime is built as CUDA library, the linking
+  # of targets that link flang-rt must be done
+  # with CUDA_RESOLVE_DEVICE_SYMBOLS.
+  # CUDA language must be enabled for CUDA_RESOLVE_DEVICE_SYMBOLS
+  # to take effect.
+  enable_language(CUDA)
+endif()
+
+
+# C++17 is required for flang-rt; user or other runtimes may override this.
+# GTest included later also requires C++17.
+set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to")
+set(CMAKE_CXX_STANDARD_REQUIRED YES)
+
+
+configure_file(cmake/config.h.cmake.in config.h)
+
+
+# The bootstrap build will create a phony target with the same as the top-level
+# directory ("flang-rt") and delegate it to the runtimes build dir.
+# AddFlangRT will add all non-EXCLUDE_FROM_ALL targets to it.
+add_custom_target(flang-rt)
+
+
+###################
+# Build Artifacts #
+###################
+
+add_subdirectory(lib)
+
+if (FLANG_RT_INCLUDE_TESTS)
+  add_subdirectory(unittests)
+  add_subdirectory(test)
+else ()
+  add_custom_target(check-flang-rt)
+endif()
diff --git a/flang-rt/CODE_OWNERS.TXT b/flang-rt/CODE_OWNERS.TXT
new file mode 100644
index 00000000000000..649243aa1e8fec
--- /dev/null
+++ b/flang-rt/CODE_OWNERS.TXT
@@ -0,0 +1,14 @@
+This file is a list of the people responsible for ensuring that patches for a
+particular part of Flang are reviewed, either by themself or by someone else.
+They are also the gatekeepers for their part of Flang, with the final word on
+what goes in or not.
+
+The list is sorted by surname and formatted to allow easy grepping and
+beautification by scripts. The fields are: name (N), email (E), web-address
+(W), PGP key ID and fingerprint (P), description (D), snail-mail address
+(S) and (I) IRC handle. Each entry should contain at least the (N), (E) and
+(D) fields.
+
+N: Steve Scalpone
+E: sscalpone at nvidia.com
+D: Anything not covered by others
diff --git a/flang-rt/LICENSE.TXT b/flang-rt/LICENSE.TXT
new file mode 100644
index 00000000000000..53bb2e7fbc7643
--- /dev/null
+++ b/flang-rt/LICENSE.TXT
@@ -0,0 +1,234 @@
+==============================================================================
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+    1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+    2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+    3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+    4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+    5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+    6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+    7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+    8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+    9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+    END OF TERMS AND CONDITIONS
+
+    APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+    Copyright [yyyy] [name of copyright owner]
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+   `LICENSE` file at the top containing the specific license and restrictions
+   which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+   file.
diff --git a/flang-rt/README.md b/flang-rt/README.md
new file mode 100644
index 00000000000000..76993f27f8e4f2
--- /dev/null
+++ b/flang-rt/README.md
@@ -0,0 +1,188 @@
+<!--===- README.md
+
+   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
+
+-->
+
+# Fortran Runtime (Flang-RT)
+
+Flang-RT is the runtime library for code emitted by the Flang compiler
+(https://flang.llvm.org).
+
+
+## Getting Started
+
+There are two build modes for the Flang-RT. The bootstrap build, also
+called the in-tree build, and the runtime-only build, also called the
+out-of-tree build.
+Not to be confused with the terms
+[in-source and out-of-source](https://cmake.org/cmake/help/latest/manual/cmake.1.html#introduction-to-cmake-buildsystems)
+builds as defined by CMake. In an in-source build, the source directory and the
+build directory are identical, whereas with an out-of-source build the
+build artifacts are stored somewhere else, possibly in a subdirectory of the
+source directory. LLVM does not support in-source builds.
+
+
+### Requirements
+
+Requirements:
+  * [Same as LLVM](https://llvm.org/docs/GettingStarted.html#requirements).
+
+
+### Bootstrapping Runtimes Build
+
+The bootstrapping build will first build Clang and Flang, then use these
+compilers to compile Flang-RT. CMake will create a secondary build tree
+configured to use these just-built compilers. The secondary build will reuse
+the same build options (Flags, Debug/Release, ...) as the primary build.
+It will also ensure that once built, Flang-RT is found by Flang from either
+the build- or install-prefix. To enable, add `flang-rt` to
+`LLVM_ENABLE_RUNTIMES`:
+
+```bash
+cmake -S <path-to-llvm-project-source>/llvm \
+  -GNinja                                   \
+  -DLLVM_ENABLE_PROJECTS="clang;flang"      \
+  -DLLVM_ENABLE_RUNTIMES=flang-rt           \
+  ...
+```
+
+It is recommended to enable building OpenMP alongside Flang and Flang-RT
+as well. This will build `omp_lib.mod` required to use OpenMP from Fortran.
+Building Compiler-RT may also be required, particularly on platforms that do
+not provide all C-ABI functionality (such as Windows).
+
+```bash
+cmake -S <path-to-llvm-project-source>/llvm     \
+  -GNinja                                       \
+  -DCMAKE_BUILD_TYPE=Release                    \
+  -DLLVM_ENABLE_PROJECTS="clang;flang;openmp"   \
+  -DLLVM_ENABLE_RUNTIMES="compiler-rt;flang-rt" \
+  ...
+```
+
+By default, the enabled runtimes will only be built for the host platform
+(`-DLLVM_RUNTIME_TARGETS=default`). To add additional targets to support
+cross-compilation via `flang --target=<target-triple>`, add more triples to
+`LLVM_RUNTIME_TARGETS`, such as
+`-DLLVM_RUNTIME_TARGETS="default;aarch64-linux-gnu"`.
+
+After configuration, build, test, and install the runtime(s) via
+
+```shell
+$ ninja flang-rt
+$ ninja check-flang-rt
+$ ninja install
+```
+
+
+### Standalone Runtimes Build
+
+Instead of building Clang and Flang from scratch, the standalone Runtime build
+uses CMake's environment introspection to find a C, C++, and Fortran compiler.
+The compiler to be used can be controlled using CMake's standard mechanisms such
+as `CMAKE_CXX_COMPILER`, `CMAKE_CXX_COMPILER`, and `CMAKE_Fortran_COMPILER`.
+`CMAKE_Fortran_COMPILER` must be `flang` built from the same Git commit as
+Flang-RT to ensure they are using the same ABI. The C and C++ compiler
+can be any compiler supporting the same ABI.
+
+In addition to the compiler, the build be able to find LLVM development tools
+such as `lit` and `FileCheck` that are not found in an LLVM's install
+directory. Use `CMAKE_BINARY_DIR` to point to directory where LLVM has
+been built. A simple build configuration might look like the following:
+
+```bash
+cmake -S <path-to-llvm-project-source>/runtimes              \
+  -GNinja                                                    \
+  -DLLVM_BINARY_DIR=<path-to-llvm-builddir>                  \
+  -DCMAKE_Fortran_COMPILER=<path-to-llvm-builddir>/bin/flang \
+  -DCMAKE_Fortran_COMPILER_WORKS=yes                         \
+  -DLLVM_ENABLE_RUNTIMES=flang-rt                            \
+  ...
+```
+
+The `CMAKE_Fortran_COMPILER_WORKS` parameter must be set because otherwise CMake
+will test whether the Fortran compiler can compile and link programs which will
+obviously fail without a runtime library available yet.
+
+Building Flang-RT for cross-compilation triple, the target triple can
+be selected using `LLVM_DEFAULT_TARGET_TRIPLE` AND `LLVM_RUNTIMES_TARGET`.
+Of course, Flang-RT can be built multiple times with different build
+configurations, but have to be located manually when using with the Flang
+driver using the `-L` option.
+
+After configuration, build, test, and install the runtime via
+
+```shell
+$ ninja
+$ ninja check-flang-rt
+$ ninja install
+```
+
+
+## Configuration Option Reference
+
+Flang-RT has the followign configuration options. This is in
+addition to the build options the LLVM_ENABLE_RUNTIMES mechanism and
+CMake itself provide.
+
+ * `FLANG_RT_INCLUDE_TESTS` (boolean; default: `ON`)
+
+   When `OFF`, does not add any tests and unittests. The `check-flang-rt`
+   build target will do nothing.
+
+ * `FLANG_RUNTIME_F128_MATH_LIB` (default: `""`)
+
+   Determines the implementation of `REAL(16)` math functions. If set to
+   `libquadmath`, uses `quadmath.h` and `-lquadmath` typically distributed with
+   gcc. If empty, disables `REAL(16)` support. For any other value, introspects
+   the compiler for `__float128` or 128-bit `long double` support.
+   [More details](docs/Real16MathSupport.md).
+
+ * `FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT` (values: `"CUDA"`,`"OpenMP"`, `""` default: `""`)
+
+   When set to `CUDA`, builds Flang-RT with experimental support for GPU
+   accelerators using CUDA. `CMAKE_CUDA_COMPILER` must be set if not
+   automatically detected by CMake. `nvcc` as well as `clang` are supported.
+
+   When set to `OpenMP`, builds Flang-RT with experimental support for
+   GPU accelerators using OpenMP offloading. Only Clang is supported for
+   `CMAKE_C_COMPILER` and `CMAKE_CXX_COMPILER`.
+
+ * `FLANG_RT_ENABLE_CUF` (bool, default: `OFF`)
+
+   Compiles the `libCufRuntime_cuda_<CUDA-version>.a/.so` library. This is
+   independent of `FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA` and only
+   requires a
+   [CUDA Toolkit installation](https://cmake.org/cmake/help/latest/module/FindCUDAToolkit.html)
+   (no `CMAKE_CUDA_COMPILER`).
+
+
+### Experimental CUDA Support
+
+With `-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA`, the following
+additional configuration options become available.
+
+ * `FLANG_RT_LIBCUDACXX_PATH` (path, default: `""`)
+
+   Path to libcu++ package installation.
+
+ * `FLANG_RT_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS` (boolean, default: `OFF`)
+
+   Do not compile global variables' definitions when producing PTX library.
+   Default is `OFF`, meaning global variable definitions are compiled by
+   default.
+
+
+### Experimental OpenMP Offload Support
+
+With `-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=OpenMP`, the following
+additional configuration options become available.
+
+ * `FLANG_RT_DEVICE_ARCHITECTURES` (default: `"all"`)
+
+   A list of device architectures that Flang-RT is going to support.
+   If `"all"` uses a pre-defined list of architectures. Same purpose as
+   `LIBOMPTARGET_DEVICE_ARCHITECTURES` from liboffload.
diff --git a/flang-rt/cmake/modules/AddFlangRT.cmake b/flang-rt/cmake/modules/AddFlangRT.cmake
new file mode 100644
index 00000000000000..aa8adedf61752a
--- /dev/null
+++ b/flang-rt/cmake/modules/AddFlangRT.cmake
@@ -0,0 +1,186 @@
+#===-- cmake/modules/AddFlangRT.cmake --------------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+# Builds a library with common options for flang-rt.
+#
+# Usage:
+#
+# add_flangrt_library(name sources ...
+#   SHARED
+#     Build a dynamic (.so/.dll) library
+#   STATIC
+#     Build a static (.a/.lib) library
+#   OBJECT
+#     Create only object files without static/dynamic library
+#   INSTALL_WITH_TOOLCHAIN
+#     Install library into Clang's resource directory so it can be found by the
+#     Flang driver during compilation, including tests
+#   EXCLUDE_FROM_ALL
+#     Do not build library by default; typically used for libraries needed for
+#     testing only, no install
+#   LINK_TO_LLVM
+#     Library requires include path and linking to LLVM's Support component
+#   ADDITIONAL_HEADERS
+#     May specify header files for IDE generators.
+#   INCLUDE_DIRECTORIES
+#     Additional include_directories for all added targets
+#   TARGET_PROPERTIES
+#     Set target properties of all added targets
+# )
+function (add_flangrt_library name)
+  set(options STATIC SHARED OBJECT INSTALL_WITH_TOOLCHAIN EXCLUDE_FROM_ALL LINK_TO_LLVM)
+  set(multiValueArgs ADDITIONAL_HEADERS INCLUDE_DIRECTORIES TARGET_PROPERTIES)
+  cmake_parse_arguments(ARG
+    "${options}"
+    ""
+    "${multiValueArgs}"
+    ${ARGN})
+
+  if (ARG_INSTALL_WITH_TOOLCHAIN AND ARG_EXCLUDE_FROM_ALL)
+    message(SEND_ERROR "add_flangrt_library(${name} ...):
+        INSTALL_WITH_TOOLCHAIN and EXCLUDE_FROM_ALL are in conflict. When
+        installing an artifact it must have been built first in the 'all' target.
+      ")
+  endif ()
+
+  # Forward libtype to add_library
+  set(extra_args "")
+  if (ARG_SHARED)
+    list(APPEND extra_args SHARED)
+  endif ()
+  if (ARG_STATIC)
+    list(APPEND extra_args STATIC)
+  endif ()
+  if (ARG_OBJECT)
+    list(APPEND extra_args OBJECT)
+  endif ()
+  if (ARG_EXCLUDE_FROM_ALL)
+    list(APPEND extra_args EXCLUDE_FROM_ALL)
+  endif ()
+
+  # Also add header files to IDEs to list as part of the library.
+  set_source_files_properties(${ARG_ADDITIONAL_HEADERS} PROPERTIES HEADER_FILE_ONLY ON)
+
+  add_library(${name} ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
+
+  if (ARG_INSTALL_WITH_TOOLCHAIN)
+    set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Toolchain Libraries")
+  elseif (ARG_OBJECT)
+    set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Object Libraries")
+  else ()
+    set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Libraries")
+  endif ()
+
+  # Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else.
+  target_compile_features(${name} PRIVATE cxx_std_17)
+
+  # Use compiler-specific options to disable exceptions and RTTI.
+  if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
+    target_compile_options(${name} PRIVATE
+        $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
+      )
+  elseif (MSVC)
+    target_compile_options(${name} PRIVATE
+        $<$<COMPILE_LANGUAGE:CXX>:/EHs-c- /GR->
+      )
+  elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
+    target_compile_options(${name} PRIVATE
+        $<$<COMPILE_LANGUAGE:CXX>:-qnoeh -qnortti>
+      )
+  endif ()
+
+  # Also for CUDA source when compiling with FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA
+  if (CMAKE_CUDA_COMPILER_ID MATCHES "NVIDIA")
+    # Assuming gcc as host compiler.
+    target_compile_options(${name} PRIVATE
+        $<$<COMPILE_LANGUAGE:CUDA>:--no-exceptions -Xcompiler -fno-rtti -Xcompiler -fno-unwind-tables -Xcompiler -fno-asynchronous-unwind-tables>
+      )
+  else ()
+    # Assuming a clang-compatible CUDA compiler.
+    target_compile_options(${name} PRIVATE
+        $<$<COMPILE_LANGUAGE:CUDA>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
+      )
+  endif ()
+
+  # Flang-RT's public headers
+  target_include_directories(${name} PRIVATE "${FLANG_RT_SOURCE_DIR}/include")
+
+  # For ISO_Fortran_binding.h to be found by the runtime itself (Accessed as #include "flang/ISO_Fortran_binding.h")
+  # User applications can use #include <ISO_Fortran_binding.h>
+  target_include_directories(${name} PRIVATE "${FLANG_SOURCE_DIR}/include")
+
+  # For Flang-RT's configured config.h to be found
+  target_include_directories(${name} PRIVATE "${FLANG_RT_BINARY_DIR}")
+
+  # Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS
+  # build, to avoid an unwanted dependency on libstdc++/libc++.so.
+  if (FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
+    target_compile_options(${name} PUBLIC -U_GLIBCXX_ASSERTIONS)
+    target_compile_options(${name} PUBLIC -U_LIBCPP_ENABLE_ASSERTIONS)
+  endif ()
+
+  # Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI
+  # should only depend on msvcrt/ucrt. LLVM still emits libgcc/compiler-rt
+  # functions in some cases like 128-bit integer math (__udivti3, __modti3,
+  # __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a
+  # dependency to Compiler-RT's builtin library where these are implemented.
+  if (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+    if (FLANG_RT_BUILTINS_LIBRARY)
+      target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:CXX,C>:-Xclang>" "$<$<COMPILE_LANGUAGE:CXX,C>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
+    endif ()
+  endif ()
+  if (MSVC AND CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
+    if (FLANG_RT_BUILTINS_LIBRARY)
+      target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:Fortran>:-Xflang>" "$<$<COMPILE_LANGUAGE:Fortran>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
+    else ()
+      message(WARNING "Did not find libclang_rt.builtins.lib.
+        LLVM may emit builtins that are not implemented in msvcrt/ucrt and
+        instead falls back to builtins from Compiler-RT. Linking with ${name}
+        may result in a linker error.")
+    endif ()
+  endif ()
+
+  # Non-GTest unittests depend on LLVMSupport
+  if (ARG_LINK_TO_LLVM)
+    if (LLVM_LINK_LLVM_DYLIB)
+      set(llvm_libs LLVM)
+    else()
+      llvm_map_components_to_libnames(llvm_libs Support)
+    endif()
+    target_link_libraries(${name} PUBLIC ${llvm_libs})
+    target_include_directories(${name} PUBLIC ${LLVM_INCLUDE_DIRS})
+  endif ()
+
+  if (ARG_INCLUDE_DIRECTORIES)
+    target_include_directories(${name} ${ARG_INCLUDE_DIRECTORIES})
+  endif ()
+
+  # If this is part of the toolchain, put it into the compiler's resource
+  # directory. Otherwise it is part of testing and is not installed at all.
+  # TODO: Consider multi-configuration builds (MSVC_IDE, "Ninja Multi-Config")
+  if (ARG_INSTALL_WITH_TOOLCHAIN)
+    set_target_properties(${name}
+      PROPERTIES
+        ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
+      )
+
+    install(TARGETS ${name}
+        ARCHIVE DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
+      )
+  endif ()
+
+  if (ARG_TARGET_PROPERTIES)
+    set_target_properties(${name} PROPERTIES ${ARG_TARGET_PROPERTIES})
+  endif ()
+
+  # flang-rt should build all the Flang-RT targets that are built in an
+  # 'all' build.
+  if (NOT ARG_EXCLUDE_FROM_ALL)
+    add_dependencies(flang-rt ${name})
+  endif ()
+endfunction (add_flangrt_library)
diff --git a/flang-rt/cmake/modules/AddFlangRTOffload.cmake b/flang-rt/cmake/modules/AddFlangRTOffload.cmake
new file mode 100644
index 00000000000000..b055646cb0604c
--- /dev/null
+++ b/flang-rt/cmake/modules/AddFlangRTOffload.cmake
@@ -0,0 +1,101 @@
+#===-- cmake/modules/AddFortranRTOffload.txt -------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+macro(enable_cuda_compilation name files)
+  if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
+    enable_language(CUDA)
+
+    set_target_properties(${name}
+        PROPERTIES
+          CUDA_SEPARABLE_COMPILATION ON
+      )
+
+    # Treat all supported sources as CUDA files.
+    set_source_files_properties(${files} PROPERTIES LANGUAGE CUDA)
+    set(CUDA_COMPILE_OPTIONS)
+    if ("${CMAKE_CUDA_COMPILER_ID}" MATCHES "Clang")
+      # Allow varargs.
+      set(CUDA_COMPILE_OPTIONS
+        -Xclang -fcuda-allow-variadic-functions
+        )
+    endif()
+    if ("${CMAKE_CUDA_COMPILER_ID}" MATCHES "NVIDIA")
+      set(CUDA_COMPILE_OPTIONS
+        --expt-relaxed-constexpr
+        # Disable these warnings:
+        #   'long double' is treated as 'double' in device code
+        -Xcudafe --diag_suppress=20208
+        -Xcudafe --display_error_number
+        )
+    endif()
+    set_source_files_properties(${files} PROPERTIES COMPILE_OPTIONS
+      "${CUDA_COMPILE_OPTIONS}"
+      )
+
+    # Create a .a library consisting of CUDA PTX.
+    # This is different from a regular static library. The CUDA_PTX_COMPILATION
+    # property can only be applied to object libraries and create *.ptx files
+    # instead of *.o files. The .a will consist of those *.ptx files only.
+    add_flangrt_library(obj.${name}PTX OBJECT ${files})
+    set_property(TARGET obj.${name}PTX PROPERTY CUDA_PTX_COMPILATION ON)
+    add_flangrt_library(${name}PTX STATIC "$<TARGET_OBJECTS:obj.${name}PTX>")
+
+    # Apply configuration options
+    if (FLANG_RT_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS)
+      target_compile_definitions(obj.${name}PTX
+        PRIVATE FLANG_RUNTIME_NO_GLOBAL_VAR_DEFS
+        )
+    endif()
+
+    # When using libcudacxx headers files, we have to use them
+    # for all files of Flang-RT.
+    if (EXISTS "${FLANG_RT_LIBCUDACXX_PATH}/include")
+      foreach (tgt IN ITEMS "${name}" "obj.${name}PTX")
+        target_include_directories(${tgt} AFTER PRIVATE "${FLANG_RT_LIBCUDACXX_PATH}/include")
+        target_compile_definitions(${tgt} PRIVATE RT_USE_LIBCUDACXX=1)
+      endforeach ()
+    endif ()
+  endif()
+endmacro()
+
+macro(enable_omp_offload_compilation name files)
+  if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")
+    # OpenMP offload build only works with Clang compiler currently.
+
+    if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND
+        "${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
+
+      string(REPLACE ";" "," compile_for_architectures
+        "${FLANG_RT_DEVICE_ARCHITECTURES}"
+        )
+
+      set(OMP_COMPILE_OPTIONS
+        -fopenmp
+        -fvisibility=hidden
+        -fopenmp-cuda-mode
+        --offload-arch=${compile_for_architectures}
+        # Force LTO for the device part.
+        -foffload-lto
+        )
+      set_source_files_properties(${files} PROPERTIES COMPILE_OPTIONS
+        "${OMP_COMPILE_OPTIONS}"
+        )
+      target_link_options(${name} PUBLIC ${OMP_COMPILE_OPTIONS})
+
+      # Enable "declare target" in the source code.
+      set_source_files_properties(${files}
+        PROPERTIES COMPILE_DEFINITIONS OMP_OFFLOAD_BUILD
+        )
+    else()
+      message(FATAL_ERROR
+        "Flang-rt build with OpenMP offload is not supported for these compilers:\n"
+        "CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}\n"
+        "CMAKE_C_COMPILER_ID: ${CMAKE_C_COMPILER_ID}")
+    endif()
+  endif()
+endmacro()
diff --git a/flang-rt/cmake/modules/GetToolchainDirs.cmake b/flang-rt/cmake/modules/GetToolchainDirs.cmake
new file mode 100644
index 00000000000000..426a5e8e801f3d
--- /dev/null
+++ b/flang-rt/cmake/modules/GetToolchainDirs.cmake
@@ -0,0 +1,125 @@
+#===-- cmake/modules/GetToolchainDirs.cmake --------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+
+# Determine the subdirectory relative to Clang's resource dir/sysroot where to
+# install target-specific libraries, to be found by Clang/Flang driver. This was
+# adapted from Compiler-RT's mechanism to find the path for
+# libclang_rt.builtins.a.
+#
+# Compiler-RT has two mechanisms for the path (simplified):
+#
+# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=1: lib/${oslibname}/libclang_rt.builtins-${arch}.a
+# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=0: lib/${triple}/libclang_rt.builtins.a
+#
+# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON is the newer scheme, but the old one is
+# currently still used for some platforms such as Windows. Clang looks for which
+# of the files exist before passing the path to the linker. Hence, the
+# directories have to match what Clang is looking for, which is done in
+# ToolChain::getArchSpecificLibPaths(..), ToolChain::getRuntimePath(),
+# ToolChain::getCompilerRTPath(), and ToolChain::getCompilerRT(..), not entirely
+# consistent between these functions, Compiler-RT's CMake code, and overrides
+# in different toolchains.
+#
+# For Fortran, Flang always assumes the library name libflang_rt.a without
+# architecture suffix. Hence, we always use the second scheme even as if
+# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, even if it actually set to OFF. It as
+# added unconditionally to the library search path by
+# ToolChain::getArchSpecificLibPaths(...).
+function (get_toolchain_library_subdir outvar)
+  if (NOT APPLE)
+    set(outval "lib")
+  else ()
+    # Required to be "darwin" for MachO toolchain.
+    get_toolchain_os_dirname(os_dirname)
+    set(outval "lib/${os_dirname}")
+  endif ()
+
+  get_toolchain_arch_dirname(arch_dirname)
+  set(outval "lib/${arch_dirname}")
+
+  set(${outvar} "${outval}" PARENT_SCOPE)
+endfunction ()
+
+
+# Corresponds to Clang's ToolChain::getOSLibName(). Adapted from Compiler-RT.
+function (get_toolchain_os_dirname outvar)
+  if (ANDROID)
+    # The CMAKE_SYSTEM_NAME for Android is "Android", but the OS is Linux and the
+    # driver will search for libraries in the "linux" directory.
+    set(outval "linux")
+  else ()
+    string(TOLOWER "${CMAKE_SYSTEM_NAME}" outval)
+  endif ()
+  set(${outvar} "${outval}" PARENT_SCOPE)
+endfunction ()
+
+
+# Corresponds to Clang's ToolChain::getRuntimePath(). Adapted from Compiler-RT.
+function (get_toolchain_arch_dirname outvar)
+  string(REPLACE "-" ";" triple_list ${LLVM_TARGET_TRIPLE})
+  list(GET triple_list 0 arch)
+
+  if("${arch}" MATCHES "^i.86$")
+    # Android uses i686, but that's remapped at a later stage.
+    set(arch "i386")
+  endif()
+
+  string(FIND ${LLVM_TARGET_TRIPLE} "-" dash_index)
+  string(SUBSTRING ${LLVM_TARGET_TRIPLE} ${dash_index} -1 triple_suffix)
+  string(SUBSTRING ${LLVM_TARGET_TRIPLE} 0 ${dash_index} triple_cpu)
+  set(arch "${triple_cpu}")
+  if("${arch}" MATCHES "^i.86$")
+    # Android uses i686, but that's remapped at a later stage.
+    set(arch "i386")
+  endif()
+
+  if(ANDROID AND ${arch} STREQUAL "i386")
+    set(target "i686${triple_suffix}")
+  elseif(${arch} STREQUAL "amd64")
+    set(target "x86_64${triple_suffix}")
+  elseif(${arch} STREQUAL "sparc64")
+    set(target "sparcv9${triple_suffix}")
+  elseif("${arch}" MATCHES "mips64|mips64el")
+    string(REGEX REPLACE "-gnu.*" "-gnuabi64" triple_suffix_gnu "${triple_suffix}")
+    string(REGEX REPLACE "mipsisa32" "mipsisa64" triple_cpu_mips "${triple_cpu}")
+    string(REGEX REPLACE "^mips$" "mips64" triple_cpu_mips "${triple_cpu_mips}")
+    string(REGEX REPLACE "^mipsel$" "mips64el" triple_cpu_mips "${triple_cpu_mips}")
+    set(target "${triple_cpu_mips}${triple_suffix_gnu}")
+  elseif("${arch}" MATCHES "mips|mipsel")
+    string(REGEX REPLACE "-gnuabi.*" "-gnu" triple_suffix_gnu "${triple_suffix}")
+    string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}")
+    string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}")
+    set(target "${triple_cpu_mips}${triple_suffix_gnu}")
+  elseif("${arch}" MATCHES "^arm")
+    # FIXME: Handle arch other than arm, armhf, armv6m
+    if (${arch} STREQUAL "armhf")
+      # If we are building for hard float but our ABI is soft float.
+      if ("${triple_suffix}" MATCHES ".*eabi$")
+        # Change "eabi" -> "eabihf"
+        set(triple_suffix "${triple_suffix}hf")
+      endif()
+      # ABI is already set in the triple, don't repeat it in the architecture.
+      set(arch "arm")
+    else ()
+      # If we are building for soft float, but the triple's ABI is hard float.
+      if ("${triple_suffix}" MATCHES ".*eabihf$")
+        # Change "eabihf" -> "eabi"
+        string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}")
+      endif()
+    endif()
+    set(target "${arch}${triple_suffix}")
+  elseif("${arch}" MATCHES "^amdgcn")
+    set(target "amdgcn-amd-amdhsa")
+  elseif("${arch}" MATCHES "^nvptx")
+    set(target "nvptx64-nvidia-cuda")
+  else()
+    set(target "${arch}${triple_suffix}")
+  endif()
+  set(${outvar} "${target}" PARENT_SCOPE)
+endfunction()
diff --git a/flang-rt/lib/CMakeLists.txt b/flang-rt/lib/CMakeLists.txt
new file mode 100644
index 00000000000000..8e2e0fbbbc24fd
--- /dev/null
+++ b/flang-rt/lib/CMakeLists.txt
@@ -0,0 +1,18 @@
+#===-- lib/CMakeLists.txt --------------------------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+add_subdirectory(FortranFloat128Math)
+add_subdirectory(flang_rt)
+
+if (FLANG_RT_ENABLE_CUF)
+  add_subdirectory(flang_rt/CUDA)
+endif()
+
+if (FLANG_RT_INCLUDE_TESTS)
+  add_subdirectory(Testing)
+endif ()
diff --git a/flang-rt/lib/FortranFloat128Math/CMakeLists.txt b/flang-rt/lib/FortranFloat128Math/CMakeLists.txt
new file mode 100644
index 00000000000000..c0b2ee32248f87
--- /dev/null
+++ b/flang-rt/lib/FortranFloat128Math/CMakeLists.txt
@@ -0,0 +1,136 @@
+#===-- lib/FortranFloat128Math/CMakeLists.txt ------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+# FortranFloat128 implements IEEE-754 128-bit float math functions.
+# It is a thin wapper and it currently relies on third-party
+# libraries available for the target.
+# It is distributed as a static library only.
+# Fortran programs/libraries that end up linking any of the provided
+# will have a dependency on the third-party library that is being
+# used for building this FortranFloat128Math library.
+
+include(CheckLibraryExists)
+include(CheckIncludeFile)
+
+set(sources
+  acos.cpp
+  acosh.cpp
+  asin.cpp
+  asinh.cpp
+  atan.cpp
+  atan2.cpp
+  atanh.cpp
+  ceil.cpp
+  complex-math.c
+  cos.cpp
+  cosh.cpp
+  erf.cpp
+  erfc.cpp
+  exp.cpp
+  exponent.cpp
+  floor.cpp
+  fma.cpp
+  fraction.cpp
+  hypot.cpp
+  j0.cpp
+  j1.cpp
+  jn.cpp
+  lgamma.cpp
+  llround.cpp
+  log.cpp
+  log10.cpp
+  lround.cpp
+  mod-real.cpp
+  modulo-real.cpp
+  nearest.cpp
+  nearbyint.cpp
+  norm2.cpp
+  pow.cpp
+  random.cpp
+  remainder.cpp
+  round.cpp
+  rrspacing.cpp
+  scale.cpp
+  set-exponent.cpp
+  sin.cpp
+  sinh.cpp
+  spacing.cpp
+  sqrt.cpp
+  tan.cpp
+  tanh.cpp
+  tgamma.cpp
+  trunc.cpp
+  y0.cpp
+  y1.cpp
+  yn.cpp
+  )
+
+include_directories(AFTER "${CMAKE_CURRENT_SOURCE_DIR}/..")
+add_library(FortranFloat128MathILib INTERFACE)
+target_include_directories(FortranFloat128MathILib INTERFACE
+  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
+  )
+
+if (FLANG_RUNTIME_F128_MATH_LIB)
+  if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath")
+    check_include_file(quadmath.h FOUND_QUADMATH_HEADER)
+    if(FOUND_QUADMATH_HEADER)
+      add_compile_definitions(HAS_QUADMATHLIB)
+    else()
+      message(FATAL_ERROR
+        "FLANG_RUNTIME_F128_MATH_LIB setting requires quadmath.h "
+        "to be available: ${FLANG_RUNTIME_F128_MATH_LIB}"
+        )
+    endif()
+  else()
+    message(FATAL_ERROR
+      "Unsupported third-party library for Fortran F128 math runtime: "
+      "${FLANG_RUNTIME_F128_MATH_LIB}"
+      )
+  endif()
+
+  if (WIN32)
+    # Do not create a FortranFloat128Math library under Windows, the Flang
+    # driver never links it. Instead, add the sources to flang_rt itself.
+    target_sources(FortranFloat128MathILib INTERFACE ${sources})
+    target_compile_definitions(FortranFloat128MathILib INTERFACE HAS_QUADMATHLIB)
+  else ()
+    add_flangrt_library(FortranFloat128Math STATIC INSTALL_WITH_TOOLCHAIN
+      ${sources})
+    target_include_directories(FortranFloat128Math PRIVATE
+        "${FLANG_RT_SOURCE_DIR}/lib/flang_rt"
+      )
+  endif ()
+elseif (HAVE_LDBL_MANT_DIG_113)
+  # We can use 'long double' versions from libc.
+  check_library_exists(m sinl "" FOUND_LIBM)
+  if (FOUND_LIBM)
+    target_compile_definitions(FortranFloat128MathILib INTERFACE
+      HAS_LIBM
+      )
+    target_include_directories(FortranFloat128MathILib INTERFACE
+      "${FLANG_RT_SOURCE_DIR}/lib/flang_rt"
+      )
+    target_sources(FortranFloat128MathILib INTERFACE ${sources})
+  else()
+    message(FATAL_ERROR "Flang-RT cannot build without libm")
+  endif()
+else()
+  # We can use '__float128' version from libc, if it has them.
+  check_library_exists(m sinf128 "" FOUND_LIBMF128)
+  if (FOUND_LIBMF128)
+    target_compile_definitions(FortranFloat128MathILib INTERFACE
+      HAS_LIBMF128
+      )
+    target_include_directories(FortranFloat128MathILib INTERFACE
+      "${FLANG_RT_SOURCE_DIR}/lib/flang_rt"
+      )
+    # Enable this, when math-entries.h and complex-math.h is ready.
+    # target_sources(FortranFloat128MathILib INTERFACE ${sources})
+  endif()
+endif()
diff --git a/flang-rt/lib/Testing/CMakeLists.txt b/flang-rt/lib/Testing/CMakeLists.txt
new file mode 100644
index 00000000000000..19c20ad44c0251
--- /dev/null
+++ b/flang-rt/lib/Testing/CMakeLists.txt
@@ -0,0 +1,20 @@
+#===-- lib/Testing/CMakeLists.txt ------------------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+set(public_headers "")
+file(GLOB_RECURSE public_headers
+  "${FLANG_SOURCE_DIR}/lib/Testing/*.h"
+)
+
+add_flangrt_library(NonGTestTesting EXCLUDE_FROM_ALL LINK_TO_LLVM
+      ${FLANG_SOURCE_DIR}/lib/Testing/testing.cpp
+      ${FLANG_SOURCE_DIR}/lib/Testing/fp-testing.cpp
+
+    ADDITIONAL_HEADERS
+      ${public_headers}
+  )
diff --git a/flang-rt/lib/flang_rt/CMakeLists.txt b/flang-rt/lib/flang_rt/CMakeLists.txt
new file mode 100644
index 00000000000000..4db1a1cbb874fc
--- /dev/null
+++ b/flang-rt/lib/flang_rt/CMakeLists.txt
@@ -0,0 +1,213 @@
+#===-- lib/flang_rt/CMakeLists.txt -----------------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+include(AddFlangRTOffload)
+# function checks
+find_package(Backtrace)
+set(HAVE_BACKTRACE ${Backtrace_FOUND})
+set(BACKTRACE_HEADER ${Backtrace_HEADER})
+
+
+# List of files that are buildable for all devices.
+set(supported_sources
+  ${FLANG_SOURCE_DIR}/lib/Decimal/binary-to-decimal.cpp
+  ${FLANG_SOURCE_DIR}/lib/Decimal/decimal-to-binary.cpp
+  ISO_Fortran_binding.cpp
+  allocator-registry.cpp
+  allocatable.cpp
+  array-constructor.cpp
+  assign.cpp
+  buffer.cpp
+  character.cpp
+  connection.cpp
+  copy.cpp
+  derived-api.cpp
+  derived.cpp
+  descriptor-io.cpp
+  descriptor.cpp
+  dot-product.cpp
+  edit-input.cpp
+  edit-output.cpp
+  environment.cpp
+  external-unit.cpp
+  extrema.cpp
+  file.cpp
+  findloc.cpp
+  format.cpp
+  inquiry.cpp
+  internal-unit.cpp
+  io-api.cpp
+  io-api-minimal.cpp
+  io-error.cpp
+  io-stmt.cpp
+  iostat.cpp
+  matmul-transpose.cpp
+  matmul.cpp
+  memory.cpp
+  misc-intrinsic.cpp
+  namelist.cpp
+  non-tbp-dio.cpp
+  numeric.cpp
+  pointer.cpp
+  product.cpp
+  pseudo-unit.cpp
+  ragged.cpp
+  stat.cpp
+  sum.cpp
+  support.cpp
+  terminator.cpp
+  tools.cpp
+  transformational.cpp
+  type-code.cpp
+  type-info.cpp
+  unit.cpp
+  unit-map.cpp
+  utf.cpp
+)
+
+# List of source not used for GPU offloading.
+set(host_sources
+  ${FLANG_SOURCE_DIR}/module/iso_fortran_env_impl.f90
+  command.cpp
+  complex-powi.cpp
+  complex-reduction.c
+  exceptions.cpp
+  execute.cpp
+  extensions.cpp
+  main.cpp
+  random.cpp
+  reduce.cpp
+  reduction.cpp
+  stop.cpp
+  temporary-stack.cpp
+  time-intrinsic.cpp
+)
+
+file(GLOB_RECURSE public_headers
+  "${FLANG_RT_SOURCE_DIR}/include/flang_rt/*.h"
+  "${FLANG_SOURCE_DIR}/include/flang/Common/*.h"
+  )
+
+file(GLOB_RECURSE private_headers
+  "${FLANG_RT_SOURCE_DIR}/lib/flang_rt/*.h"
+  "${FLANG_SOURCE_DIR}/lib/Common/*.h"
+  )
+
+
+# Import changes from sibling FortranFloat128Math
+get_target_property(f128_sources
+  FortranFloat128MathILib INTERFACE_SOURCES
+  )
+if (f128_sources)
+  # The interface may define special macros for Float128Math files,
+  # so we need to propagate them.
+  get_target_property(f128_defs
+    FortranFloat128MathILib INTERFACE_COMPILE_DEFINITIONS
+    )
+  set_property(SOURCE ${f128_sources}
+    APPEND PROPERTY COMPILE_DEFINITIONS
+    ${f128_defs}
+    )
+  get_target_property(f128_include_dirs
+    FortranFloat128MathILib INTERFACE_INCLUDE_DIRECTORIES
+    )
+  set_property(SOURCE ${f128_sources}
+    APPEND PROPERTY INCLUDE_DIRECTORIES
+    ${f128_include_dirs}
+    )
+else ()
+  set(f128_sources "")
+endif ()
+
+
+set(sources ${supported_sources} ${host_sources} ${f128_sources})
+
+if (NOT WIN32)
+  add_flangrt_library(flang_rt STATIC
+    ${sources}
+    INSTALL_WITH_TOOLCHAIN
+    ADDITIONAL_HEADERS ${public_headers} ${private_headers}
+  )
+
+  enable_cuda_compilation(flang_rt "${supported_sources}")
+  enable_omp_offload_compilation(flang_rt "${supported_sources}")
+
+  # For unittests that depend on flang_rt. Should link to the static version
+  # of the library.
+  add_library(flang_rt.static ALIAS flang_rt)
+  add_library(flang_rt.unittest ALIAS flang_rt)
+else()
+  # Target for building all versions of the runtime
+  add_custom_target(flang_rt)
+  set_target_properties(flang_rt PROPERTIES FOLDER "Flang-RT/Meta")
+
+  function (add_win_flangrt_library libtype suffix msvc_lib)
+    set(name "flang_rt.${suffix}")
+    add_flangrt_library(${name} ${libtype}
+        ${sources}
+        ${ARGN}
+        ADDITIONAL_HEADERS ${public_headers} ${private_headers}
+      )
+
+    if (msvc_lib)
+      set_target_properties(${name}
+          PROPERTIES
+            MSVC_RUNTIME_LIBRARY "${msvc_lib}"
+        )
+    endif ()
+
+    # Setting an unique Fortran_MODULE_DIRECTORY is required for each variant to
+    # write a different .mod file.
+    set_target_properties(${name}
+        PROPERTIES
+          Fortran_MODULE_DIRECTORY "module.${suffix}"
+      )
+
+    enable_cuda_compilation(${name} "${supported_sources}")
+    enable_omp_offload_compilation(${name} "${supported_sources}")
+    add_dependencies(flang_rt ${name})
+  endfunction ()
+
+  # Variants of the static flang_rt for different versions of the msvc runtime.
+  #
+  # The dynamic/dynamic_dbg variants are not DLLs themselves, only require
+  # linking to msvcrt(d).dll.
+  # FIXME: Generating actual runtime DLLs is currently not possible. There are
+  # two roadblocks:
+  #
+  #  * Flang emits /DEFAULTLIB:flang_rt.dynamic.lib into
+  #    iso_fortran_env_impl.f90.obj. Because that file is itself part of
+  #    flang_rt.dynamic, this results in a recursive dependency when invoking
+  #    the linker.
+  #
+  #  * The externally-visible functions must either be annotated with
+  #    __declspec(dllexport), or listed in an exports file. A possible workaround
+  #    is CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS which would also export the internal
+  #    C++ symbols and still requires global data symbols to be annotated
+  #    manually.
+  add_win_flangrt_library(STATIC static      MultiThreaded         INSTALL_WITH_TOOLCHAIN)
+  add_win_flangrt_library(STATIC static_dbg  MultiThreadedDebug    INSTALL_WITH_TOOLCHAIN)
+  add_win_flangrt_library(STATIC dynamic     MultiThreadedDLL      INSTALL_WITH_TOOLCHAIN)
+  add_win_flangrt_library(STATIC dynamic_dbg MultiThreadedDebugDLL INSTALL_WITH_TOOLCHAIN)
+
+  # Unittests link against LLVMSupport which is using CMake's default runtime
+  # library selection, which is either MultiThreadedDLL or MultiThreadedDebugDLL
+  # depending on the configuration. They have to match or linking will fail.
+  if (GENERATOR_IS_MULTI_CONFIG)
+    # We cannot select an ALIAS library because it may be different
+    # per configuration. Fallback to CMake's default.
+    add_win_flangrt_library(STATIC unittest "" EXCLUDE_FROM_ALL)
+  else ()
+    string(TOLOWER ${CMAKE_BUILD_TYPE} build_type)
+    if (build_type STREQUAL "debug")
+      add_library(flang_rt.unittest ALIAS flang_rt.dynamic_dbg)
+    else ()
+      add_library(flang_rt.unittest ALIAS flang_rt.dynamic)
+    endif ()
+  endif ()
+endif()
diff --git a/flang-rt/lib/flang_rt/CUDA/CMakeLists.txt b/flang-rt/lib/flang_rt/CUDA/CMakeLists.txt
new file mode 100644
index 00000000000000..3c741ac93d64b2
--- /dev/null
+++ b/flang-rt/lib/flang_rt/CUDA/CMakeLists.txt
@@ -0,0 +1,33 @@
+#===-- lib/flang_rt/CUDA/CMakeLists.txt ------------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+
+add_flangrt_library(CufRuntime STATIC
+  allocatable.cpp
+  allocator.cpp
+  descriptor.cpp
+  kernel.cpp
+  memmove-function.cpp
+  memory.cpp
+  registration.cpp
+
+  # libCufRuntime depends on a certain version of CUDA. To be able to have
+  # multiple build of this library with different CUDA version, the version is
+  # added to the library name.
+  TARGET_PROPERTIES
+    OUTPUT_NAME "CufRuntime_cuda_${CUDAToolkit_VERSION_MAJOR}"
+
+  INCLUDE_DIRECTORIES
+    PRIVATE ${CUDAToolkit_INCLUDE_DIRS}
+)
+
+target_link_libraries(CufRuntime
+  PUBLIC
+  flang_rt
+  CUDA::cudart_static
+)
diff --git a/flang-rt/lib/flang_rt/io-api-minimal.cpp b/flang-rt/lib/flang_rt/io-api-minimal.cpp
index c3234c78c10c80..cd5cf6bd3e6991 100644
--- a/flang-rt/lib/flang_rt/io-api-minimal.cpp
+++ b/flang-rt/lib/flang_rt/io-api-minimal.cpp
@@ -150,7 +150,7 @@ bool IODEF(OutputLogical)(Cookie cookie, bool truth) {
 // Provide own definition for `std::__libcpp_verbose_abort` to avoid dependency
 // on the version provided by libc++.
 
-void std::__libcpp_verbose_abort(char const *format, ...) {
+void std::__libcpp_verbose_abort(char const *format, ...) noexcept {
   va_list list;
   va_start(list, format);
   std::vfprintf(stderr, format, list);
diff --git a/flang-rt/test/CMakeLists.txt b/flang-rt/test/CMakeLists.txt
new file mode 100644
index 00000000000000..5ca07b66e4f9b5
--- /dev/null
+++ b/flang-rt/test/CMakeLists.txt
@@ -0,0 +1,59 @@
+#===-- test/CMakeLists.txt -------------------------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+# Test runner infrastructure for Flang. This configures the Flang test trees
+# for use by Lit, and delegates to LLVM's lit test handlers.
+
+llvm_canonicalize_cmake_booleans(
+  FLANG_STANDALONE_BUILD
+  LLVM_BUILD_EXAMPLES
+  LLVM_BYE_LINK_INTO_TOOLS
+  LLVM_ENABLE_PLUGINS
+)
+
+configure_lit_site_cfg(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
+  MAIN_CONFIG
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
+)
+
+if (TARGET FlangRTUnitTests)
+  configure_lit_site_cfg(
+    ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
+    ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py
+    MAIN_CONFIG
+    ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py
+  )
+
+  configure_lit_site_cfg(
+    ${CMAKE_CURRENT_SOURCE_DIR}/NonGtestUnit/lit.site.cfg.py.in
+    ${CMAKE_CURRENT_BINARY_DIR}/NonGtestUnit/lit.site.cfg.py
+    MAIN_CONFIG
+    ${CMAKE_CURRENT_SOURCE_DIR}/NonGtestUnit/lit.cfg.py
+  )
+endif ()
+
+
+add_custom_target(flang-rt-test-depends)
+set_target_properties(flang-rt-test-depends PROPERTIES FOLDER "Flang-RT/Meta")
+add_dependencies(flang-rt-test-depends
+    FlangRTUnitTests
+    flang_rt.unittest
+    flang_rt.static
+  )
+
+add_lit_testsuite(check-flang-rt "Running the Flang-RT regression tests"
+    ${CMAKE_CURRENT_BINARY_DIR}
+    DEPENDS flang-rt-test-depends
+  )
+set_target_properties(check-flang-rt PROPERTIES FOLDER "Flang-RT/Meta")
+
+add_lit_testsuites(flang-rt ${CMAKE_CURRENT_SOURCE_DIR}
+    DEPENDS flang-rt-test-depends
+  )
diff --git a/flang-rt/test/Driver/ctofortran.f90 b/flang-rt/test/Driver/ctofortran.f90
index 10c7adaccc9588..e385e7974cdc18 100644
--- a/flang-rt/test/Driver/ctofortran.f90
+++ b/flang-rt/test/Driver/ctofortran.f90
@@ -1,8 +1,10 @@
 ! UNSUPPORTED: system-windows
-! REQUIRES: flang-rt
+! UNSUPPORTED: offload-cuda
+
 ! RUN: split-file %s %t
-! RUN: chmod +x %t/runtest.sh
-! RUN: %t/runtest.sh %t %t/ffile.f90 %t/cfile.c %flang | FileCheck %s
+! RUN: %clang -I"%include/flang" -c %t/cfile.c -o %t/cfile.o
+! RUN: %flang -L"%libdir" %t/ffile.f90 %t/cfile.o -o %t/ctofortran
+! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t/ctofortran | FileCheck %s
 
 !--- ffile.f90
 program fmain
@@ -66,24 +68,3 @@ end subroutine foo
   foo(desc);
   return;
 }
-!--- runtest.sh
-#!/bin/bash
-TMPDIR=$1
-FFILE=$2
-CFILE=$3
-FLANG=$4
-shift 4
-FLAGS="$*"
-BINDIR=`dirname $FLANG`
-LIBDIR=$BINDIR/../lib
-CCOMP=$BINDIR/clang
-if [ -x $CCOMP ]
-then
-  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIBDIR
-  $CCOMP $FLAGS -c $CFILE -o $TMPDIR/cfile.o
-  $FLANG $FLAGS $FFILE $TMPDIR/cfile.o -o $TMPDIR/ctofortran
-  $TMPDIR/ctofortran # should print "PASS"
-else
-  # No clang compiler, just pass by default
-  echo "PASS"
-fi
diff --git a/flang-rt/test/Driver/exec.f90 b/flang-rt/test/Driver/exec.f90
index 9ca91ee24011c9..5a81a1e4c3e450 100644
--- a/flang-rt/test/Driver/exec.f90
+++ b/flang-rt/test/Driver/exec.f90
@@ -1,10 +1,10 @@
-! UNSUPPORTED: system-windows
 ! REQUIRES: flang-rt
+! UNSUPPORTED: offload-cuda
+
 ! Verify that flang can correctly build executables.
 
-! RUN: %flang %s -o %t
-! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%llvmshlibdir" %t | FileCheck %s
-! RUN: rm -f %t
+! RUN: %flang -L"%libdir" %s -o %t
+! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t | FileCheck %s
 
 ! CHECK: Hello, World!
 program hello
diff --git a/flang-rt/test/NonGtestUnit/lit.cfg.py b/flang-rt/test/NonGtestUnit/lit.cfg.py
new file mode 100644
index 00000000000000..4bee709b78f43f
--- /dev/null
+++ b/flang-rt/test/NonGtestUnit/lit.cfg.py
@@ -0,0 +1,22 @@
+# -*- Python -*-
+
+import os
+
+import lit.formats
+
+# name: The name of this test suite.
+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"]
+
+# test_source_root: The root path where unit test binaries are located.
+config.test_source_root = os.path.join(config.flangrt_binary_dir, "unittests")
+
+# test_exec_root: The root path where tests should be run.
+# lit writes a '.lit_test_times.txt' file into this directory.
+config.test_exec_root = config.flang_rt_binary_test_dir
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.ExecutableTest()
diff --git a/flang-rt/test/NonGtestUnit/lit.site.cfg.py.in b/flang-rt/test/NonGtestUnit/lit.site.cfg.py.in
new file mode 100644
index 00000000000000..8244b5b62d3aaf
--- /dev/null
+++ b/flang-rt/test/NonGtestUnit/lit.site.cfg.py.in
@@ -0,0 +1,14 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+import os
+
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.flang_rt_source_dir = "@FLANG_RT_SOURCE_DIR@"
+config.flangrt_binary_dir = "@FLANG_RT_BINARY_DIR@"
+config.flang_rt_binary_test_dir = os.path.dirname(__file__)
+
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+
+# Let the main config do the real work.
+lit_config.load_config(config, os.path.join(config.flang_rt_source_dir, 'test', 'NonGtestUnit', 'lit.cfg.py'))
diff --git a/flang-rt/test/Runtime/no-cpp-dep.c b/flang-rt/test/Runtime/no-cpp-dep.c
index c03029f0f3c26d..2a416bdb27ee22 100644
--- a/flang-rt/test/Runtime/no-cpp-dep.c
+++ b/flang-rt/test/Runtime/no-cpp-dep.c
@@ -3,10 +3,11 @@ This test makes sure that flang's runtime does not depend on the C++ runtime
 library. It tries to link this simple file against libflang_rt.a with
 a C compiler.
 
-REQUIRES: c-compiler, flang-rt
+UNSUPPORTED: system-windows
+UNSUPPORTED: offload-cuda
 
 RUN: %if system-aix %{ export OBJECT_MODE=64 %}
-RUN: %cc -std=c99 %s -I%include %libruntime -lm  \
+RUN: %cc -std=c99 %s -I%include -L"%libdir" -lflang_rt -lm \
 RUN: %if system-aix %{-lpthread %}
 RUN: rm a.out
 */
diff --git a/flang-rt/test/Unit/lit.cfg.py b/flang-rt/test/Unit/lit.cfg.py
new file mode 100644
index 00000000000000..516bc653f413f4
--- /dev/null
+++ b/flang-rt/test/Unit/lit.cfg.py
@@ -0,0 +1,21 @@
+# -*- Python -*-
+
+import os
+
+import lit.formats
+
+# name: The name of this test suite.
+config.name = "flang-rt-Unit"
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = []
+
+# test_source_root: The root path where unit test binaries are located.
+config.test_source_root = os.path.join(config.flangrt_binary_dir, "unittests")
+
+# test_exec_root: The root path where tests should be run.
+# lit writes a '.lit_test_times.txt' file into this directory.
+config.test_exec_root = config.flang_rt_binary_test_dir
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, "Tests")
diff --git a/flang-rt/test/Unit/lit.site.cfg.py.in b/flang-rt/test/Unit/lit.site.cfg.py.in
new file mode 100644
index 00000000000000..ed6dea07bcdde1
--- /dev/null
+++ b/flang-rt/test/Unit/lit.site.cfg.py.in
@@ -0,0 +1,15 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+import os
+
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.llvm_build_mode = "@LLVM_BUILD_MODE@"
+config.flang_rt_source_dir = "@FLANG_RT_SOURCE_DIR@"
+config.flangrt_binary_dir = "@FLANG_RT_BINARY_DIR@"
+config.flang_rt_binary_test_dir = os.path.dirname(__file__)
+
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+
+# Let the main config do the real work.
+lit_config.load_config(config, os.path.join(config.flang_rt_source_dir, 'test', 'Unit', 'lit.cfg.py'))
diff --git a/flang-rt/test/lit.cfg.py b/flang-rt/test/lit.cfg.py
new file mode 100644
index 00000000000000..08f3f1121c8960
--- /dev/null
+++ b/flang-rt/test/lit.cfg.py
@@ -0,0 +1,102 @@
+# -*- Python -*-
+
+import shlex
+import lit.util
+
+from lit.llvm import llvm_config
+from lit.llvm.subst import ToolSubst, FindTool
+
+
+def shjoin(args, sep=" "):
+    return sep.join([shlex.quote(arg) for arg in args])
+
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = "flang-rt"
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = [
+    ".c",
+    ".cpp",
+    ".f",
+    ".F",
+    ".ff",
+    ".FOR",
+    ".for",
+    ".f77",
+    ".f90",
+    ".F90",
+    ".ff90",
+    ".f95",
+    ".F95",
+    ".ff95",
+    ".fpp",
+    ".FPP",
+    ".cuf",
+    ".CUF",
+    ".f18",
+    ".F18",
+    ".f03",
+    ".F03",
+    ".f08",
+    ".F08",
+    ".ll",
+    ".fir",
+    ".mlir",
+]
+
+llvm_config.use_default_substitutions()
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+# lit writes a '.lit_test_times.txt' file into this directory.
+config.test_exec_root = config.flang_rt_binary_test_dir
+
+# On MacOS, -isysroot is needed to build binaries.
+isysroot_flag = []
+if config.osx_sysroot:
+    isysroot_flag = ["-isysroot", config.osx_sysroot]
+
+tools = [
+    ToolSubst(
+        "%flang",
+        command=config.flang,
+        extra_args=isysroot_flag,
+        unresolved="fatal",
+    ),
+    ToolSubst(
+        "%clang",
+        command=FindTool("clang"),
+        extra_args=isysroot_flag,
+        unresolved="fatal",
+    ),
+    ToolSubst("%cc",
+        command=config.cc,
+        extra_args=isysroot_flag,
+        unresolved="fatal"
+    ),
+]
+llvm_config.add_tool_substitutions(tools)
+
+# Let tests find LLVM's standard tools (FileCheck, split-file, not, ...)
+llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True)
+
+# Include path for C headers that define Flang's Fortran ABI.
+config.substitutions.append(("%include", os.path.join(config.flang_source_dir, "include")))
+
+# Library path of libflang_rt.a (for lib search path when using non-Flang driver for linking)
+config.substitutions.append(("%libdir", config.flang_rt_output_resource_lib_dir))
+
+# 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")
diff --git a/flang-rt/test/lit.site.cfg.py.in b/flang-rt/test/lit.site.cfg.py.in
new file mode 100644
index 00000000000000..662d076b1fe24f
--- /dev/null
+++ b/flang-rt/test/lit.site.cfg.py.in
@@ -0,0 +1,19 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+import sys
+
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+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 = "@FLANG_RT_OUTPUT_RESOURCE_LIB_DIR@"
+config.flang_rt_experimental_offload_support = "@FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT@"
+config.cc = "@CMAKE_C_COMPILER@"
+config.flang = "@CMAKE_Fortran_COMPILER@"
+config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@")
+
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+
+# Let the main config do the real work.
+lit_config.load_config(config, os.path.join(config.flang_rt_source_dir, 'test', 'lit.cfg.py'))
diff --git a/flang-rt/unittests/CMakeLists.txt b/flang-rt/unittests/CMakeLists.txt
new file mode 100644
index 00000000000000..ca94805f1403bc
--- /dev/null
+++ b/flang-rt/unittests/CMakeLists.txt
@@ -0,0 +1,111 @@
+#===-- unittests/CMakeLists.txt --------------------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+# LLVM uses a modified version of GTest that uses LLVMSupport for console
+# output. Therefore it also needs to include files from LLVM. Unfortunately,
+# LLVM/GTest doesn't add the include search path itself. Limiting the scope
+# using target_include_directories does not work because with
+# LLVM_INSTALL_GTEST=ON, as llvm_gtest is an IMPORT library.
+include_directories("${LLVM_INCLUDE_DIR}" "${LLVM_MAIN_INCLUDE_DIR}")
+
+# Add GTest if not already present.
+# Using a function so LLVM_SUBPROJECT_TITLE does not propagate.
+function (build_gtest)
+  set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test")
+  add_subdirectory("${LLVM_THIRD_PARTY_DIR}/unittest" "${CMAKE_CURRENT_BINARY_DIR}/third-party/unittest")
+endfunction ()
+if (NOT TARGET llvm_gtest)
+  build_gtest()
+endif ()
+
+if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+  add_compile_options("-Wno-suggest-override")
+endif()
+
+
+# Target that depends on all unittests
+add_custom_target(FlangRTUnitTests)
+set_target_properties(FlangRTUnitTests PROPERTIES FOLDER "Flang-RT/Meta")
+
+
+function(add_flangrt_unittest_offload_properties target)
+  # Set CUDA_RESOLVE_DEVICE_SYMBOLS.
+  if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
+    set_target_properties(${target}
+      PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON
+      )
+  endif()
+  # Enable OpenMP offload during linking. We may need to replace
+  # LINK_OPTIONS with COMPILE_OPTIONS when there are OpenMP offload
+  # unittests.
+  #
+  # FIXME: replace 'native' in --offload-arch option with the list
+  #        of targets that Fortran Runtime was built for.
+  if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")
+    set_target_properties(${target}
+      PROPERTIES LINK_OPTIONS
+      "-fopenmp;--offload-arch=native"
+      )
+  endif()
+endfunction()
+
+
+function(add_flangrt_unittest test_dirname)
+  cmake_parse_arguments(ARG
+    ""
+    ""
+    "LINK_LIBS"
+    ${ARGN})
+
+  add_unittest(FlangRTUnitTests ${test_dirname} ${ARG_UNPARSED_ARGUMENTS})
+
+  target_include_directories(${test_dirname} PRIVATE "${FLANG_RT_SOURCE_DIR}/include")
+  target_include_directories(${test_dirname} PRIVATE "${FLANG_SOURCE_DIR}/include")
+  target_link_libraries(${test_dirname} PRIVATE ${ARG_LINK_LIBS})
+  add_flangrt_unittest_offload_properties(${test_dirname})
+
+  # Required because LLVMSupport is compiled with this option.
+  # FIXME: According to CMake documentation, this is the default. Why is it
+  #        needed? LLVM's add_unittest doesn't set it either.
+  set_target_properties(${test_dirname}
+      PROPERTIES
+        MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL"
+    )
+endfunction()
+
+function(add_flangrt_nongtest_unittest test_name)
+  cmake_parse_arguments(ARG
+    "SLOW_TEST"
+    ""
+    "LINK_LIBS"
+    ${ARGN})
+
+  if(ARG_SLOW_TEST)
+      set(suffix .slow)
+  else()
+      set(suffix .test)
+  endif()
+
+  add_executable(${test_name}${suffix} EXCLUDE_FROM_ALL ${ARG_UNPARSED_ARGUMENTS})
+  set_target_properties(${test_name}${suffix} PROPERTIES FOLDER "Flang-RT/Tests/Unit")
+
+  target_include_directories(${test_name}${suffix} PRIVATE
+      "${FLANG_RT_SOURCE_DIR}/include"
+      "${FLANG_SOURCE_DIR}/include"
+    )
+  target_link_libraries(${test_name}${suffix} PRIVATE NonGTestTesting ${ARG_LINK_LIBS})
+
+  if(NOT ARG_SLOW_TEST)
+    add_dependencies(FlangRTUnitTests ${test_name}${suffix})
+  endif()
+
+  add_flangrt_unittest_offload_properties(${test_name}${suffix})
+endfunction()
+
+add_subdirectory(Evaluate)
+add_subdirectory(Runtime)
diff --git a/flang-rt/unittests/Evaluate/CMakeLists.txt b/flang-rt/unittests/Evaluate/CMakeLists.txt
new file mode 100644
index 00000000000000..15b813bcb19da1
--- /dev/null
+++ b/flang-rt/unittests/Evaluate/CMakeLists.txt
@@ -0,0 +1,21 @@
+#===-- unittests/Evaluate/CMakeLists.txt -----------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+add_flangrt_nongtest_unittest(reshape
+  reshape.cpp
+
+  LINK_LIBS
+    flang_rt.unittest
+)
+
+add_flangrt_nongtest_unittest(ISO-Fortran-binding
+  ISO-Fortran-binding.cpp
+
+  LINK_LIBS
+    flang_rt.unittest
+)
diff --git a/flang-rt/unittests/Runtime/CMakeLists.txt b/flang-rt/unittests/Runtime/CMakeLists.txt
new file mode 100644
index 00000000000000..32f12b14caca7a
--- /dev/null
+++ b/flang-rt/unittests/Runtime/CMakeLists.txt
@@ -0,0 +1,48 @@
+#===-- unittests/Runtime/CMakeLists.txt ------------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+add_flangrt_unittest(RuntimeTests
+  AccessTest.cpp
+  Allocatable.cpp
+  ArrayConstructor.cpp
+  BufferTest.cpp
+  CharacterTest.cpp
+  CommandTest.cpp
+  Complex.cpp
+  CrashHandlerFixture.cpp
+  Derived.cpp
+  ExternalIOTest.cpp
+  Format.cpp
+  Inquiry.cpp
+  ListInputTest.cpp
+  LogicalFormatTest.cpp
+  Matmul.cpp
+  MatmulTranspose.cpp
+  MiscIntrinsic.cpp
+  Namelist.cpp
+  Numeric.cpp
+  NumericalFormatTest.cpp
+  Pointer.cpp
+  Ragged.cpp
+  Random.cpp
+  Reduction.cpp
+  RuntimeCrashTest.cpp
+  Stop.cpp
+  Support.cpp
+  Time.cpp
+  TemporaryStack.cpp
+  Transformational.cpp
+
+  LINK_LIBS
+    flang_rt.unittest
+)
+target_compile_definitions(RuntimeTests PRIVATE NOT_EXE="${LLVM_TOOLS_DIR}/not${CMAKE_EXECUTABLE_SUFFIX}")
+
+if (FLANG_RT_ENABLE_CUF)
+  add_subdirectory(CUDA)
+endif ()
diff --git a/flang-rt/unittests/Runtime/CUDA/CMakeLists.txt b/flang-rt/unittests/Runtime/CUDA/CMakeLists.txt
new file mode 100644
index 00000000000000..37b117234208c4
--- /dev/null
+++ b/flang-rt/unittests/Runtime/CUDA/CMakeLists.txt
@@ -0,0 +1,18 @@
+#===-- unittests/Runtime/CUDA/CMakeLists.txt -------------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+
+add_flangrt_unittest(FlangCufRuntimeTests
+  Allocatable.cpp
+  AllocatorCUF.cpp
+  Memory.cpp
+)
+
+target_link_libraries(FlangCufRuntimeTests
+  PRIVATE
+  CufRuntime
+)
diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt
index 0044779da011d7..38004c149b7835 100644
--- a/flang/CMakeLists.txt
+++ b/flang/CMakeLists.txt
@@ -35,17 +35,6 @@ endif()
 
 option(FLANG_ENABLE_WERROR "Fail and stop building flang if a warning is triggered." OFF)
 
-# The out of tree builds of the compiler and the Fortran runtime
-# must use the same setting of FLANG_RUNTIME_F128_MATH_LIB
-# to be composable. Failure to synchronize this setting may result
-# in linking errors or fatal failures in F128 runtime functions.
-set(FLANG_RUNTIME_F128_MATH_LIB "" CACHE STRING
-  "Specifies the target library used for implementing IEEE-754 128-bit float \
-  math in F18 runtime, e.g. it might be libquadmath for targets where \
-  REAL(16) is mapped to __float128, or libm for targets where REAL(16) \
-  is mapped to long double, etc."
-  )
-
 # Check for a standalone build and configure as appropriate from
 # there.
 if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
@@ -248,7 +237,25 @@ else()
   include_directories(SYSTEM ${MLIR_TABLEGEN_OUTPUT_DIR})
 endif()
 
-option(FLANG_INCLUDE_RUNTIME "Build the runtime in-tree (deprecated; to be replaced with LLVM_ENABLE_RUNTIMES=flang-rt)" ON)
+set(FLANG_INCLUDE_RUNTIME_default ON)
+if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
+  set(FLANG_INCLUDE_RUNTIME_default OFF)
+endif ()
+option(FLANG_INCLUDE_RUNTIME "Build the runtime in-tree (deprecated; to be replaced with LLVM_ENABLE_RUNTIMES=flang-rt)" FLANG_INCLUDE_RUNTIME_default)
+if (FLANG_INCLUDE_RUNTIME)
+  if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
+    message(WARNING "Building Flang-RT using LLVM_ENABLE_RUNTIMES. FLANG_INCLUDE_RUNTIME=${FLANG_INCLUDE_RUNTIME} ignored.")
+    set(FLANG_INCLUDE_RUNTIME OFF)
+  else ()
+     message(STATUS "Building flang_rt in-tree")
+  endif ()
+else ()
+  if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
+    message(STATUS "Building Flang-RT using LLVM_ENABLE_RUNTIMES.")
+  else ()
+    message(STATUS "Not building Flang-RT. For a usable Fortran toolchain, compile a standalone Flang-RT")
+  endif ()
+endif ()
 
 set(FLANG_TOOLS_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH
     "Path for binary subdirectory (defaults to '${CMAKE_INSTALL_BINDIR}')")
@@ -358,20 +365,6 @@ if (FLANG_REPOSITORY_STRING)
   add_definitions(-DFLANG_REPOSITORY_STRING="${FLANG_REPOSITORY_STRING}")
 endif()
 
-if (FLANG_RUNTIME_F128_MATH_LIB)
-  add_compile_definitions(
-    FLANG_RUNTIME_F128_MATH_LIB="${FLANG_RUNTIME_F128_MATH_LIB}"
-    )
-endif()
-
-include(TestBigEndian)
-test_big_endian(IS_BIGENDIAN)
-if (IS_BIGENDIAN)
-  add_compile_definitions(FLANG_BIG_ENDIAN=1)
-else ()
-  add_compile_definitions(FLANG_LITTLE_ENDIAN=1)
-endif ()
-
 # Configure Flang's Version.inc file.
 configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/include/flang/Version.inc.in
@@ -469,6 +462,7 @@ if (APPLE)
 endif()
 
 include(AddFlang)
+include(FlangCommon)
 
 if (FLANG_INCLUDE_TESTS)
   add_compile_definitions(FLANG_INCLUDE_TESTS=1)
@@ -562,7 +556,12 @@ include(GetClangResourceDir)
 get_clang_resource_dir(HEADER_BINARY_DIR PREFIX ${LLVM_LIBRARY_OUTPUT_INTDIR}/.. SUBDIR include)
 configure_file(
   ${FLANG_SOURCE_DIR}/include/flang/ISO_Fortran_binding.h
-  ${HEADER_BINARY_DIR}/ISO_Fortran_binding.h)
+  ${HEADER_BINARY_DIR}/ISO_Fortran_binding.h COPYONLY)
+
+# llvm-test-suite fails if it does not find the the file in this location.
+configure_file(
+  ${FLANG_SOURCE_DIR}/include/flang/ISO_Fortran_binding.h
+  ${LLVM_RUNTIME_OUTPUT_INTDIR}/../include/flang COPYONLY)
 
 # And also install it into the install area
 get_clang_resource_dir(HEADER_INSTALL_DIR SUBDIR include)
diff --git a/flang/cmake/modules/FlangCommon.cmake b/flang/cmake/modules/FlangCommon.cmake
new file mode 100644
index 00000000000000..1b8606843b2240
--- /dev/null
+++ b/flang/cmake/modules/FlangCommon.cmake
@@ -0,0 +1,43 @@
+#===-- cmake/modules/FlangCommon.txt ----------------------------===#
+#
+# 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
+#
+#===------------------------------------------------------------------------===#
+#
+# CMake definitions shared between Flang and Flang-RT
+#
+#===------------------------------------------------------------------------===#
+
+# The out of tree builds of the compiler and the Fortran runtime
+# must use the same setting of FLANG_RUNTIME_F128_MATH_LIB
+# to be composable. Failure to synchronize this setting may result
+# in linking errors or fatal failures in F128 runtime functions.
+set(FLANG_RUNTIME_F128_MATH_LIB "" CACHE STRING
+  "Specifies the target library used for implementing IEEE-754 128-bit float \
+  math in F18 runtime, e.g. it might be libquadmath for targets where \
+  REAL(16) is mapped to __float128, or libm for targets where REAL(16) \
+  is mapped to long double, etc."
+  )
+if (FLANG_RUNTIME_F128_MATH_LIB)
+  add_compile_definitions(FLANG_RUNTIME_F128_MATH_LIB="${FLANG_RUNTIME_F128_MATH_LIB}")
+endif()
+
+# 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)
+
+include(TestBigEndian)
+test_big_endian(IS_BIGENDIAN)
+if (IS_BIGENDIAN)
+  add_compile_definitions(FLANG_BIG_ENDIAN=1)
+else ()
+  add_compile_definitions(FLANG_LITTLE_ENDIAN=1)
+endif ()
diff --git a/flang/docs/GettingStarted.md b/flang/docs/GettingStarted.md
index ffde50b6f481e8..47ba268b3e7636 100644
--- a/flang/docs/GettingStarted.md
+++ b/flang/docs/GettingStarted.md
@@ -30,7 +30,7 @@ https://llvm.org/docs/GettingStarted.html.
 All of the examples below use GCC as the C/C++ compilers and ninja as the build
 tool.
 
-### Building flang in tree
+### Building flang in tree with bootstrapped Flang-RT
 Building flang in tree means building flang along with all of the projects on
 which it depends.  These projects include mlir, clang, flang, openmp, and
 compiler-rt.  Note that compiler-rt is only needed to access libraries that
@@ -82,7 +82,7 @@ cmake \
   -DLLVM_TARGETS_TO_BUILD=host \
   -DLLVM_LIT_ARGS=-v \
   -DLLVM_ENABLE_PROJECTS="clang;mlir;flang;openmp" \
-  -DLLVM_ENABLE_RUNTIMES="compiler-rt" \
+  -DLLVM_ENABLE_RUNTIMES="compiler-rt;flang_rt" \
   ../llvm-project/llvm
 
 ninja
@@ -101,7 +101,7 @@ the cmake command above:
 To run the flang tests on this build, execute the command in the "build"
 directory:
 ```bash
-ninja check-flang
+ninja check-flang check-flang-rt
 ```
 
 To create the installed files:
@@ -111,34 +111,6 @@ ninja install
 echo "latest" > $INSTALLDIR/bin/versionrc
 ```
 
-To build compiler-rt:
-```bash
-cd $ROOTDIR
-rm -rf compiler-rt
-mkdir compiler-rt
-cd compiler-rt
-CC=$INSTALLDIR/bin/clang \
-CXX=$INSTALLDIR/bin/clang++ \
-cmake \
-  -G Ninja \
-  ../llvm-project/compiler-rt \
-  -DCMAKE_BUILD_TYPE=Release \
-  -DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
-  -DCMAKE_CXX_STANDARD=11 \
-  -DCMAKE_C_CFLAGS=-mlong-double-128 \
-  -DCMAKE_CXX_CFLAGS=-mlong-double-128 \
-  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-  -DCOMPILER_RT_BUILD_ORC=OFF \
-  -DCOMPILER_RT_BUILD_XRAY=OFF \
-  -DCOMPILER_RT_BUILD_MEMPROF=OFF \
-  -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
-  -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
-  -DLLVM_CONFIG_PATH=$INSTALLDIR/bin/llvm-config
-
-ninja
-ninja install
-```
-
 Note that these instructions specify flang as one of the projects to build in
 the in tree build.  This is not strictly necessary for subsequent standalone
 builds, but doing so lets you run the flang tests to verify that the source
@@ -192,31 +164,57 @@ directory:
 ninja check-flang
 ```
 
-### Building flang runtime for accelerators
+To build Flang-RT (required for linking executables):
+```bash
+cd $ROOTDIR
+rm -rf flang-rt
+mkdir flang-rt
+cd flang-rt
+CC=$INSTALLDIR/bin/clang \
+CXX=$INSTALLDIR/bin/clang++ \
+cmake \
+  -G Ninja \
+  ../llvm-project/runtimes \
+  -DCMAKE_BUILD_TYPE=Release \
+  -DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
+  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
+  -DLLVM_ENABLE_RUNTIMES=flang-rt \
+  -DLLVM_BINARY_DIR=$ROOTDIR/build \
+  -DLLVM_Fortran_COMPILER=$INSTALLDIR/bin/flang \
+  -DLLVM_Fortran_COMPILER_WORKS=ON
+
+ninja
+ninja check-flang-rt
+ninja install
+```
+
+
+### Building Flang-RT for accelerators
 Flang runtime can be built for accelerators in experimental mode, i.e.
 complete enabling is WIP.  CUDA and OpenMP target offload builds
 are currently supported.
 
-#### Building out-of-tree
+#### Bootstrapping Build of Flang-RT
 
 ##### CUDA build
 Clang with NVPTX backend and NVCC compilers are supported.
 
 ```bash
-cd llvm-project/flang
+cd llvm-project
 rm -rf build_flang_runtime
 mkdir build_flang_runtime
 cd build_flang_runtime
 
 cmake \
-  -DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \
+  -DLLVM_ENABLE_RUNTIMES=flang-rt \
+  -DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA \
   -DCMAKE_CUDA_ARCHITECTURES=80 \
   -DCMAKE_C_COMPILER=clang \
   -DCMAKE_CXX_COMPILER=clang++ \
   -DCMAKE_CUDA_COMPILER=clang \
   -DCMAKE_CUDA_HOST_COMPILER=clang++ \
-  ../runtime/
-make -j flang-rt
+  ../runtimes/
+make flang-rt
 ```
 
 Note that the used version of `clang` must [support](https://releases.llvm.org/16.0.0/tools/clang/docs/ReleaseNotes.html#cuda-support)
@@ -225,21 +223,22 @@ CUDA toolkit installations, please use `-DCUDAToolkit_ROOT=/some/path`
 to specify the compatible version.
 
 ```bash
-cd llvm-project/flang
+cd llvm-project
 rm -rf build_flang_runtime
 mkdir build_flang_runtime
 cd build_flang_runtime
 
 cmake \
-  -DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \
+  -DLLVM_ENABLE_RUNTIMES=flang-rt \
+  -DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA \
   -DCMAKE_CUDA_ARCHITECTURES=80 \
   -DCMAKE_C_COMPILER=clang \
   -DCMAKE_CXX_COMPILER=clang++ \
   -DCMAKE_CUDA_COMPILER=nvcc \
   -DCMAKE_CUDA_HOST_COMPILER=clang++ \
-  ../runtime/
+  ../runtimes/
 
-make -j flang-rt
+make flang-rt
 ```
 
 Note that `nvcc` might limit support to certain
@@ -251,50 +250,59 @@ code.  Note that the packaging of the libraries is different
 between [Clang](https://clang.llvm.org/docs/OffloadingDesign.html#linking-target-device-code) and NVCC, so the library must be linked using
 compatible compiler drivers.
 
-#### Building in-tree
+#### Building in-tree (bootstrap build)
 One may build Flang runtime library along with building Flang itself
 by providing these additional CMake variables on top of the Flang in-tree
 build config:
 
 For example:
 ```bash
-  -DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \
+  -DLLVM_ENABLE_RUNTIMES=flang-rt \
+  -DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA \
   -DCMAKE_CUDA_ARCHITECTURES=80 \
   -DCMAKE_C_COMPILER=clang \
   -DCMAKE_CXX_COMPILER=clang++ \
   -DCMAKE_CUDA_COMPILER=clang \
   -DCMAKE_CUDA_HOST_COMPILER=clang++ \
+  ../llvm
 ```
 
 Or:
 ```bash
-  -DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \
+  -DLLVM_ENABLE_RUNTIMES=flang-rt \
+  -DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA \
   -DCMAKE_CUDA_ARCHITECTURES=80 \
   -DCMAKE_C_COMPILER=gcc \
   -DCMAKE_CXX_COMPILER=g++ \
   -DCMAKE_CUDA_COMPILER=nvcc \
   -DCMAKE_CUDA_HOST_COMPILER=g++ \
+  ../llvm
 ```
 
-Normal `make -j check-flang` will work with such CMake configuration.
+Normal `make check-flang` will work with such CMake configuration.
+Consider building in parallel using the `-j<jobs>` flag, where `<jobs>` is a
+number low enough for all build jobs to fit into the available RAM. Using
+the number of harware threads (`nprocs`) is likely too much for most
+commodity computers.
 
 ##### OpenMP target offload build
 Only Clang compiler is currently supported.
 
 ```bash
-cd llvm-project/flang
+cd llvm-project
 rm -rf build_flang_runtime
 mkdir build_flang_runtime
 cd build_flang_runtime
 
 cmake \
-  -DFLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD="host_device" \
+  -DLLVM_ENABLE_RUNTIMES=flang-rt \
+  -DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT="OpenMP" \
   -DCMAKE_C_COMPILER=clang \
   -DCMAKE_CXX_COMPILER=clang++ \
-  -DFLANG_OMP_DEVICE_ARCHITECTURES="all" \
-  ../runtime/
+  -DFLANG_RT_DEVICE_ARCHITECTURES=all \
+  ../runtimes/
 
-make -j flang-rt
+make flang-rt
 ```
 
 The result of the build is a "device-only" library, i.e. the host
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index a163b4f4ed67de..2633b27f0093c6 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -36,7 +36,13 @@ page](https://llvm.org/releases/).
 
 ## Build System Changes
 
- * FortranRuntime has been renamed to `flang_rt`.
+ * The Fortran Runtime library has been move to a new top-level directory
+   named "flang-rt". The library was also renamed from `FortranRuntime` to
+   `flang_rt`. It now supports the
+   LLVM_ENABLE_RUNTIMES mechanism to build flang-rt for multiple target
+   triples. libflang_rt.a will now be emitted into Clang's per-target
+   resource directory (next to libclang_rt.*.*) where it is also found by
+   Flang's driver.
 
 ## New Issues Found
 
diff --git a/flang/module/iso_fortran_env_impl.f90 b/flang/module/iso_fortran_env_impl.f90
index 5408e7de370011..3ee00acfde4d7c 100644
--- a/flang/module/iso_fortran_env_impl.f90
+++ b/flang/module/iso_fortran_env_impl.f90
@@ -8,7 +8,7 @@
 
 ! This MODULE implements part of the ISO_FORTRAN_ENV module file, which
 ! partially requires linkable symbols for some entities defined
-! (e.g., real_kinds).
+! (e.g., real_kinds). This file is also used by Flang-RT.
 
 module iso_fortran_env_impl
   implicit none
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index 08ba586e1226d3..0ba80f9a03f2ec 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -166,26 +166,6 @@
 if config.flang_include_runtime:
     config.available_features.add("flang-rt")
 
-# Define some variables to help us test that the flang runtime doesn't depend on
-# the C++ runtime libraries. For this we need a C compiler. If for some reason
-# we don't have one, we can just disable the test.
-if config.flang_include_runtime and config.cc:
-    libruntime = os.path.join(config.flang_lib_dir, "libflang_rt.a")
-    include = os.path.join(config.flang_src_dir, "include")
-
-    if (
-        os.path.isfile(libruntime)
-        and os.path.isdir(include)
-    ):
-        config.available_features.add("c-compiler")
-        tools.append(
-            ToolSubst(
-                "%cc", command=config.cc, extra_args=isysroot_flag, unresolved="fatal"
-            )
-        )
-        tools.append(ToolSubst("%libruntime", command=libruntime, unresolved="fatal"))
-        tools.append(ToolSubst("%include", command=include, unresolved="fatal"))
-
 # Add all the tools and their substitutions (if applicable). Use the search paths provided for
 # finding the tools.
 if config.flang_standalone_build:
diff --git a/flang/test/lit.site.cfg.py.in b/flang/test/lit.site.cfg.py.in
index 697ba3fa797633..5b66e592bcfeec 100644
--- a/flang/test/lit.site.cfg.py.in
+++ b/flang/test/lit.site.cfg.py.in
@@ -11,18 +11,15 @@ config.llvm_target_triple_env = "@LLVM_TARGET_TRIPLE_ENV@"
 config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
 config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@"
 config.flang_obj_root = "@FLANG_BINARY_DIR@"
-config.flang_src_dir = "@FLANG_SOURCE_DIR@"
 config.flang_tools_dir = lit_config.substitute("@FLANG_TOOLS_DIR@")
 config.flang_intrinsic_modules_dir = "@FLANG_INTRINSIC_MODULES_DIR@"
 config.flang_llvm_tools_dir = "@CMAKE_BINARY_DIR@/bin"
-config.flang_lib_dir = "@CMAKE_BINARY_DIR@/lib"
 config.flang_test_triple = "@FLANG_TEST_TARGET_TRIPLE@"
 config.flang_examples = @LLVM_BUILD_EXAMPLES@
 config.python_executable = "@PYTHON_EXECUTABLE@"
 config.flang_standalone_build = @FLANG_STANDALONE_BUILD@
 config.has_plugins = @LLVM_ENABLE_PLUGINS@
 config.linked_bye_extension = @LLVM_BYE_LINK_INTO_TOOLS@
-config.cc = "@CMAKE_C_COMPILER@"
 config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@")
 config.targets_to_build = "@TARGETS_TO_BUILD@"
 config.default_sysroot = "@DEFAULT_SYSROOT@"
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index f14065ab037990..9a1dc824658fd5 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -157,12 +157,18 @@ if ("libc" IN_LIST LLVM_ENABLE_PROJECTS)
     "https://libc.llvm.org/ for building the runtimes.")
 endif()
 
+if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
+  if (NOT "flang" IN_LIST LLVM_ENABLE_PROJECTS)
+    message(FATAL_ERROR "Flang is not enabled, but is required for the Flang-RT runtime")
+  endif ()
+endif ()
+
 # Select the runtimes to build
 #
 # As we migrate runtimes to using the bootstrapping build, the set of default runtimes
 # should grow as we remove those runtimes from LLVM_ENABLE_PROJECTS above.
 set(LLVM_DEFAULT_RUNTIMES "libcxx;libcxxabi;libunwind")
-set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc;offload")
+set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc;offload;flang-rt")
 set(LLVM_ENABLE_RUNTIMES "" CACHE STRING
   "Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.")
 if(LLVM_ENABLE_RUNTIMES STREQUAL "all")
diff --git a/llvm/cmake/modules/LLVMExternalProjectUtils.cmake b/llvm/cmake/modules/LLVMExternalProjectUtils.cmake
index 55422c2a4c023d..caccb62d666ced 100644
--- a/llvm/cmake/modules/LLVMExternalProjectUtils.cmake
+++ b/llvm/cmake/modules/LLVMExternalProjectUtils.cmake
@@ -38,6 +38,8 @@ endfunction()
 
 
 # llvm_ExternalProject_Add(name source_dir ...
+#   ENABLE_FORTRAN
+#     External project requires the Flang compiler
 #   USE_TOOLCHAIN
 #     Use just-built tools (see TOOLCHAIN_TOOLS)
 #   EXCLUDE_FROM_ALL
@@ -65,7 +67,7 @@ endfunction()
 #   )
 function(llvm_ExternalProject_Add name source_dir)
   cmake_parse_arguments(ARG
-    "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
+    "ENABLE_FORTRAN;USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
     "SOURCE_DIR;FOLDER"
     "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES;STRIP_TOOL;TARGET_TRIPLE"
     ${ARGN})
@@ -93,6 +95,9 @@ function(llvm_ExternalProject_Add name source_dir)
 
   if(NOT ARG_TOOLCHAIN_TOOLS)
     set(ARG_TOOLCHAIN_TOOLS clang)
+    if (ARG_ENABLE_FORTRAN)
+      list(APPEND ARG_TOOLCHAIN_TOOLS flang)
+    endif ()
     # AIX 64-bit XCOFF and big AR format is not yet supported in some of these tools.
     if(NOT _cmake_system_name STREQUAL AIX)
       list(APPEND ARG_TOOLCHAIN_TOOLS lld llvm-ar llvm-ranlib llvm-nm llvm-objdump)
@@ -143,6 +148,10 @@ function(llvm_ExternalProject_Add name source_dir)
     set(CLANG_IN_TOOLCHAIN On)
   endif()
 
+  if(flang IN_LIST TOOLCHAIN_TOOLS)
+    set(FLANG_IN_TOOLCHAIN On)
+  endif()
+
   if(RUNTIME_LIBRARIES AND CLANG_IN_TOOLCHAIN)
     list(APPEND TOOLCHAIN_BINS ${RUNTIME_LIBRARIES})
   endif()
@@ -225,6 +234,9 @@ function(llvm_ExternalProject_Add name source_dir)
                           -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX})
       endif()
     endif()
+    if(FLANG_IN_TOOLCHAIN)
+      list(APPEND compiler_args -DCMAKE_Fortran_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/flang${CMAKE_EXECUTABLE_SUFFIX})
+    endif()
     if(lld IN_LIST TOOLCHAIN_TOOLS)
       if(is_msvc_target)
         list(APPEND compiler_args -DCMAKE_LINKER=${LLVM_RUNTIME_OUTPUT_INTDIR}/lld-link${CMAKE_EXECUTABLE_SUFFIX})
@@ -308,6 +320,7 @@ function(llvm_ExternalProject_Add name source_dir)
     set(compiler_args -DCMAKE_ASM_COMPILER=${CMAKE_ASM_COMPILER}
                       -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
                       -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
+                      -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER}
                       -DCMAKE_LINKER=${CMAKE_LINKER}
                       -DCMAKE_AR=${CMAKE_AR}
                       -DCMAKE_RANLIB=${CMAKE_RANLIB}
@@ -357,6 +370,7 @@ function(llvm_ExternalProject_Add name source_dir)
   if(ARG_TARGET_TRIPLE)
     list(APPEND compiler_args -DCMAKE_C_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
     list(APPEND compiler_args -DCMAKE_CXX_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
+    list(APPEND compiler_args -DCMAKE_Fortran_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
     list(APPEND compiler_args -DCMAKE_ASM_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
   endif()
 
diff --git a/llvm/projects/CMakeLists.txt b/llvm/projects/CMakeLists.txt
index 08f2fa522420b0..f254cf10806d75 100644
--- a/llvm/projects/CMakeLists.txt
+++ b/llvm/projects/CMakeLists.txt
@@ -11,7 +11,8 @@ foreach(entry ${entries})
        (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libunwind) AND
        (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/test-suite) AND
        (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/openmp) AND
-       (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/cross-project-tests))
+       (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/cross-project-tests) AND
+       (NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/flang-rt))
       get_filename_component(entry_name "${entry}" NAME)
       add_llvm_external_project(${entry_name})
     endif()
@@ -37,6 +38,7 @@ if(${LLVM_BUILD_RUNTIME})
   if(NOT LLVM_BUILD_EXTERNAL_COMPILER_RT)
     add_llvm_external_project(compiler-rt)
   endif()
+  add_llvm_external_project(flang-rt)
 endif()
 
 add_llvm_external_project(dragonegg)
diff --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt
index 70e85c123e4127..2370b41fb7f0ba 100644
--- a/llvm/runtimes/CMakeLists.txt
+++ b/llvm/runtimes/CMakeLists.txt
@@ -230,7 +230,7 @@ foreach(entry ${runtimes})
 endforeach()
 
 function(runtime_default_target)
-  cmake_parse_arguments(ARG "" "" "DEPENDS;CMAKE_ARGS;PREFIXES" ${ARGN})
+  cmake_parse_arguments(ARG "" "" "DEPENDS;CMAKE_ARGS;PREFIXES;EXTRA_ARGS" ${ARGN})
 
   include(${LLVM_BINARY_DIR}/runtimes/Components.cmake OPTIONAL)
   set(SUB_CHECK_TARGETS ${SUB_CHECK_TARGETS} PARENT_SCOPE)
@@ -270,14 +270,16 @@ function(runtime_default_target)
                                       -DLLVM_BUILD_TOOLS=${LLVM_BUILD_TOOLS}
                                       -DCMAKE_C_COMPILER_WORKS=ON
                                       -DCMAKE_CXX_COMPILER_WORKS=ON
+                                      -DCMAKE_Fortran_COMPILER_WORKS=ON
                                       -DCMAKE_ASM_COMPILER_WORKS=ON
                                       ${COMMON_CMAKE_ARGS}
                                       ${RUNTIMES_CMAKE_ARGS}
                                       ${ARG_CMAKE_ARGS}
                            PASSTHROUGH_PREFIXES LLVM_ENABLE_RUNTIMES
                                                 LLVM_USE_LINKER
-                                                CUDA # For runtimes that may look for the CUDA SDK (libc, offload)
+                                                CUDA CMAKE_CUDA # For runtimes that may look for the CUDA compiler and/or SDK (libc, offload, flang-rt)
                                                 FFI # offload uses libffi
+                                                FLANG_RUNTIME # Shared between Flang and Flang-RT
                                                 ${ARG_PREFIXES}
                            EXTRA_TARGETS ${extra_targets}
                                          ${test_targets}
@@ -287,7 +289,7 @@ function(runtime_default_target)
                            USE_TOOLCHAIN
                            TARGET_TRIPLE ${LLVM_TARGET_TRIPLE}
                            FOLDER "Runtimes"
-                           ${EXTRA_ARGS})
+                           ${EXTRA_ARGS} ${ARG_EXTRA_ARGS})
 endfunction()
 
 # runtime_register_target(name)
@@ -404,6 +406,7 @@ function(runtime_register_target name)
                                       -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=${LLVM_ENABLE_PER_TARGET_RUNTIME_DIR}
                                       -DCMAKE_C_COMPILER_WORKS=ON
                                       -DCMAKE_CXX_COMPILER_WORKS=ON
+                                      -DCMAKE_Fortran_COMPILER_WORKS=ON
                                       -DCMAKE_ASM_COMPILER_WORKS=ON
                                       -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON
                                       -DLLVM_RUNTIMES_TARGET=${name}
@@ -463,10 +466,13 @@ if(build_runtimes)
   # together in a single CMake invocation.
   set(extra_deps "")
   set(extra_cmake_args "")
+  set(extra_args "")
 
   if(LLVM_INCLUDE_TESTS)
     foreach(dep FileCheck
                 clang
+                clang-offload-packager
+                flang
                 count
                 lld
                 lli
@@ -549,19 +555,24 @@ 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)
+  endif ()
 
   if(NOT LLVM_RUNTIME_TARGETS)
     runtime_default_target(
       DEPENDS ${builtins_dep} ${extra_deps}
       CMAKE_ARGS ${extra_cmake_args}
-      PREFIXES ${prefixes})
+      PREFIXES ${prefixes}
+      EXTRA_ARGS ${extra_args})
     set(test_targets check-runtimes)
   else()
     if("default" IN_LIST LLVM_RUNTIME_TARGETS)
       runtime_default_target(
         DEPENDS ${builtins_dep} ${extra_deps}
         CMAKE_ARGS ${extra_cmake_args}
-        PREFIXES ${prefixes})
+        PREFIXES ${prefixes}
+        EXTRA_ARGS ${extra_args})
       list(REMOVE_ITEM LLVM_RUNTIME_TARGETS "default")
     else()
       add_custom_target(runtimes)
@@ -608,7 +619,7 @@ if(build_runtimes)
       runtime_register_target(${name}
         DEPENDS ${builtins_dep_name} ${extra_deps}
         CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=${name} ${extra_cmake_args}
-        EXTRA_ARGS TARGET_TRIPLE ${name})
+        EXTRA_ARGS TARGET_TRIPLE ${name} ${extra_args})
     endforeach()
 
     foreach(multilib ${LLVM_RUNTIME_MULTILIBS})
@@ -620,7 +631,7 @@ if(build_runtimes)
                      -DLLVM_RUNTIMES_LIBDIR_SUBDIR=${multilib}
                      ${extra_cmake_args}
           BASE_NAME ${name}
-          EXTRA_ARGS TARGET_TRIPLE ${name})
+          EXTRA_ARGS TARGET_TRIPLE ${name} ${extra_args})
       endforeach()
     endforeach()
   endif()
diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt
index 4a6b317a03f660..7f1e2ae065d6c7 100644
--- a/runtimes/CMakeLists.txt
+++ b/runtimes/CMakeLists.txt
@@ -36,7 +36,7 @@ list(INSERT CMAKE_MODULE_PATH 0
 # We order libraries to mirror roughly how they are layered, except that compiler-rt can depend
 # on libc++, so we put it after.
 set(LLVM_DEFAULT_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;offload")
-set(LLVM_SUPPORTED_RUNTIMES "${LLVM_DEFAULT_RUNTIMES};llvm-libgcc")
+set(LLVM_SUPPORTED_RUNTIMES "${LLVM_DEFAULT_RUNTIMES};llvm-libgcc;flang-rt")
 set(LLVM_ENABLE_RUNTIMES "" CACHE STRING
   "Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.")
 if(LLVM_ENABLE_RUNTIMES STREQUAL "all" )



More information about the llvm-branch-commits mailing list