Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -40,47 +40,20 @@
   endif()
 endif()
 
-# Top level target used to build all compiler-rt libraries.
-add_custom_target(compiler-rt ALL)
+# Add path for custom compiler-rt modules.
+list(INSERT CMAKE_MODULE_PATH 0
+  "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
+  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
+  )
+
+include(base-config-ix)
 
 option(COMPILER_RT_BUILD_BUILTINS "Build builtins" ON)
 mark_as_advanced(COMPILER_RT_BUILD_BUILTINS)
 option(COMPILER_RT_BUILD_SANITIZERS "Build sanitizers" ON)
 mark_as_advanced(COMPILER_RT_BUILD_SANITIZERS)
 
-if (NOT COMPILER_RT_STANDALONE_BUILD)
-  # Compute the Clang version from the LLVM version.
-  # FIXME: We should be able to reuse CLANG_VERSION variable calculated
-  #        in Clang cmake files, instead of copying the rules here.
-  string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
-         ${PACKAGE_VERSION})
-  # Setup the paths where compiler-rt runtimes and headers should be stored.
-  set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION})
-  set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
-  set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION})
-  option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests."
-         ${LLVM_INCLUDE_TESTS})
- option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered"
-        ${LLVM_ENABLE_WERROR})
-  # Use just-built Clang to compile/link tests on all platforms, except for
-  # Windows where we need to use clang-cl instead.
-  if(NOT MSVC)
-    set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
-  else()
-    set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe)
-  endif()
-else()
-  # Take output dir and install path from the user.
-  set(COMPILER_RT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH
-    "Path where built compiler-rt libraries should be stored.")
-  set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH
-    "Path where built compiler-rt executables should be stored.")
-  set(COMPILER_RT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} CACHE PATH
-    "Path where built compiler-rt libraries should be installed.")
-  option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests." OFF)
-  option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" OFF)
-  # Use a host compiler to compile/link tests.
-  set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "Compiler to use for testing")
+if (COMPILER_RT_STANDALONE_BUILD)
 
   if (NOT LLVM_CONFIG_PATH)
     find_program(LLVM_CONFIG_PATH "llvm-config"
@@ -129,14 +102,6 @@
   set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
 endif()
 
-if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$")
-  set(COMPILER_RT_TEST_COMPILER_ID Clang)
-elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang.*.exe$")
-  set(COMPILER_RT_TEST_COMPILER_ID Clang)
-else()
-  set(COMPILER_RT_TEST_COMPILER_ID GNU)
-endif()
-
 set(COMPILER_RT_DEFAULT_TARGET_TRIPLE ${TARGET_TRIPLE} CACHE STRING
     "Default triple for which compiler-rt runtimes will be built.")
 if(DEFINED COMPILER_RT_TEST_TARGET_TRIPLE)
@@ -156,23 +121,6 @@
 else()
   set(COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE FALSE)
 endif()
-
-if ("${COMPILER_RT_DEFAULT_TARGET_ABI}" STREQUAL "androideabi")
-  set(ANDROID 1)
-endif()
-
-string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR)
-set(COMPILER_RT_LIBRARY_OUTPUT_DIR
-  ${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR})
-set(COMPILER_RT_LIBRARY_INSTALL_DIR
-  ${COMPILER_RT_INSTALL_PATH}/lib/${COMPILER_RT_OS_DIR})
-
-# Add path for custom compiler-rt modules.
-set(CMAKE_MODULE_PATH
-  "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
-  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
-  ${CMAKE_MODULE_PATH}
-  )
 include(CompilerRTUtils)
 
 set(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
@@ -318,6 +266,8 @@
 add_subdirectory(lib)
 
 if(COMPILER_RT_INCLUDE_TESTS)
+  # Building the tests requires LLVM's CMake modules for lit support
+  include(AddLLVM)
   add_subdirectory(unittests)
   add_subdirectory(test)
 endif()
Index: cmake/Modules/AddCompilerRT.cmake
===================================================================
--- cmake/Modules/AddCompilerRT.cmake
+++ cmake/Modules/AddCompilerRT.cmake
@@ -1,4 +1,3 @@
-include(AddLLVM)
 include(ExternalProject)
 include(CompilerRTUtils)
 
Index: cmake/Modules/BuiltinTests.cmake
===================================================================
--- /dev/null
+++ cmake/Modules/BuiltinTests.cmake
@@ -0,0 +1,33 @@
+
+# This function takes an OS and a list of architectures and identifies the
+# subset of the architectures list that the installed toolchain can target.
+function(try_compile_only output)
+  set(SIMPLE_C ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.c)
+  file(WRITE ${SIMPLE_C} "int foo(int x, int y) { return x + y; }\n")
+
+  execute_process(
+    COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} "${ARGN}" -c ${SIMPLE_C}
+    RESULT_VARIABLE result
+    OUTPUT_VARIABLE TEST_OUTPUT
+    ERROR_VARIABLE TEST_ERROR
+  )
+  if(result EQUAL 0)
+    set(${output} True PARENT_SCOPE)
+  else()
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Testing compiler for supporting ${ARGN}:\n"
+        "${TEST_OUTPUT}\n${TEST_ERROR}\n")
+    set(${output} False PARENT_SCOPE)
+  endif()
+endfunction()
+
+function(builtin_check_c_compiler_flag flag output)
+  message(STATUS "Performing Test ${output}")
+  try_compile_only(result ${flag})
+  set(${output} ${result} PARENT_SCOPE)
+  if(${result})
+    message(STATUS "Performing Test ${output} - Success")
+  else()
+    message(STATUS "Performing Test ${output} - Failed")
+  endif()
+endfunction()
Index: cmake/Modules/CompilerRTDarwinUtils.cmake
===================================================================
--- cmake/Modules/CompilerRTDarwinUtils.cmake
+++ cmake/Modules/CompilerRTDarwinUtils.cmake
@@ -1,3 +1,5 @@
+include(CMakeParseArguments)
+
 # On OS X SDKs can be installed anywhere on the base system and xcode-select can
 # set the default Xcode to use. This function finds the SDKs that are present in
 # the current Xcode.
@@ -88,6 +90,36 @@
     CACHE STRING "List of valid architectures for platform ${os}.")
 endfunction()
 
+# This function takes an OS and a list of architectures and identifies the
+# subset of the architectures list that the installed toolchain can target.
+# This variant of the function is specifically for generating builtin libraries
+# where we don't need a fully functioning sysroot.
+function(darwin_builtin_test_archs os valid_archs)
+  if(${valid_archs})
+    message(STATUS "Using cached valid architectures for ${os}.")
+    return()
+  endif()
+
+  set(archs ${ARGN})
+
+  # The simple program will build for x86_64h on the simulator because it is 
+  # compatible with x86_64 libraries (mostly), but since x86_64h isn't actually
+  # a valid or useful architecture for the iOS simulator we should drop it.
+  if(${os} STREQUAL "iossim")
+    list(REMOVE_ITEM archs "x86_64h")
+  endif()
+
+  set(working_archs)
+  foreach(arch ${archs})
+    set(arch_linker_flags "-arch ${arch} ${os_linker_flags}")
+    try_compile_only(CAN_TARGET_${os}_${arch} -v -arch ${arch} ${DARWIN_${os}_CFLAGS})
+    if(CAN_TARGET_${os}_${arch})
+      list(APPEND working_archs ${arch})
+    endif()
+  endforeach()
+  set(${valid_archs} ${working_archs} PARENT_SCOPE)
+endfunction()
+
 # This function checks the host cpusubtype to see if it is post-haswell. Haswell
 # and later machines can run x86_64h binaries. Haswell is cpusubtype 8.
 function(darwin_filter_host_archs input output)
Index: cmake/Modules/CompilerRTUtils.cmake
===================================================================
--- cmake/Modules/CompilerRTUtils.cmake
+++ cmake/Modules/CompilerRTUtils.cmake
@@ -1,3 +1,6 @@
+include(CMakePushCheckState)
+include(CheckSymbolExists)
+
 # Because compiler-rt spends a lot of time setting up custom compile flags,
 # define a handy helper function for it. The compile flags setting in CMake
 # has serious issues that make its syntax challenging at best.
@@ -67,3 +70,28 @@
     endif()
   endforeach()
 endmacro()
+
+# Takes ${ARGN} and puts only supported architectures in @out_var list.
+function(filter_available_targets out_var)
+  set(archs ${${out_var}})
+  foreach(arch ${ARGN})
+    list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)
+    if(NOT (ARCH_INDEX EQUAL -1) AND CAN_TARGET_${arch})
+      list(APPEND archs ${arch})
+    endif()
+  endforeach()
+  set(${out_var} ${archs} PARENT_SCOPE)
+endfunction()
+
+function(check_compile_definition def argstring out_var)
+  if("${def}" STREQUAL "")
+    set(${out_var} TRUE PARENT_SCOPE)
+    return()
+  endif()
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${argstring}")
+  check_symbol_exists(${def} "" ${out_var})
+  cmake_pop_check_state()
+endfunction()
+
+
Index: cmake/base-config-ix.cmake
===================================================================
--- /dev/null
+++ cmake/base-config-ix.cmake
@@ -0,0 +1,156 @@
+# The CompilerRT build system requires CMake version 2.8.8 or higher in order
+# to use its support for building convenience "libraries" as a collection of
+# .o files. This is particularly useful in producing larger, more complex
+# runtime libraries.
+
+# Top level target used to build all compiler-rt libraries.
+add_custom_target(compiler-rt ALL)
+
+if (NOT COMPILER_RT_STANDALONE_BUILD)
+  # Compute the Clang version from the LLVM version.
+  # FIXME: We should be able to reuse CLANG_VERSION variable calculated
+  #        in Clang cmake files, instead of copying the rules here.
+  string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
+         ${PACKAGE_VERSION})
+  # Setup the paths where compiler-rt runtimes and headers should be stored.
+  set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION})
+  set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
+  set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION})
+  option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests."
+         ${LLVM_INCLUDE_TESTS})
+ option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered"
+        ${LLVM_ENABLE_WERROR})
+  # Use just-built Clang to compile/link tests on all platforms, except for
+  # Windows where we need to use clang-cl instead.
+  if(NOT MSVC)
+    set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
+  else()
+    set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe)
+  endif()
+else()
+    # Take output dir and install path from the user.
+  set(COMPILER_RT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH
+    "Path where built compiler-rt libraries should be stored.")
+  set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH
+    "Path where built compiler-rt executables should be stored.")
+  set(COMPILER_RT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} CACHE PATH
+    "Path where built compiler-rt libraries should be installed.")
+  option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests." OFF)
+  option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" OFF)
+  # Use a host compiler to compile/link tests.
+  set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "Compiler to use for testing")
+endif()
+
+if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$")
+  set(COMPILER_RT_TEST_COMPILER_ID Clang)
+elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang.*.exe$")
+  set(COMPILER_RT_TEST_COMPILER_ID Clang)
+else()
+  set(COMPILER_RT_TEST_COMPILER_ID GNU)
+endif()
+
+if ("${COMPILER_RT_DEFAULT_TARGET_ABI}" STREQUAL "androideabi")
+  set(ANDROID 1)
+endif()
+
+string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR)
+set(COMPILER_RT_LIBRARY_OUTPUT_DIR
+  ${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR})
+set(COMPILER_RT_LIBRARY_INSTALL_DIR
+  ${COMPILER_RT_INSTALL_PATH}/lib/${COMPILER_RT_OS_DIR})
+
+if(APPLE)
+  option(COMPILER_RT_ENABLE_IOS "Enable building for iOS - Experimental" Off)
+  option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off)
+  option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off)
+endif()
+
+# test_target_arch(<arch> <def> <target flags...>)
+# Checks if architecture is supported: runs host compiler with provided
+# flags to verify that:
+#   1) <def> is defined (if non-empty)
+#   2) simple file can be successfully built.
+# If successful, saves target flags for this architecture.
+macro(test_target_arch arch def)
+  set(TARGET_${arch}_CFLAGS ${ARGN})
+  set(argstring "")
+  foreach(arg ${ARGN})
+    set(argstring "${argstring} ${arg}")
+  endforeach()
+  check_compile_definition("${def}" "${argstring}" HAS_${arch}_DEF)
+  if(NOT HAS_${arch}_DEF)
+    set(CAN_TARGET_${arch} FALSE)
+  elseif(TEST_COMPILE_ONLY)
+    set(argstring "${CMAKE_EXE_LINKER_FLAGS} ${argstring}")
+    try_compile_only(CAN_TARGET_${arch} ${TARGET_${arch}_CFLAGS})
+  else()
+    set(argstring "${CMAKE_EXE_LINKER_FLAGS} ${argstring}")
+    try_compile(CAN_TARGET_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_SOURCE}
+                COMPILE_DEFINITIONS "${TARGET_${arch}_CFLAGS}"
+                OUTPUT_VARIABLE TARGET_${arch}_OUTPUT
+                CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS:STRING=${argstring}")
+  endif()
+  if(${CAN_TARGET_${arch}})
+    list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
+  elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "${arch}" AND
+         COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE)
+    # Bail out if we cannot target the architecture we plan to test.
+    message(FATAL_ERROR "Cannot compile for ${arch}:\n${TARGET_${arch}_OUTPUT}")
+  endif()
+endmacro()
+
+macro(test_targets)
+  # Generate the COMPILER_RT_SUPPORTED_ARCH list.
+  if(ANDROID)
+    # Examine compiler output to determine target architecture.
+    detect_target_arch()
+    set(COMPILER_RT_OS_SUFFIX "-android")
+  elseif(NOT APPLE) # Supported archs for Apple platforms are generated later
+    if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "i[2-6]86|x86|amd64")
+      if(NOT MSVC)
+        test_target_arch(x86_64 "" "-m64")
+        # FIXME: We build runtimes for both i686 and i386, as "clang -m32" may
+        # target different variant than "$CMAKE_C_COMPILER -m32". This part should
+        # be gone after we resolve PR14109.
+        test_target_arch(i686 __i686__ "-m32")
+        test_target_arch(i386 __i386__ "-m32")
+      else()
+        if (CMAKE_SIZEOF_VOID_P EQUAL 4)
+          test_target_arch(i386 "" "")
+        else()
+          test_target_arch(x86_64 "" "")
+        endif()
+      endif()
+    elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc")
+      TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN)
+      if(HOST_IS_BIG_ENDIAN)
+        test_target_arch(powerpc64 "" "-m64")
+      else()
+        test_target_arch(powerpc64le "" "-m64")
+      endif()
+    elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mipsel|mips64el")
+      # Gcc doesn't accept -m32/-m64 so we do the next best thing and use
+      # -mips32r2/-mips64r2. We don't use -mips1/-mips3 because we want to match
+      # clang's default CPU's. In the 64-bit case, we must also specify the ABI
+      # since the default ABI differs between gcc and clang.
+      # FIXME: Ideally, we would build the N32 library too.
+      test_target_arch(mipsel "" "-mips32r2" "--target=mipsel-linux-gnu")
+      test_target_arch(mips64el "" "-mips64r2" "--target=mips64el-linux-gnu" "-mabi=n64")
+    elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mips")
+      test_target_arch(mips "" "-mips32r2" "--target=mips-linux-gnu")
+      test_target_arch(mips64 "" "-mips64r2" "--target=mips64-linux-gnu" "-mabi=n64")
+    elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm")
+      test_target_arch(arm "" "-march=armv7-a" "-mfloat-abi=soft" "-target=arm")
+      test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard" "-target=arm")
+    elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32")
+      test_target_arch(aarch32 "" "-march=armv8-a" "-target" "arm")
+    elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64")
+      test_target_arch(aarch64 "" "-march=armv8-a" "-target" "aarch64")
+    elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32")
+      test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown")
+    elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64")
+      test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown")
+    endif()
+    set(COMPILER_RT_OS_SUFFIX "")
+  endif()
+endmacro()
Index: cmake/builtin-config-ix.cmake
===================================================================
--- /dev/null
+++ cmake/builtin-config-ix.cmake
@@ -0,0 +1,182 @@
+include(BuiltinTests)
+
+builtin_check_c_compiler_flag(-fPIC                 COMPILER_RT_HAS_FPIC_FLAG)
+builtin_check_c_compiler_flag(-fPIE                 COMPILER_RT_HAS_FPIE_FLAG)
+builtin_check_c_compiler_flag(-fno-builtin          COMPILER_RT_HAS_FNO_BUILTIN_FLAG)
+builtin_check_c_compiler_flag(-std=c99              COMPILER_RT_HAS_STD_C99_FLAG)
+builtin_check_c_compiler_flag(-fvisibility=hidden   COMPILER_RT_HAS_VISIBILITY_HIDDEN_FLAG)
+builtin_check_c_compiler_flag(-fomit-frame-pointer  COMPILER_RT_HAS_OMIT_FRAME_POINTER_FLAG)
+builtin_check_c_compiler_flag(-ffreestanding        COMPILER_RT_HAS_FREESTANDING_FLAG)
+builtin_check_c_compiler_flag(-mfloat-abi=soft      COMPILER_RT_HAS_FLOAT_ABI_SOFT_FLAG)
+builtin_check_c_compiler_flag(-mfloat-abi=hard      COMPILER_RT_HAS_FLOAT_ABI_HARD_FLAG)
+builtin_check_c_compiler_flag(-static               COMPILER_RT_HAS_STATIC_FLAG)
+
+set(ARM64 aarch64)
+set(ARM32 arm armhf)
+set(X86 i386 i686)
+set(X86_64 x86_64)
+set(MIPS32 mips mipsel)
+set(MIPS64 mips64 mips64el)
+set(PPC64 powerpc64 powerpc64le)
+set(WASM32 wasm32)
+set(WASM64 wasm64)
+
+if(APPLE)
+  set(ARM64 arm64)
+  set(ARM32 armv7 armv7s)
+  set(X86_64 x86_64 x86_64h)
+endif()
+
+set(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
+    ${MIPS32} ${MIPS64} ${WASM32} ${WASM64})
+
+include(CompilerRTUtils)
+include(CompilerRTDarwinUtils)
+
+if(APPLE)
+  # On Darwin if /usr/include doesn't exist, the user probably has Xcode but not
+  # the command line tools. If this is the case, we need to find the OS X
+  # sysroot to pass to clang.
+  if(NOT EXISTS /usr/include)
+    execute_process(COMMAND xcodebuild -version -sdk macosx Path
+       OUTPUT_VARIABLE OSX_SYSROOT
+       ERROR_QUIET
+       OUTPUT_STRIP_TRAILING_WHITESPACE)
+    set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}")
+  endif()
+
+  option(COMPILER_RT_ENABLE_IOS "Enable building for iOS - Experimental" Off)
+  option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off)
+  option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off)
+
+  find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx)
+  find_darwin_sdk_dir(DARWIN_iossim_SYSROOT iphonesimulator)
+  find_darwin_sdk_dir(DARWIN_ios_SYSROOT iphoneos)
+  find_darwin_sdk_dir(DARWIN_watchossim_SYSROOT watchsimulator)
+  find_darwin_sdk_dir(DARWIN_watchos_SYSROOT watchos)
+  find_darwin_sdk_dir(DARWIN_tvossim_SYSROOT appletvsimulator)
+  find_darwin_sdk_dir(DARWIN_tvos_SYSROOT appletvos)
+
+  set(DARWIN_EMBEDDED_PLATFORMS)
+
+  if(COMPILER_RT_ENABLE_IOS)
+    list(APPEND DARWIN_EMBEDDED_PLATFORMS ios)
+    set(DARWIN_ios_MIN_VER_FLAG -miphoneos-version-min)
+    set(DARWIN_ios_BUILTIN_MIN_VER 6.0)
+    set(DARWIN_ios_BUILTIN_MIN_VER_FLAG
+      ${DARWIN_ios_MIN_VER_FLAG}=${DARWIN_ios_BUILTIN_MIN_VER})
+  endif()
+  if(COMPILER_RT_ENABLE_WATCHOS)
+    list(APPEND DARWIN_EMBEDDED_PLATFORMS watchos)
+    set(DARWIN_watchos_MIN_VER_FLAG -mwatchos-version-min)
+    set(DARWIN_watchos_BUILTIN_MIN_VER 2.0)
+    set(DARWIN_watchos_BUILTIN_MIN_VER_FLAG
+      ${DARWIN_watchos_MIN_VER_FLAG}=${DARWIN_watchos_BUILTIN_MIN_VER})
+  endif()
+  if(COMPILER_RT_ENABLE_TVOS)
+    list(APPEND DARWIN_EMBEDDED_PLATFORMS tvos)
+    set(DARWIN_tvos_MIN_VER_FLAG -mtvos-version-min)
+    set(DARWIN_tvos_BUILTIN_MIN_VER 9.0)
+    set(DARWIN_tvos_BUILTIN_MIN_VER_FLAG
+      ${DARWIN_tvos_MIN_VER_FLAG}=${DARWIN_tvos_BUILTIN_MIN_VER})
+  endif()
+
+  set(BUILTIN_SUPPORTED_OS osx)
+
+  # We're setting the flag manually for each target OS
+  set(CMAKE_OSX_DEPLOYMENT_TARGET "")
+
+  if(NOT DARWIN_osx_ARCHS)
+    set(DARWIN_osx_ARCHS i386 x86_64 x86_64h)
+  endif()
+
+  set(DARWIN_sim_ARCHS i386 x86_64)
+  set(DARWIN_device_ARCHS armv7 armv7s armv7k arm64)
+  
+  message(STATUS "OSX supported arches: ${DARWIN_osx_ARCHS}")
+  foreach(arch ${DARWIN_osx_ARCHS})
+    list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
+    set(CAN_TARGET_${arch} 1)
+  endforeach()
+
+  # Need to build a 10.4 compatible libclang_rt
+  set(DARWIN_10.4_SYSROOT ${DARWIN_osx_SYSROOT})
+  set(DARWIN_10.4_BUILTIN_MIN_VER 10.4)
+  set(DARWIN_10.4_BUILTIN_MIN_VER_FLAG
+      -mmacosx-version-min=${DARWIN_10.4_BUILTIN_MIN_VER})
+  set(DARWIN_10.4_SKIP_CC_KEXT On)
+  darwin_builtin_test_archs(10.4 DARWIN_10.4_ARCHS i386 x86_64)
+  message(STATUS "OSX 10.4 supported builtin arches: ${DARWIN_10.4_ARCHS}")
+  if(DARWIN_10.4_ARCHS)
+    # don't include the Haswell slice in the 10.4 compatibility library
+    list(REMOVE_ITEM DARWIN_10.4_ARCHS x86_64h)
+    list(APPEND BUILTIN_SUPPORTED_OS 10.4)
+  endif()
+
+  foreach(platform ${DARWIN_EMBEDDED_PLATFORMS})
+
+    if(DARWIN_${platform}sim_SYSROOT)
+      set(DARWIN_${platform}sim_BUILTIN_MIN_VER
+        ${DARWIN_${platform}_BUILTIN_MIN_VER})
+      set(DARWIN_${platform}sim_BUILTIN_MIN_VER_FLAG
+        ${DARWIN_${platform}_BUILTIN_MIN_VER_FLAG})
+
+      set(DARWIN_${platform}sim_SKIP_CC_KEXT On)
+
+      set(test_arches ${DARWIN_sim_ARCHS})
+      if(DARWIN_${platform}sim_ARCHS)
+        set(test_arches DARWIN_${platform}sim_ARCHS)
+      endif()
+
+      darwin_builtin_test_archs(${platform}sim
+        DARWIN_${platform}sim_ARCHS
+        ${test_arches})
+      message(STATUS "${platform} Simulator supported builtin arches: ${DARWIN_${platform}sim_ARCHS}")
+      if(DARWIN_iossim_ARCHS)
+        list(APPEND BUILTIN_SUPPORTED_OS ${platform}sim)
+      endif()
+      foreach(arch ${DARWIN_${platform}sim_ARCHS})
+        list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
+        set(CAN_TARGET_${arch} 1)
+      endforeach()
+    endif()
+
+    if(DARWIN_${platform}_SYSROOT)
+      set(test_arches ${DARWIN_device_ARCHS})
+      if(DARWIN_${platform}_ARCHS)
+        set(test_arches DARWIN_${platform}_ARCHS)
+      endif()
+
+      darwin_builtin_test_archs(${platform}
+        DARWIN_${platform}_ARCHS
+        ${test_arches})
+      message(STATUS "${platform} supported builtin arches: ${DARWIN_${platform}_ARCHS}")
+      if(DARWIN_${platform}_ARCHS)
+        list(APPEND BUILTIN_SUPPORTED_OS ${platform})
+      endif()
+      foreach(arch ${DARWIN_${platform}_ARCHS})
+        list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
+        set(CAN_TARGET_${arch} 1)
+      endforeach()
+    endif()
+  endforeach()
+
+  # for list_intersect
+  include(CompilerRTUtils)
+
+  list_intersect(BUILTIN_SUPPORTED_ARCH ALL_BUILTIN_SUPPORTED_ARCH COMPILER_RT_SUPPORTED_ARCH)
+
+else()
+  # If we're not building the builtins standalone, just rely on the  tests in
+  # config-ix.cmake to tell us what to build. Otherwise we need to do some leg
+  # work here...
+  if(COMPILER_RT_BUILTINS_STANDALONE_BUILD)
+    set(TEST_COMPILE_ONLY On)
+    test_targets()
+  endif()
+  # Architectures supported by compiler-rt libraries.
+  filter_available_targets(BUILTIN_SUPPORTED_ARCH
+    ${ALL_BUILTIN_SUPPORTED_ARCH})
+endif()
+
+message(STATUS "Builtin supported architectures: ${BUILTIN_SUPPORTED_ARCH}")
Index: cmake/config-ix.cmake
===================================================================
--- cmake/config-ix.cmake
+++ cmake/config-ix.cmake
@@ -93,17 +93,6 @@
 set(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.cc)
 file(WRITE ${SIMPLE_SOURCE} "#include <stdlib.h>\n#include <limits>\nint main() {}\n")
 
-function(check_compile_definition def argstring out_var)
-  if("${def}" STREQUAL "")
-    set(${out_var} TRUE PARENT_SCOPE)
-    return()
-  endif()
-  cmake_push_check_state()
-  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${argstring}")
-  check_symbol_exists(${def} "" ${out_var})
-  cmake_pop_check_state()
-endfunction()
-
 # test_target_arch(<arch> <def> <target flags...>)
 # Checks if architecture is supported: runs host compiler with provided
 # flags to verify that:
@@ -180,71 +169,7 @@
   message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.")
 endif()
 
-# Generate the COMPILER_RT_SUPPORTED_ARCH list.
-if(ANDROID)
-  # Examine compiler output to determine target architecture.
-  detect_target_arch()
-  set(COMPILER_RT_OS_SUFFIX "-android")
-elseif(NOT APPLE) # Supported archs for Apple platforms are generated later
-  if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "i[2-6]86|x86|amd64")
-    if(NOT MSVC)
-      test_target_arch(x86_64 "" "-m64")
-      # FIXME: We build runtimes for both i686 and i386, as "clang -m32" may
-      # target different variant than "$CMAKE_C_COMPILER -m32". This part should
-      # be gone after we resolve PR14109.
-      test_target_arch(i686 __i686__ "-m32")
-      test_target_arch(i386 __i386__ "-m32")
-    else()
-      if (CMAKE_SIZEOF_VOID_P EQUAL 4)
-        test_target_arch(i386 "" "")
-      else()
-        test_target_arch(x86_64 "" "")
-      endif()
-    endif()
-  elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc")
-    TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN)
-    if(HOST_IS_BIG_ENDIAN)
-      test_target_arch(powerpc64 "" "-m64")
-    else()
-      test_target_arch(powerpc64le "" "-m64")
-    endif()
-  elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mipsel|mips64el")
-    # Gcc doesn't accept -m32/-m64 so we do the next best thing and use
-    # -mips32r2/-mips64r2. We don't use -mips1/-mips3 because we want to match
-    # clang's default CPU's. In the 64-bit case, we must also specify the ABI
-    # since the default ABI differs between gcc and clang.
-    # FIXME: Ideally, we would build the N32 library too.
-    test_target_arch(mipsel "" "-mips32r2" "--target=mipsel-linux-gnu")
-    test_target_arch(mips64el "" "-mips64r2" "--target=mips64el-linux-gnu" "-mabi=n64")
-  elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mips")
-    test_target_arch(mips "" "-mips32r2" "--target=mips-linux-gnu")
-    test_target_arch(mips64 "" "-mips64r2" "--target=mips64-linux-gnu" "-mabi=n64")
-  elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm")
-    test_target_arch(arm "" "-march=armv7-a" "-mfloat-abi=soft")
-    test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard")
-  elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32")
-    test_target_arch(aarch32 "" "-march=armv8-a")
-  elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64")
-    test_target_arch(aarch64 "" "-march=armv8-a")
-  elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32")
-    test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown")
-  elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64")
-    test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown")
-  endif()
-  set(COMPILER_RT_OS_SUFFIX "")
-endif()
-
-# Takes ${ARGN} and puts only supported architectures in @out_var list.
-function(filter_available_targets out_var)
-  set(archs ${${out_var}})
-  foreach(arch ${ARGN})
-    list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)
-    if(NOT (ARCH_INDEX EQUAL -1) AND CAN_TARGET_${arch})
-      list(APPEND archs ${arch})
-    endif()
-  endforeach()
-  set(${out_var} ${archs} PARENT_SCOPE)
-endfunction()
+test_targets()
 
 # Returns a list of architecture specific target cflags in @out_var list.
 function(get_target_flags_for_arch arch out_var)
@@ -279,8 +204,6 @@
   set(X86_64 x86_64 x86_64h)
 endif()
 
-set(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
-    ${MIPS32} ${MIPS64} ${WASM32} ${WASM64})
 set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64}
     ${ARM32} ${ARM64} ${MIPS32} ${MIPS64})
 set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
@@ -310,10 +233,6 @@
     set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}")
   endif()
 
-  option(COMPILER_RT_ENABLE_IOS "Enable building for iOS - Experimental" Off)
-  option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off)
-  option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off)
-
   find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx)
   find_darwin_sdk_dir(DARWIN_iossim_SYSROOT iphonesimulator)
   find_darwin_sdk_dir(DARWIN_ios_SYSROOT iphoneos)
@@ -327,33 +246,23 @@
     set(DARWIN_ios_MIN_VER_FLAG -miphoneos-version-min)
     set(DARWIN_ios_SANITIZER_MIN_VER_FLAG
       ${DARWIN_ios_MIN_VER_FLAG}=7.0)
-    set(DARWIN_ios_BUILTIN_MIN_VER 6.0)
-    set(DARWIN_ios_BUILTIN_MIN_VER_FLAG
-      ${DARWIN_ios_MIN_VER_FLAG}=${DARWIN_ios_BUILTIN_MIN_VER})
   endif()
   if(COMPILER_RT_ENABLE_WATCHOS)
     list(APPEND DARWIN_EMBEDDED_PLATFORMS watchos)
     set(DARWIN_watchos_MIN_VER_FLAG -mwatchos-version-min)
     set(DARWIN_watchos_SANITIZER_MIN_VER_FLAG
       ${DARWIN_watchos_MIN_VER_FLAG}=2.0)
-    set(DARWIN_watchos_BUILTIN_MIN_VER 2.0)
-    set(DARWIN_watchos_BUILTIN_MIN_VER_FLAG
-      ${DARWIN_watchos_MIN_VER_FLAG}=${DARWIN_watchos_BUILTIN_MIN_VER})
   endif()
   if(COMPILER_RT_ENABLE_TVOS)
     list(APPEND DARWIN_EMBEDDED_PLATFORMS tvos)
     set(DARWIN_tvos_MIN_VER_FLAG -mtvos-version-min)
     set(DARWIN_tvos_SANITIZER_MIN_VER_FLAG
       ${DARWIN_tvos_MIN_VER_FLAG}=9.0)
-    set(DARWIN_tvos_BUILTIN_MIN_VER 9.0)
-    set(DARWIN_tvos_BUILTIN_MIN_VER_FLAG
-      ${DARWIN_tvos_MIN_VER_FLAG}=${DARWIN_tvos_BUILTIN_MIN_VER})
   endif()
 
   # Note: In order to target x86_64h on OS X the minimum deployment target must
   # be 10.8 or higher.
   set(SANITIZER_COMMON_SUPPORTED_OS osx)
-  set(BUILTIN_SUPPORTED_OS osx)
   set(PROFILE_SUPPORTED_OS osx)
   set(TSAN_SUPPORTED_OS osx)
   if(NOT SANITIZER_MIN_OSX_VERSION)
@@ -391,9 +300,6 @@
   set(DARWIN_osx_LINKFLAGS
     ${DARWIN_COMMON_LINKFLAGS}
     -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION})
-  set(DARWIN_osx_BUILTIN_MIN_VER 10.5)
-  set(DARWIN_osx_BUILTIN_MIN_VER_FLAG
-      -mmacosx-version-min=${DARWIN_osx_BUILTIN_MIN_VER})
 
   if(DARWIN_osx_SYSROOT)
     list(APPEND DARWIN_osx_CFLAGS -isysroot ${DARWIN_osx_SYSROOT})
@@ -414,22 +320,6 @@
       set(CAN_TARGET_${arch} 1)
     endforeach()
 
-    # Need to build a 10.4 compatible libclang_rt
-    set(DARWIN_10.4_SYSROOT ${DARWIN_osx_SYSROOT})
-    set(DARWIN_10.4_BUILTIN_MIN_VER 10.4)
-    set(DARWIN_10.4_BUILTIN_MIN_VER_FLAG
-        -mmacosx-version-min=${DARWIN_10.4_BUILTIN_MIN_VER})
-    set(DARWIN_10.4_SKIP_CC_KEXT On)
-    darwin_test_archs(10.4
-      DARWIN_10.4_ARCHS
-      ${toolchain_arches})
-    message(STATUS "OSX 10.4 supported arches: ${DARWIN_10.4_ARCHS}")
-    if(DARWIN_10.4_ARCHS)
-      # don't include the Haswell slice in the 10.4 compatibility library
-      list(REMOVE_ITEM DARWIN_10.4_ARCHS x86_64h)
-      list(APPEND BUILTIN_SUPPORTED_OS 10.4)
-    endif()
-
     foreach(platform ${DARWIN_EMBEDDED_PLATFORMS})
       if(DARWIN_${platform}sim_SYSROOT)
         set(DARWIN_${platform}sim_CFLAGS
@@ -440,10 +330,6 @@
           ${DARWIN_COMMON_LINKFLAGS}
           ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
           -isysroot ${DARWIN_${platform}sim_SYSROOT})
-        set(DARWIN_${platform}sim_BUILTIN_MIN_VER
-          ${DARWIN_${platform}_BUILTIN_MIN_VER})
-        set(DARWIN_${platform}sim_BUILTIN_MIN_VER_FLAG
-          ${DARWIN_${platform}_BUILTIN_MIN_VER_FLAG})
 
         set(DARWIN_${platform}sim_SKIP_CC_KEXT On)
         darwin_test_archs(${platform}sim
@@ -452,7 +338,6 @@
         message(STATUS "${platform} Simulator supported arches: ${DARWIN_${platform}sim_ARCHS}")
         if(DARWIN_iossim_ARCHS)
           list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform}sim)
-          list(APPEND BUILTIN_SUPPORTED_OS ${platform}sim)
           list(APPEND PROFILE_SUPPORTED_OS ${platform}sim)
         endif()
         foreach(arch ${DARWIN_${platform}sim_ARCHS})
@@ -477,7 +362,6 @@
         message(STATUS "${platform} supported arches: ${DARWIN_${platform}_ARCHS}")
         if(DARWIN_${platform}_ARCHS)
           list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform})
-          list(APPEND BUILTIN_SUPPORTED_OS ${platform})
           list(APPEND PROFILE_SUPPORTED_OS ${platform})
         endif()
         foreach(arch ${DARWIN_${platform}_ARCHS})
@@ -491,7 +375,6 @@
   # for list_intersect
   include(CompilerRTUtils)
 
-  list_intersect(BUILTIN_SUPPORTED_ARCH ALL_BUILTIN_SUPPORTED_ARCH toolchain_arches)
 
   list_intersect(SANITIZER_COMMON_SUPPORTED_ARCH
     ALL_SANITIZER_COMMON_SUPPORTED_ARCH
@@ -528,8 +411,6 @@
     SANITIZER_COMMON_SUPPORTED_ARCH)
 else()
   # Architectures supported by compiler-rt libraries.
-  filter_available_targets(BUILTIN_SUPPORTED_ARCH
-    ${ALL_BUILTIN_SUPPORTED_ARCH})
   filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH
     ${ALL_SANITIZER_COMMON_SUPPORTED_ARCH})
   # LSan and UBSan common files should be available on all architectures
Index: lib/builtins/CMakeLists.txt
===================================================================
--- lib/builtins/CMakeLists.txt
+++ lib/builtins/CMakeLists.txt
@@ -4,6 +4,24 @@
 
 # TODO: Need to add a mechanism for logging errors when builtin source files are
 # added to a sub-directory and not this CMakeLists file.
+if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+  cmake_minimum_required(VERSION 3.2)
+
+  project(CompilerRTBuiltins C CXX ASM)
+  set(COMPILER_RT_STANDALONE_BUILD TRUE)
+  set(COMPILER_RT_BUILTINS_STANDALONE_BUILD TRUE)
+  list(INSERT CMAKE_MODULE_PATH 0
+    "${CMAKE_SOURCE_DIR}/../../cmake"
+    "${CMAKE_SOURCE_DIR}/../../cmake/Modules")
+  include(base-config-ix)
+  include(CompilerRTUtils)
+  if(APPLE)
+    include(CompilerRTDarwinUtils)
+  endif()
+  include(AddCompilerRT)
+endif()
+
+include(builtin-config-ix)
 
 set(GENERIC_SOURCES
   absvdi2.c