about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-06-22 13:14:00 -0700
committerAlex Crichton <alex@alexcrichton.com>2017-07-05 07:08:36 -0700
commit7e6c9f363501c49d3a1f666d85d41891f50890b8 (patch)
tree4ae27896af44a2d8226c640556d6e997ac67c148
parent1d2db7b9e8082f0459e000985d77fc7ad0dabade (diff)
downloadrust-7e6c9f363501c49d3a1f666d85d41891f50890b8.tar.gz
rust-7e6c9f363501c49d3a1f666d85d41891f50890b8.zip
Switch to rust-lang-nursery/compiler-builtins
This commit migrates the in-tree `libcompiler_builtins` to the upstream version
at https://github.com/rust-lang-nursery/compiler-builtins. The upstream version
has a number of intrinsics written in Rust and serves as an in-progress rewrite
of compiler-rt into Rust. Additionally it also contains all the existing
intrinsics defined in `libcompiler_builtins` for 128-bit integers.

It's been the intention since the beginning to make this transition but
previously it just lacked the manpower to get done. As this PR likely shows it
wasn't a trivial integration! Some highlight changes are:

* The PR rust-lang-nursery/compiler-builtins#166 contains a number of fixes
  across platforms and also some refactorings to make the intrinsics easier to
  read. The additional testing added there also fixed a number of integration
  issues when pulling the repository into this tree.

* LTO with the compiler-builtins crate was fixed to link in the entire crate
  after the LTO process as these intrinsics are excluded from LTO.

* Treatment of hidden symbols was updated as previously the
  `#![compiler_builtins]` crate would mark all symbol *imports* as hidden
  whereas it was only intended to mark *exports* as hidden.
-rw-r--r--.gitmodules6
-rw-r--r--src/Cargo.lock1
-rw-r--r--src/bootstrap/bin/rustc.rs19
-rw-r--r--src/bootstrap/bootstrap.py2
-rw-r--r--src/bootstrap/dist.rs2
-rw-r--r--src/build_helper/lib.rs5
-rwxr-xr-xsrc/ci/init_repo.sh7
m---------src/compiler-rt0
-rw-r--r--src/doc/unstable-book/src/library-features/compiler-builtins-lib.md35
m---------src/libcompiler_builtins0
-rw-r--r--src/libcompiler_builtins/Cargo.toml19
-rw-r--r--src/libcompiler_builtins/build.rs423
-rw-r--r--src/libcompiler_builtins/lib.rs721
-rw-r--r--src/libprofiler_builtins/build.rs2
-rw-r--r--src/librustc_trans/attributes.rs2
-rw-r--r--src/librustc_trans/back/link.rs27
-rw-r--r--src/librustc_trans/back/write.rs3
-rw-r--r--src/librustc_trans/declare.rs11
-rw-r--r--src/librustc_trans/trans_item.rs12
-rw-r--r--src/libstd/Cargo.toml2
-rw-r--r--src/rustc/compiler_builtins_shim/Cargo.toml24
-rw-r--r--src/rustc/compiler_builtins_shim/build.rs (renamed from src/test/run-pass/auxiliary/clibrary.rs)13
-rw-r--r--src/test/run-pass/lib-defaults.rs9
-rw-r--r--src/test/run-pass/rfc1717/library-override.rs7
-rw-r--r--src/tools/tidy/src/lib.rs1
25 files changed, 109 insertions, 1244 deletions
diff --git a/.gitmodules b/.gitmodules
index 1ef3c086a1c..6244b3c0951 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,9 +2,6 @@
 	path = src/llvm
 	url = https://github.com/rust-lang/llvm.git
 	branch = master
-[submodule "src/compiler-rt"]
-	path = src/compiler-rt
-	url = https://github.com/rust-lang/compiler-rt.git
 [submodule "src/rt/hoedown"]
 	path = src/rt/hoedown
 	url = https://github.com/rust-lang/hoedown.git
@@ -33,3 +30,6 @@
 [submodule "src/tools/rls"]
 	path = src/tools/rls
 	url = https://github.com/rust-lang-nursery/rls.git
+[submodule "src/libcompiler_builtins"]
+	path = src/libcompiler_builtins
+	url = https://github.com/rust-lang-nursery/compiler-builtins
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 2d42903ad0a..cf4c3dce6e3 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -273,7 +273,6 @@ dependencies = [
 name = "compiler_builtins"
 version = "0.0.0"
 dependencies = [
- "build_helper 0.1.0",
  "core 0.0.0",
  "gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 8c6eaee24f2..fbb2ae29ef2 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -142,6 +142,11 @@ fn main() {
             }
         }
 
+        let crate_name = args.windows(2)
+            .find(|a| &*a[0] == "--crate-name")
+            .unwrap();
+        let crate_name = &*crate_name[1];
+
         // If we're compiling specifically the `panic_abort` crate then we pass
         // the `-C panic=abort` option. Note that we do not do this for any
         // other crate intentionally as this is the only crate for now that we
@@ -150,9 +155,7 @@ fn main() {
         // This... is a bit of a hack how we detect this. Ideally this
         // information should be encoded in the crate I guess? Would likely
         // require an RFC amendment to RFC 1513, however.
-        let is_panic_abort = args.windows(2)
-            .any(|a| &*a[0] == "--crate-name" && &*a[1] == "panic_abort");
-        if is_panic_abort {
+        if crate_name == "panic_abort" {
             cmd.arg("-C").arg("panic=abort");
         }
 
@@ -167,7 +170,15 @@ fn main() {
             Ok(s) => if s == "true" { "y" } else { "n" },
             Err(..) => "n",
         };
-        cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions));
+
+        // The compiler builtins are pretty sensitive to symbols referenced in
+        // libcore and such, so we never compile them with debug assertions.
+        if crate_name == "compiler_builtins" {
+            cmd.arg("-C").arg("debug-assertions=no");
+        } else {
+            cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions));
+        }
+
         if let Ok(s) = env::var("RUSTC_CODEGEN_UNITS") {
             cmd.arg("-C").arg(format!("codegen-units={}", s));
         }
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index eaf2a40f2fa..ebc4c2fdf7b 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -583,7 +583,7 @@ class RustBuild(object):
                                (self.get_toml('jemalloc') or
                                 self.get_mk('CFG_JEMALLOC_ROOT'))))]
         run(["git", "submodule", "update",
-             "--init"] + submodules,
+             "--init", "--recursive"] + submodules,
             cwd=self.rust_root, verbose=self.verbose)
         run(["git", "submodule", "-q", "foreach", "git",
              "reset", "-q", "--hard"],
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 753bd1df0d8..3bf1b82b0a8 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -564,10 +564,10 @@ pub fn rust_src(build: &Build) {
         "src/libstd",
         "src/libstd_unicode",
         "src/libunwind",
+        "src/rustc/compiler_builtins_shim",
         "src/rustc/libc_shim",
         "src/libtest",
         "src/libterm",
-        "src/compiler-rt",
         "src/jemalloc",
         "src/libprofiler_builtins",
     ];
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index ea6a822e360..7011261ab6c 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -239,7 +239,10 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str) -> Result<NativeLibBoiler
         ),
         _ => return Err(()),
     };
-    native_lib_boilerplate("compiler-rt", sanitizer_name, &link_name, search_path)
+    native_lib_boilerplate("libcompiler_builtins/compiler-rt",
+                           sanitizer_name,
+                           &link_name,
+                           search_path)
 }
 
 fn dir_up_to_date(src: &Path, threshold: &FileTime) -> bool {
diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh
index 817ed8dd554..f8e86986f82 100755
--- a/src/ci/init_repo.sh
+++ b/src/ci/init_repo.sh
@@ -67,13 +67,14 @@ for module in $modules; do
         mv "src/llvm-$commit" src/llvm
         continue
     fi
-    if [ ! -d "$cache_src_dir/$module" ]; then
+    if [ ! -e "$cache_src_dir/$module/.git" ]; then
         echo "WARNING: $module not found in pristine repo"
-        retry sh -c "git submodule deinit -f $module && git submodule update --init $module"
+        retry sh -c "git submodule deinit -f $module && \
+            git submodule update --init --recursive $module"
         continue
     fi
     retry sh -c "git submodule deinit -f $module && \
-        git submodule update --init --reference $cache_src_dir/$module $module"
+        git submodule update --init --recursive --reference $cache_src_dir/$module $module"
 done
 
 travis_fold end update_submodules
diff --git a/src/compiler-rt b/src/compiler-rt
deleted file mode 160000
-Subproject c8a8767c56ad3d3f4eb45c87b95026936fb9aa3
diff --git a/src/doc/unstable-book/src/library-features/compiler-builtins-lib.md b/src/doc/unstable-book/src/library-features/compiler-builtins-lib.md
deleted file mode 100644
index 5da8968fd0c..00000000000
--- a/src/doc/unstable-book/src/library-features/compiler-builtins-lib.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# `compiler_builtins_lib`
-
-The tracking issue for this feature is: None.
-
-------------------------
-
-This feature is required to link to the `compiler_builtins` crate which contains
-"compiler intrinsics". Compiler intrinsics are software implementations of basic
-operations like multiplication of `u64`s. These intrinsics are only required on
-platforms where these operations don't directly map to a hardware instruction.
-
-You should never need to explicitly link to the `compiler_builtins` crate when
-building "std" programs as `compiler_builtins` is already in the dependency
-graph of `std`. But you may need it when building `no_std` **binary** crates. If
-you get a *linker* error like:
-
-``` text
-$PWD/src/main.rs:11: undefined reference to `__aeabi_lmul'
-$PWD/src/main.rs:11: undefined reference to `__aeabi_uldivmod'
-```
-
-That means that you need to link to this crate.
-
-When you link to this crate, make sure it only appears once in your crate
-dependency graph. Also, it doesn't matter where in the dependency graph, you
-place the `compiler_builtins` crate.
-
-<!-- NOTE(ignore) doctests don't support `no_std` binaries -->
-
-``` rust,ignore
-#![feature(compiler_builtins_lib)]
-#![no_std]
-
-extern crate compiler_builtins;
-```
diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins
new file mode 160000
+Subproject 238647af806470dc73e585c03682083931d29cd
diff --git a/src/libcompiler_builtins/Cargo.toml b/src/libcompiler_builtins/Cargo.toml
deleted file mode 100644
index 2c9cee5e7a0..00000000000
--- a/src/libcompiler_builtins/Cargo.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-build = "build.rs"
-name = "compiler_builtins"
-version = "0.0.0"
-
-[lib]
-name = "compiler_builtins"
-path = "lib.rs"
-test = false
-bench = false
-doc = false
-
-[dependencies]
-core = { path = "../libcore" }
-
-[build-dependencies]
-build_helper = { path = "../build_helper" }
-gcc = "0.3.50"
diff --git a/src/libcompiler_builtins/build.rs b/src/libcompiler_builtins/build.rs
deleted file mode 100644
index 8fe79057bd8..00000000000
--- a/src/libcompiler_builtins/build.rs
+++ /dev/null
@@ -1,423 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Compiles the `compiler-rt` library, or at least the builtins part of it.
-//!
-//! Note that while compiler-rt has a build system associated with it, we
-//! specifically don't use it here. The compiler-rt build system, written in
-//! CMake, is actually *very* difficult to work with in terms of getting it to
-//! compile on all the relevant platforms we want it to compile on. In the end
-//! it became so much pain to work with local patches, work around the oddities
-//! of the build system, etc, that we're just building everything by hand now.
-//!
-//! In general compiler-rt is just a bunch of intrinsics that are in practice
-//! *very* stable. We just need to make sure that all the relevant functions and
-//! such are compiled somewhere and placed in an object file somewhere.
-//! Eventually, these should all be written in Rust!
-//!
-//! So below you'll find a listing of every single file in the compiler-rt repo
-//! that we're compiling. We just reach in and compile with the `gcc` crate
-//! which should have all the relevant flags and such already configured.
-//!
-//! The risk here is that if we update compiler-rt we may need to compile some
-//! new intrinsics, but to be honest we surely don't use all of the intrinsics
-//! listed below today so the likelihood of us actually needing a new intrinsic
-//! is quite low. The failure case is also just that someone reports a link
-//! error (if any) and then we just add it to the list. Overall, that cost is
-//! far far less than working with compiler-rt's build system over time.
-
-extern crate build_helper;
-extern crate gcc;
-
-use std::collections::BTreeMap;
-use std::env;
-use std::path::Path;
-use build_helper::native_lib_boilerplate;
-
-struct Sources {
-    // SYMBOL -> PATH TO SOURCE
-    map: BTreeMap<&'static str, &'static str>,
-}
-
-impl Sources {
-    fn new() -> Sources {
-        Sources { map: BTreeMap::new() }
-    }
-
-    fn extend(&mut self, sources: &[&'static str]) {
-        // NOTE Some intrinsics have both a generic implementation (e.g.
-        // `floatdidf.c`) and an arch optimized implementation
-        // (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized
-        // implementation and discard the generic implementation. If we don't
-        // and keep both implementations, the linker will yell at us about
-        // duplicate symbols!
-        for &src in sources {
-            let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap();
-            if src.contains("/") {
-                // Arch-optimized implementation (preferred)
-                self.map.insert(symbol, src);
-            } else {
-                // Generic implementation
-                if !self.map.contains_key(symbol) {
-                    self.map.insert(symbol, src);
-                }
-            }
-        }
-    }
-}
-
-fn main() {
-    let target = env::var("TARGET").expect("TARGET was not set");
-
-    // Emscripten's runtime includes all the builtins
-    if target.contains("emscripten") {
-        return;
-    }
-
-    // Can't reuse `sources` list for the freshness check becuse it doesn't contain header files.
-    let native = match native_lib_boilerplate("compiler-rt", "compiler-rt", "compiler-rt", ".") {
-        Ok(native) => native,
-        _ => return,
-    };
-
-    let cfg = &mut gcc::Config::new();
-    cfg.out_dir(&native.out_dir);
-
-    if target.contains("msvc") {
-        // Don't pull in extra libraries on MSVC
-        cfg.flag("/Zl");
-
-        // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
-        cfg.define("__func__", Some("__FUNCTION__"));
-    } else {
-        // Turn off various features of gcc and such, mostly copying
-        // compiler-rt's build system already
-        cfg.flag("-fno-builtin");
-        cfg.flag("-fvisibility=hidden");
-        // Accepted practice on Solaris is to never omit frame pointer so that
-        // system observability tools work as expected.  In addition, at least
-        // on Solaris, -fomit-frame-pointer on sparcv9 appears to generate
-        // references to data outside of the current stack frame.  A search of
-        // the gcc bug database provides a variety of issues surrounding
-        // -fomit-frame-pointer on non-x86 platforms.
-        if !target.contains("solaris") && !target.contains("sparc") {
-            cfg.flag("-fomit-frame-pointer");
-        }
-        cfg.flag("-ffreestanding");
-        cfg.define("VISIBILITY_HIDDEN", None);
-    }
-
-    let mut sources = Sources::new();
-    sources.extend(&["absvdi2.c",
-                     "absvsi2.c",
-                     "adddf3.c",
-                     "addsf3.c",
-                     "addvdi3.c",
-                     "addvsi3.c",
-                     "apple_versioning.c",
-                     "ashldi3.c",
-                     "ashrdi3.c",
-                     "clzdi2.c",
-                     "clzsi2.c",
-                     "cmpdi2.c",
-                     "comparedf2.c",
-                     "comparesf2.c",
-                     "ctzdi2.c",
-                     "ctzsi2.c",
-                     "divdc3.c",
-                     "divdf3.c",
-                     "divdi3.c",
-                     "divmoddi4.c",
-                     "divmodsi4.c",
-                     "divsc3.c",
-                     "divsf3.c",
-                     "divsi3.c",
-                     "divxc3.c",
-                     "extendsfdf2.c",
-                     "extendhfsf2.c",
-                     "ffsdi2.c",
-                     "fixdfdi.c",
-                     "fixdfsi.c",
-                     "fixsfdi.c",
-                     "fixsfsi.c",
-                     "fixunsdfdi.c",
-                     "fixunsdfsi.c",
-                     "fixunssfdi.c",
-                     "fixunssfsi.c",
-                     "fixunsxfdi.c",
-                     "fixunsxfsi.c",
-                     "fixxfdi.c",
-                     "floatdidf.c",
-                     "floatdisf.c",
-                     "floatdixf.c",
-                     "floatsidf.c",
-                     "floatsisf.c",
-                     "floatundidf.c",
-                     "floatundisf.c",
-                     "floatundixf.c",
-                     "floatunsidf.c",
-                     "floatunsisf.c",
-                     "int_util.c",
-                     "lshrdi3.c",
-                     "moddi3.c",
-                     "modsi3.c",
-                     "muldc3.c",
-                     "muldf3.c",
-                     "muldi3.c",
-                     "mulodi4.c",
-                     "mulosi4.c",
-                     "muloti4.c",
-                     "mulsc3.c",
-                     "mulsf3.c",
-                     "mulvdi3.c",
-                     "mulvsi3.c",
-                     "mulxc3.c",
-                     "negdf2.c",
-                     "negdi2.c",
-                     "negsf2.c",
-                     "negvdi2.c",
-                     "negvsi2.c",
-                     "paritydi2.c",
-                     "paritysi2.c",
-                     "popcountdi2.c",
-                     "popcountsi2.c",
-                     "powidf2.c",
-                     "powisf2.c",
-                     "powixf2.c",
-                     "subdf3.c",
-                     "subsf3.c",
-                     "subvdi3.c",
-                     "subvsi3.c",
-                     "truncdfhf2.c",
-                     "truncdfsf2.c",
-                     "truncsfhf2.c",
-                     "ucmpdi2.c",
-                     "udivdi3.c",
-                     "udivmoddi4.c",
-                     "udivmodsi4.c",
-                     "udivsi3.c",
-                     "umoddi3.c",
-                     "umodsi3.c"]);
-
-    if !target.contains("ios") {
-        sources.extend(&["absvti2.c",
-                         "addvti3.c",
-                         "ashlti3.c",
-                         "ashrti3.c",
-                         "clzti2.c",
-                         "cmpti2.c",
-                         "ctzti2.c",
-                         "divti3.c",
-                         "ffsti2.c",
-                         "fixdfti.c",
-                         "fixsfti.c",
-                         "fixunsdfti.c",
-                         "fixunssfti.c",
-                         "fixunsxfti.c",
-                         "fixxfti.c",
-                         "floattidf.c",
-                         "floattisf.c",
-                         "floattixf.c",
-                         "floatuntidf.c",
-                         "floatuntisf.c",
-                         "floatuntixf.c",
-                         "lshrti3.c",
-                         "modti3.c",
-                         "multi3.c",
-                         "mulvti3.c",
-                         "negti2.c",
-                         "negvti2.c",
-                         "parityti2.c",
-                         "popcountti2.c",
-                         "subvti3.c",
-                         "ucmpti2.c",
-                         "udivmodti4.c",
-                         "udivti3.c",
-                         "umodti3.c"]);
-    }
-
-    if target.contains("apple") {
-        sources.extend(&["atomic_flag_clear.c",
-                         "atomic_flag_clear_explicit.c",
-                         "atomic_flag_test_and_set.c",
-                         "atomic_flag_test_and_set_explicit.c",
-                         "atomic_signal_fence.c",
-                         "atomic_thread_fence.c"]);
-    }
-
-    if target.contains("msvc") {
-        if target.contains("x86_64") {
-            sources.extend(&["x86_64/floatdidf.c", "x86_64/floatdisf.c", "x86_64/floatdixf.c"]);
-        }
-    } else {
-        if !target.contains("freebsd") && !target.contains("netbsd") {
-            sources.extend(&["gcc_personality_v0.c"]);
-        }
-
-        if target.contains("x86_64") {
-            sources.extend(&["x86_64/chkstk.S",
-                             "x86_64/chkstk2.S",
-                             "x86_64/floatdidf.c",
-                             "x86_64/floatdisf.c",
-                             "x86_64/floatdixf.c",
-                             "x86_64/floatundidf.S",
-                             "x86_64/floatundisf.S",
-                             "x86_64/floatundixf.S"]);
-        }
-
-        if target.contains("i386") || target.contains("i586") || target.contains("i686") {
-            sources.extend(&["i386/ashldi3.S",
-                             "i386/ashrdi3.S",
-                             "i386/chkstk.S",
-                             "i386/chkstk2.S",
-                             "i386/divdi3.S",
-                             "i386/floatdidf.S",
-                             "i386/floatdisf.S",
-                             "i386/floatdixf.S",
-                             "i386/floatundidf.S",
-                             "i386/floatundisf.S",
-                             "i386/floatundixf.S",
-                             "i386/lshrdi3.S",
-                             "i386/moddi3.S",
-                             "i386/muldi3.S",
-                             "i386/udivdi3.S",
-                             "i386/umoddi3.S"]);
-        }
-    }
-
-    if target.contains("arm") && !target.contains("ios") {
-        // (At least) udivsi3.S is broken for Thumb 1 which our gcc uses by
-        // default, we don't want Thumb 2 since it isn't supported on some
-        // devices, so disable thumb entirely.
-        // Upstream bug: https://bugs.llvm.org/show_bug.cgi?id=32492
-        cfg.define("__ARM_ARCH_ISA_THUMB", Some("0"));
-
-        sources.extend(&["arm/aeabi_cdcmp.S",
-                         "arm/aeabi_cdcmpeq_check_nan.c",
-                         "arm/aeabi_cfcmp.S",
-                         "arm/aeabi_cfcmpeq_check_nan.c",
-                         "arm/aeabi_dcmp.S",
-                         "arm/aeabi_div0.c",
-                         "arm/aeabi_drsub.c",
-                         "arm/aeabi_fcmp.S",
-                         "arm/aeabi_frsub.c",
-                         "arm/aeabi_idivmod.S",
-                         "arm/aeabi_ldivmod.S",
-                         "arm/aeabi_memcmp.S",
-                         "arm/aeabi_memcpy.S",
-                         "arm/aeabi_memmove.S",
-                         "arm/aeabi_memset.S",
-                         "arm/aeabi_uidivmod.S",
-                         "arm/aeabi_uldivmod.S",
-                         "arm/bswapdi2.S",
-                         "arm/bswapsi2.S",
-                         "arm/clzdi2.S",
-                         "arm/clzsi2.S",
-                         "arm/comparesf2.S",
-                         "arm/divmodsi4.S",
-                         "arm/divsi3.S",
-                         "arm/modsi3.S",
-                         "arm/switch16.S",
-                         "arm/switch32.S",
-                         "arm/switch8.S",
-                         "arm/switchu8.S",
-                         "arm/sync_synchronize.S",
-                         "arm/udivmodsi4.S",
-                         "arm/udivsi3.S",
-                         "arm/umodsi3.S"]);
-    }
-
-    if target.contains("armv7") {
-        sources.extend(&["arm/sync_fetch_and_add_4.S",
-                         "arm/sync_fetch_and_add_8.S",
-                         "arm/sync_fetch_and_and_4.S",
-                         "arm/sync_fetch_and_and_8.S",
-                         "arm/sync_fetch_and_max_4.S",
-                         "arm/sync_fetch_and_max_8.S",
-                         "arm/sync_fetch_and_min_4.S",
-                         "arm/sync_fetch_and_min_8.S",
-                         "arm/sync_fetch_and_nand_4.S",
-                         "arm/sync_fetch_and_nand_8.S",
-                         "arm/sync_fetch_and_or_4.S",
-                         "arm/sync_fetch_and_or_8.S",
-                         "arm/sync_fetch_and_sub_4.S",
-                         "arm/sync_fetch_and_sub_8.S",
-                         "arm/sync_fetch_and_umax_4.S",
-                         "arm/sync_fetch_and_umax_8.S",
-                         "arm/sync_fetch_and_umin_4.S",
-                         "arm/sync_fetch_and_umin_8.S",
-                         "arm/sync_fetch_and_xor_4.S",
-                         "arm/sync_fetch_and_xor_8.S"]);
-    }
-
-    if target.contains("eabihf") {
-        sources.extend(&["arm/adddf3vfp.S",
-                         "arm/addsf3vfp.S",
-                         "arm/divdf3vfp.S",
-                         "arm/divsf3vfp.S",
-                         "arm/eqdf2vfp.S",
-                         "arm/eqsf2vfp.S",
-                         "arm/extendsfdf2vfp.S",
-                         "arm/fixdfsivfp.S",
-                         "arm/fixsfsivfp.S",
-                         "arm/fixunsdfsivfp.S",
-                         "arm/fixunssfsivfp.S",
-                         "arm/floatsidfvfp.S",
-                         "arm/floatsisfvfp.S",
-                         "arm/floatunssidfvfp.S",
-                         "arm/floatunssisfvfp.S",
-                         "arm/gedf2vfp.S",
-                         "arm/gesf2vfp.S",
-                         "arm/gtdf2vfp.S",
-                         "arm/gtsf2vfp.S",
-                         "arm/ledf2vfp.S",
-                         "arm/lesf2vfp.S",
-                         "arm/ltdf2vfp.S",
-                         "arm/ltsf2vfp.S",
-                         "arm/muldf3vfp.S",
-                         "arm/mulsf3vfp.S",
-                         "arm/negdf2vfp.S",
-                         "arm/negsf2vfp.S",
-                         "arm/nedf2vfp.S",
-                         "arm/nesf2vfp.S",
-                         "arm/restore_vfp_d8_d15_regs.S",
-                         "arm/save_vfp_d8_d15_regs.S",
-                         "arm/subdf3vfp.S",
-                         "arm/subsf3vfp.S",
-                         "arm/truncdfsf2vfp.S",
-                         "arm/unorddf2vfp.S",
-                         "arm/unordsf2vfp.S"]);
-    }
-
-    if target.contains("aarch64") {
-        sources.extend(&["comparetf2.c",
-                         "extenddftf2.c",
-                         "extendsftf2.c",
-                         "fixtfdi.c",
-                         "fixtfsi.c",
-                         "fixtfti.c",
-                         "fixunstfdi.c",
-                         "fixunstfsi.c",
-                         "fixunstfti.c",
-                         "floatditf.c",
-                         "floatsitf.c",
-                         "floatunditf.c",
-                         "floatunsitf.c",
-                         "multc3.c",
-                         "trunctfdf2.c",
-                         "trunctfsf2.c"]);
-    }
-
-    for src in sources.map.values() {
-        cfg.file(Path::new("../compiler-rt/lib/builtins").join(src));
-    }
-
-    cfg.compile("libcompiler-rt.a");
-}
diff --git a/src/libcompiler_builtins/lib.rs b/src/libcompiler_builtins/lib.rs
deleted file mode 100644
index 09b3d639507..00000000000
--- a/src/libcompiler_builtins/lib.rs
+++ /dev/null
@@ -1,721 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(compiler_builtins)]
-#![no_std]
-#![compiler_builtins]
-#![unstable(feature = "compiler_builtins_lib",
-            reason = "internal implementation detail of rustc right now",
-            issue = "0")]
-#![crate_name = "compiler_builtins"]
-#![crate_type = "rlib"]
-#![allow(unused_features)]
-#![feature(staged_api, core_intrinsics, repr_simd,
-           i128_type, core_float, abi_unadjusted, associated_consts)]
-#![allow(non_camel_case_types, unused_variables, unused_imports)]
-
-#[cfg(any(target_pointer_width="32", target_pointer_width="16", target_os="windows",
-          target_arch="mips64"))]
-pub mod reimpls {
-
-    #![allow(unused_comparisons)]
-
-    use core::intrinsics::unchecked_div;
-    use core::intrinsics::unchecked_rem;
-    use core::ptr;
-
-    macro_rules! ashl {
-        ($a:expr, $b:expr, $ty:ty) => {{
-            let (a, b) = ($a, $b);
-            let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty;
-            let half_bits = bits.wrapping_shr(1);
-            if b & half_bits != 0 {
-                <$ty>::from_parts(0, a.low().wrapping_shl(
-                                        b.wrapping_sub(half_bits) as u32))
-            } else if b == 0 {
-                a
-            } else {
-                <$ty>::from_parts(a.low().wrapping_shl(b as u32),
-                                  a.high().wrapping_shl(b as u32)
-                                  | a.low()
-                                     .wrapping_shr(half_bits.wrapping_sub(b) as u32))
-            }
-        }}
-    }
-
-    #[export_name="__ashlti3"]
-    pub extern "C" fn shl(a: u128, b: u128) -> u128 {
-        ashl!(a, b, u128)
-    }
-
-    macro_rules! ashr {
-        ($a: expr, $b: expr, $ty:ty) => {{
-            let (a, b) = ($a, $b);
-            let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty;
-            let half_bits = bits.wrapping_shr(1);
-            if b & half_bits != 0 {
-                <$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32)
-                                  as <$ty as LargeInt>::LowHalf,
-                                  a.high().wrapping_shr(half_bits.wrapping_sub(1) as u32))
-            } else if b == 0 {
-                a
-            } else {
-                let high_unsigned = a.high() as <$ty as LargeInt>::LowHalf;
-                <$ty>::from_parts(high_unsigned.wrapping_shl(half_bits.wrapping_sub(b) as u32)
-                                  | a.low().wrapping_shr(b as u32),
-                                  a.high().wrapping_shr(b as u32))
-            }
-        }}
-    }
-
-    #[export_name="__ashrti3"]
-    pub extern "C" fn shr(a: i128, b: i128) -> i128 {
-        ashr!(a, b, i128)
-    }
-
-    macro_rules! lshr {
-        ($a: expr, $b: expr, $ty:ty) => {{
-            let (a, b) = ($a, $b);
-            let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty;
-            let half_bits = bits.wrapping_shr(1);
-            if b & half_bits != 0 {
-                <$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32), 0)
-            } else if b == 0 {
-                a
-            } else {
-                <$ty>::from_parts(a.high().wrapping_shl(half_bits.wrapping_sub(b) as u32)
-                                  | a.low().wrapping_shr(b as u32),
-                                  a.high().wrapping_shr(b as u32))
-            }
-        }}
-    }
-
-
-    #[export_name="__lshrti3"]
-    pub extern "C" fn lshr(a: u128, b: u128) -> u128 {
-        lshr!(a, b, u128)
-    }
-
-    pub extern "C" fn u128_div_mod(n: u128, d: u128, rem: *mut u128) -> u128 {
-        // Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide
-        unsafe {
-        // special cases, X is unknown, K != 0
-        if n.high() == 0 {
-            if d.high() == 0 {
-                // 0 X
-                // ---
-                // 0 X
-                if !rem.is_null() {
-                    *rem = u128::from(unchecked_rem(n.low(), d.low()));
-                }
-                return u128::from(unchecked_div(n.low(), d.low()));
-            } else {
-                // 0 X
-                // ---
-                // K X
-                if !rem.is_null() {
-                    *rem = n;
-                }
-                return 0;
-            };
-        }
-
-        let mut sr;
-        let mut q;
-        let mut r;
-
-        if d.low() == 0 {
-            if d.high() == 0 {
-                // K X
-                // ---
-                // 0 0
-                if !rem.is_null() {
-                    *rem = u128::from(unchecked_rem(n.high(), d.low()));
-                }
-                return u128::from(unchecked_div(n.high(), d.low()));
-            }
-
-            if n.low() == 0 {
-                // K 0
-                // ---
-                // K 0
-                if !rem.is_null() {
-                    *rem = u128::from_parts(0, unchecked_rem(n.high(), d.high()));
-                }
-                return u128::from(unchecked_div(n.high(), d.high()));
-            }
-
-            // K K
-            // ---
-            // K 0
-
-            if d.high().is_power_of_two() {
-                if !rem.is_null() {
-                    *rem = u128::from_parts(n.low(),
-                                            n.high() & (d.high().wrapping_sub(1)));
-                }
-                return u128::from(n.high().wrapping_shr(d.high().trailing_zeros()));
-            }
-
-            // K K
-            // ---
-            // K 0
-            sr = d.high().leading_zeros().wrapping_sub(n.high().leading_zeros());
-
-            // D > N
-            if sr > 64 - 2 {
-                if !rem.is_null() {
-                    *rem = n;
-                }
-                return 0;
-            }
-
-            sr = sr.wrapping_add(1);
-
-            // 1 <= sr <= u64::bits() - 1
-            q = n.wrapping_shl(128u32.wrapping_sub(sr));
-            r = n.wrapping_shr(sr);
-        } else {
-            if d.high() == 0 {
-                // K X
-                // ---
-                // 0 K
-                if d.low().is_power_of_two() {
-                    if !rem.is_null() {
-                        *rem = u128::from(n.low() & (d.low().wrapping_sub(1)));
-                    }
-
-                    if d.low() == 1 {
-                        return n;
-                    } else {
-                        let sr = d.low().trailing_zeros();
-                        return n.wrapping_shr(sr);
-                    };
-                }
-
-                sr = (1 + 64u32)
-                    .wrapping_add(d.low().leading_zeros())
-                    .wrapping_sub(n.high().leading_zeros());
-
-                // 2 <= sr <= u64::bits() - 1
-                q = n.wrapping_shl(128u32.wrapping_sub(sr));
-                r = n.wrapping_shr(sr);
-                // FIXME the C compiler-rt implementation has something here
-                // that looks like a speed optimisation.
-                // It would be worth a try to port it to Rust too and
-                // compare the speed.
-            } else {
-                // K X
-                // ---
-                // K K
-                sr = d.high().leading_zeros().wrapping_sub(n.high().leading_zeros());
-
-                // D > N
-                if sr > 64 - 1 {
-                    if !rem.is_null() {
-                        *rem = n;
-                    }
-                    return 0;
-                }
-
-                sr = sr.wrapping_add(1);
-
-                // 1 <= sr <= u32::bits()
-                q = n.wrapping_shl(128u32.wrapping_sub(sr));
-                r = n.wrapping_shr(sr);
-            }
-        }
-
-        // Not a special case
-        // q and r are initialized with
-        // q = n << (u64::bits() - sr)
-        // r = n >> sr
-        // 1 <= sr <= u64::bits() - 1
-        let mut carry = 0;
-
-        // FIXME: replace this with a for loop
-        // (atm not doable as this generates call to
-        // eh_personality when optimisations are turned off,
-        // which in turn gives a linker error in later
-        // compilation steps)
-        while sr > 0 {
-            // r:q = ((r:q) << 1) | carry
-            r = r.wrapping_shl(1) | q.wrapping_shr(128 - 1);
-            q = q.wrapping_shl(1) | carry as u128;
-
-            // carry = 0
-            // if r >= d {
-            //     r -= d;
-            //     carry = 1;
-            // }
-            let s = ((d.wrapping_sub(r).wrapping_sub(1)) as i128).wrapping_shr(128 - 1);
-            carry = (s & 1) as u64;
-            r = r.wrapping_sub(d & s as u128);
-            sr = sr.wrapping_sub(1);
-        }
-
-        if !rem.is_null() {
-            *rem = r;
-        }
-        (q.wrapping_shl(1)) | carry as u128
-        }
-    }
-
-    fn i128_mod(a: i128, b: i128) -> i128 {
-        let b = b.uabs();
-        let sa = a.signum();
-        let a = a.uabs();
-        unsafe {
-            let mut r = ::core::mem::zeroed();
-            u128_div_mod(a, b, &mut r);
-            if sa == -1 { (r as i128).unchecked_neg() } else { r as i128 }
-        }
-    }
-
-    fn i128_div(a: i128, b: i128) -> i128 {
-        let sa = a.signum();
-        let sb = b.signum();
-        let a = a.uabs();
-        let b = b.uabs();
-        let sr = sa.wrapping_mul(sb); // sign of quotient
-        (if sr == -1 {
-            (u128_div_mod(a, b, ptr::null_mut()) as i128).unchecked_neg()
-        } else {
-            u128_div_mod(a, b, ptr::null_mut()) as i128
-        })
-    }
-
-    macro_rules! mulo {
-        ($a:expr, $b:expr, $o: expr, $ty: ty) => {{
-            let (a, b, overflow) = ($a, $b, $o);
-            *overflow = 0;
-            let result = a.wrapping_mul(b);
-            if a == <$ty>::min_value() {
-                if b != 0 && b != 1 {
-                    *overflow = 1;
-                }
-                return result;
-            }
-            if b == <$ty>::min_value() {
-                if a != 0 && a != 1 {
-                    *overflow = 1;
-                }
-                return result;
-            }
-
-            let sa = a.signum();
-            let abs_a = a.iabs();
-            let sb = b.signum();
-            let abs_b = b.iabs();
-            if abs_a < 2 || abs_b < 2 {
-                return result;
-            }
-            if sa == sb {
-                if abs_a > unchecked_div(<$ty>::max_value(), abs_b) {
-                    *overflow = 1;
-                }
-            } else {
-                if abs_a > unchecked_div(<$ty>::min_value(), abs_b.unchecked_neg()) {
-                    *overflow = 1;
-                }
-            }
-            result
-        }}
-    }
-
-    pub trait LargeInt {
-        type LowHalf;
-        type HighHalf;
-
-        fn low(self) -> Self::LowHalf;
-        fn high(self) -> Self::HighHalf;
-        fn from_parts(low: Self::LowHalf, high: Self::HighHalf) -> Self;
-    }
-    impl LargeInt for u128 {
-        type LowHalf = u64;
-        type HighHalf = u64;
-
-        fn low(self) -> u64 {
-            self as u64
-        }
-        fn high(self) -> u64 {
-            self.wrapping_shr(64) as u64
-        }
-        fn from_parts(low: u64, high: u64) -> u128 {
-            (high as u128).wrapping_shl(64) | low as u128
-        }
-    }
-    impl LargeInt for i128 {
-        type LowHalf = u64;
-        type HighHalf = i64;
-
-        fn low(self) -> u64 {
-            self as u64
-        }
-        fn high(self) -> i64 {
-            self.wrapping_shr(64) as i64
-        }
-        fn from_parts(low: u64, high: i64) -> i128 {
-            u128::from_parts(low, high as u64) as i128
-        }
-    }
-
-    macro_rules! mul {
-        ($a:expr, $b:expr, $ty: ty, $tyh: ty) => {{
-            let (a, b) = ($a, $b);
-            let half_bits = ::core::mem::size_of::<$tyh>().wrapping_mul(4) as u32;
-            let lower_mask = (!0u64).wrapping_shr(half_bits);
-            let mut low = (a.low() & lower_mask).wrapping_mul(b.low() & lower_mask);
-            let mut t = low.wrapping_shr(half_bits);
-            low &= lower_mask;
-            t = t.wrapping_add(a.low().wrapping_shr(half_bits)
-                                      .wrapping_mul(b.low() & lower_mask));
-            low = low.wrapping_add((t & lower_mask).wrapping_shl(half_bits));
-            let mut high = t.wrapping_shr(half_bits) as $tyh;
-            t = low.wrapping_shr(half_bits);
-            low &= lower_mask;
-            t = t.wrapping_add(b.low().wrapping_shr(half_bits)
-                                      .wrapping_mul(a.low() & lower_mask));
-            low = low.wrapping_add((t & lower_mask).wrapping_shl(half_bits));
-            high = high.wrapping_add(t.wrapping_shr(half_bits) as $tyh);
-            high = high.wrapping_add(a.low().wrapping_shr(half_bits)
-                           .wrapping_mul(b.low().wrapping_shr(half_bits)) as $tyh);
-            high = high
-                .wrapping_add(a.high()
-                .wrapping_mul(b.low() as $tyh))
-                .wrapping_add((a.low() as $tyh)
-                .wrapping_mul(b.high()));
-            <$ty>::from_parts(low, high)
-        }}
-    }
-
-    #[export_name="__multi3"]
-    pub extern "C" fn u128_mul(a: i128, b: i128) -> i128 {
-        mul!(a, b, i128, i64)
-    }
-
-    trait AbsExt: Sized {
-        fn uabs(self) -> u128;
-        fn iabs(self) -> i128;
-    }
-
-    impl AbsExt for i128 {
-        fn uabs(self) -> u128 {
-            self.iabs() as u128
-        }
-        fn iabs(self) -> i128 {
-            let s = self.wrapping_shr(127);
-            ((self ^ s).wrapping_sub(s))
-        }
-    }
-
-    trait NegExt: Sized {
-        fn unchecked_neg(self) -> i128;
-    }
-
-    impl NegExt for i128 {
-        fn unchecked_neg(self) -> i128 {
-            (!self).wrapping_add(1)
-        }
-    }
-
-    trait FloatStuff: Sized {
-        type ToBytes;
-
-        const MANTISSA_BITS: u32;
-        const MAX_EXP: i32;
-        const EXP_MASK: Self::ToBytes;
-        const MANTISSA_MASK: Self::ToBytes;
-        const MANTISSA_LEAD_BIT: Self::ToBytes;
-
-        fn to_bytes(self) -> Self::ToBytes;
-        fn get_exponent(self) -> i32;
-    }
-
-    impl FloatStuff for f32 {
-        type ToBytes = u32;
-        const MANTISSA_BITS: u32 = 23;
-        const MAX_EXP: i32 = 127;
-        const EXP_MASK: u32 = 0x7F80_0000;
-        const MANTISSA_MASK: u32 = 0x007F_FFFF;
-        const MANTISSA_LEAD_BIT: u32 = 0x0080_0000;
-
-        fn to_bytes(self) -> u32 { unsafe { ::core::mem::transmute(self) } }
-        fn get_exponent(self) -> i32 {
-            ((self.to_bytes() & Self::EXP_MASK).wrapping_shr(Self::MANTISSA_BITS) as i32)
-            .wrapping_sub(Self::MAX_EXP)
-        }
-    }
-
-    impl FloatStuff for f64 {
-        type ToBytes = u64;
-        const MANTISSA_BITS: u32 = 52;
-        const MAX_EXP: i32 = 1023;
-        const EXP_MASK: u64 = 0x7FF0_0000_0000_0000;
-        const MANTISSA_MASK: u64 = 0x000F_FFFF_FFFF_FFFF;
-        const MANTISSA_LEAD_BIT: u64 = 0x0010_0000_0000_0000;
-
-        fn to_bytes(self) -> u64 { unsafe { ::core::mem::transmute(self) } }
-        fn get_exponent(self) -> i32 {
-            ((self.to_bytes() & Self::EXP_MASK).wrapping_shr(Self::MANTISSA_BITS) as i32)
-            .wrapping_sub(Self::MAX_EXP)
-        }
-    }
-
-    macro_rules! float_as_unsigned {
-        ($from: expr, $fromty: ty, $outty: ty) => { {
-            use core::num::Float;
-            let repr = $from.to_bytes();
-            let sign = $from.signum();
-            let exponent = $from.get_exponent();
-            let mantissa_fraction = repr & <$fromty as FloatStuff>::MANTISSA_MASK;
-            let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT;
-            if sign == -1.0 || exponent < 0 { return 0 as u128; }
-            if exponent > ::core::mem::size_of::<$outty>().wrapping_mul(8) as i32 {
-                return !(0 as u128);
-            }
-            (if exponent < (<$fromty as FloatStuff>::MANTISSA_BITS) as i32 {
-                (mantissa as $outty)
-                    .wrapping_shr((<$fromty as FloatStuff>::MANTISSA_BITS as i32)
-                                  .wrapping_sub(exponent) as u32)
-            } else {
-                (mantissa as $outty)
-                    .wrapping_shl(exponent.wrapping_sub(
-                        <$fromty as FloatStuff>::MANTISSA_BITS as i32) as u32)
-            })
-        } }
-    }
-
-    macro_rules! float_as_signed {
-        ($from: expr, $fromty: ty, $outty: ty) => {{
-            use core::num::Float;
-            let repr = $from.to_bytes();
-            let sign = $from.signum();
-            let exponent = $from.get_exponent();
-            let mantissa_fraction = repr & <$fromty as FloatStuff>::MANTISSA_MASK;
-            let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT;
-
-            if exponent < 0 { return 0 as i128; }
-            if exponent > ::core::mem::size_of::<$outty>().wrapping_mul(8) as i32 {
-                let ret = if sign > 0.0 { <$outty>::max_value() } else { <$outty>::min_value() };
-                return ret
-            }
-            let r = if exponent < (<$fromty as FloatStuff>::MANTISSA_BITS) as i32 {
-                (mantissa as $outty)
-                    .wrapping_shr((<$fromty as FloatStuff>::MANTISSA_BITS as i32)
-                                  .wrapping_sub(exponent) as u32)
-            } else {
-                (mantissa as $outty)
-                    .wrapping_shl(exponent.wrapping_sub(
-                        <$fromty as FloatStuff>::MANTISSA_BITS as i32) as u32)
-            };
-            (if sign >= 0.0 { r } else { r.unchecked_neg() })
-        }}
-    }
-
-
-    fn i128_as_f64(a: i128) -> f64 {
-        match a.signum() {
-            1 => u128_as_f64(a.uabs()),
-            0 => 0.0,
-            _ => -u128_as_f64(a.uabs()),
-        }
-    }
-
-    fn i128_as_f32(a: i128) -> f32 {
-        match a.signum() {
-            1 => u128_as_f32(a.uabs()),
-            0 => 0.0,
-            _ => -u128_as_f32(a.uabs()),
-        }
-    }
-
-    fn u128_as_f64(mut a: u128) -> f64 {
-        use ::core::f64::MANTISSA_DIGITS;
-        if a == 0 { return 0.0; }
-        let sd = 128u32.wrapping_sub(a.leading_zeros());
-        let mut e = sd.wrapping_sub(1);
-        const MD1 : u32 = MANTISSA_DIGITS + 1;
-        const MD2 : u32 = MANTISSA_DIGITS + 2;
-
-        let negn = !0u128;
-
-        if sd > MANTISSA_DIGITS {
-            a = match sd {
-                MD1 => a.wrapping_shl(1),
-                MD2 => a,
-                _ => a.wrapping_shr(sd.wrapping_sub(MANTISSA_DIGITS + 2)) |
-                     (if (a & (negn.wrapping_shr(128 + MANTISSA_DIGITS + 2)
-                                   .wrapping_sub(sd as u128))) == 0 { 0 } else { 1 })
-            };
-            a |= if (a & 4) == 0 { 0 } else { 1 };
-            a = a.wrapping_add(1);
-            a = a.wrapping_shr(2);
-            if a & (1 << MANTISSA_DIGITS) != 0 {
-                a = a.wrapping_shr(1);
-                e = e.wrapping_add(1);
-            }
-        } else {
-            a = a.wrapping_shl(MANTISSA_DIGITS.wrapping_sub(sd));
-        }
-        unsafe {
-            ::core::mem::transmute((e as u64).wrapping_add(1023).wrapping_shl(52)
-                                   | (a as u64 & 0x000f_ffff_ffff_ffff))
-        }
-    }
-
-    fn u128_as_f32(mut a: u128) -> f32 {
-        use ::core::f32::MANTISSA_DIGITS;
-        if a == 0 { return 0.0; }
-        let sd = 128u32.wrapping_sub(a.leading_zeros());
-        let mut e = sd.wrapping_sub(1);
-        const MD1 : u32 = MANTISSA_DIGITS + 1;
-        const MD2 : u32 = MANTISSA_DIGITS + 2;
-
-        let negn = !0u128;
-
-        if sd > MANTISSA_DIGITS {
-            a = match sd {
-                MD1 => a.wrapping_shl(1),
-                MD2 => a,
-                _ => a.wrapping_shr(sd.wrapping_sub(MANTISSA_DIGITS + 2)) |
-                     (if (a & (negn.wrapping_shr(128 + MANTISSA_DIGITS + 2)
-                                   .wrapping_sub(sd as u128))) == 0 { 0 } else { 1 })
-            };
-            a |= if (a & 4) == 0 { 0 } else { 1 };
-            a = a.wrapping_add(1);
-            a = a.wrapping_shr(2);
-            if a & (1 << MANTISSA_DIGITS) != 0 {
-                a = a.wrapping_shr(1);
-                e = e.wrapping_add(1);
-            }
-        } else {
-            a = a.wrapping_shl(MANTISSA_DIGITS.wrapping_sub(sd));
-        }
-        unsafe {
-            ::core::mem::transmute((e as u32).wrapping_add(127).wrapping_shl(23)
-                                   | (a as u32 & 0x007f_ffff))
-        }
-    }
-
-
-    macro_rules! why_are_abi_strings_checked_by_parser { ($cret:ty, $conv:expr, $unadj:tt) => {
-    mod imp {
-        use super::{LargeInt, FloatStuff, NegExt, AbsExt};
-        use super::{i128_as_f64, i128_as_f32, u128_as_f64, u128_as_f32,
-                    i128_div, i128_mod, u128_div_mod, unchecked_div, ptr};
-        // For x64
-        // rdx:rcx, r9:r8, stack -> rdx:rax
-        // aka.
-        // define i128 @__muloti4(i128, i128, i32*)
-        #[export_name="__muloti4"]
-        pub unsafe extern $unadj fn i128_mul_oflow(a: i128, b: i128, o: *mut i32) -> i128 {
-            mulo!(a, b, o, i128)
-        }
-
-        // For x64
-        // rdx:rax -> xmm0
-        // aka.
-        // define double @__muloti4(i128)
-        #[export_name="__floattidf"]
-        pub extern $unadj fn i128_as_f64_(a: i128) -> f64 {
-            i128_as_f64(a)
-        }
-        #[export_name="__floattisf"]
-        pub extern $unadj fn i128_as_f32_(a: i128) -> f32 {
-            i128_as_f32(a)
-        }
-        #[export_name="__floatuntidf"]
-        pub extern $unadj fn u128_as_f64_(a: u128) -> f64 {
-            u128_as_f64(a)
-        }
-        #[export_name="__floatuntisf"]
-        pub extern $unadj fn u128_as_f32_(a: u128) -> f32 {
-            u128_as_f32(a)
-        }
-
-        // For x64
-        // xmm0 -> rdx:rax
-        // aka.
-        // define i128 @stuff(double)
-        #[export_name="__fixunsdfti"]
-        pub extern $unadj fn f64_as_u128(a: f64) -> u128 {
-            float_as_unsigned!(a, f64, u128)
-        }
-
-        #[export_name="__fixunssfti"]
-        pub extern $unadj fn f32_as_u128(a: f32) -> u128 {
-            float_as_unsigned!(a, f32, u128)
-        }
-
-        #[export_name="__fixdfti"]
-        pub extern $unadj fn f64_as_i128(a: f64) -> i128 {
-            float_as_signed!(a, f64, i128)
-        }
-
-        #[export_name="__fixsfti"]
-        pub extern $unadj fn f32_as_i128(a: f32) -> i128 {
-            float_as_signed!(a, f32, i128)
-        }
-
-        #[repr(simd)]
-        pub struct u64x2(u64, u64);
-
-        // For x64
-        // pointers -> xmm0
-        // aka.
-        // define <2 x u64> @stuff(i128*, i128*, i128*)
-        //
-        // That almost matches the C ABI, so we simply use the C ABI
-        #[export_name="__udivmodti4"]
-        pub extern "C" fn u128_div_mod_(n: u128, d: u128, rem: *mut u128) -> $cret {
-            let x = u128_div_mod(n, d, rem);
-            ($conv)(x)
-        }
-
-        #[export_name="__udivti3"]
-        pub extern "C" fn u128_div_(a: u128, b: u128) -> $cret {
-            let x = u128_div_mod(a, b, ptr::null_mut());
-            ($conv)(x)
-        }
-
-        #[export_name="__umodti3"]
-        pub extern "C" fn u128_mod_(a: u128, b: u128) -> $cret {
-            unsafe {
-                let mut r = ::core::mem::zeroed();
-                u128_div_mod(a, b, &mut r);
-                ($conv)(r)
-            }
-        }
-
-        #[export_name="__divti3"]
-        pub extern "C" fn i128_div_(a: i128, b: i128) -> $cret {
-            let x = i128_div(a, b);
-            ($conv)(x as u128)
-        }
-
-        #[export_name="__modti3"]
-        pub extern "C" fn i128_mod_(a: i128, b: i128) -> $cret {
-            let x = i128_mod(a, b);
-            ($conv)(x as u128)
-        }
-    }
-    } }
-
-    // LLVM expectations for ABI on windows x64 are pure madness.
-    #[cfg(all(windows, target_pointer_width="64"))]
-    why_are_abi_strings_checked_by_parser!(u64x2,
-                                           |i: u128| u64x2(i.low(), i.high()),
-                                           "unadjusted");
-
-    #[cfg(not(all(windows, target_pointer_width="64")))]
-    why_are_abi_strings_checked_by_parser!(u128, |i|{ i }, "C");
-    pub use self::imp::*;
-}
diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs
index 1ee284ff4da..55df14ea215 100644
--- a/src/libprofiler_builtins/build.rs
+++ b/src/libprofiler_builtins/build.rs
@@ -53,7 +53,7 @@ fn main() {
     }
 
     for src in profile_sources {
-        cfg.file(Path::new("../compiler-rt/lib/profile").join(src));
+        cfg.file(Path::new("../libcompiler_builtins/compiler-rt/lib/profile").join(src));
     }
 
     cfg.compile("libprofiler-rt.a");
diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs
index 6bef31ccf64..fa93c005dcd 100644
--- a/src/librustc_trans/attributes.rs
+++ b/src/librustc_trans/attributes.rs
@@ -13,7 +13,7 @@ use std::ffi::{CStr, CString};
 
 use llvm::{self, Attribute, ValueRef};
 use llvm::AttributePlace::Function;
-pub use syntax::attr::InlineAttr;
+pub use syntax::attr::{self, InlineAttr};
 use syntax::ast;
 use context::CrateContext;
 
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index a7f205a18a4..b32e1d4aa8d 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -363,6 +363,24 @@ pub fn each_linked_rlib(sess: &Session,
     Ok(())
 }
 
+/// Returns a boolean indicating whether the specified crate should be ignored
+/// during LTO.
+///
+/// Crates ignored during LTO are not lumped together in the "massive object
+/// file" that we create and are linked in their normal rlib states. See
+/// comments below for what crates do not participate in LTO.
+///
+/// It's unusual for a crate to not participate in LTO. Typically only
+/// compiler-specific and unstable crates have a reason to not participate in
+/// LTO.
+pub fn ignored_for_lto(sess: &Session, cnum: CrateNum) -> bool {
+    // `#![no_builtins]` crates don't participate in LTO because the state
+    // of builtins gets messed up (our crate isn't tagged with no builtins).
+    // Similarly `#![compiler_builtins]` doesn't participate because we want
+    // those builtins!
+    sess.cstore.is_no_builtins(cnum) || sess.cstore.is_compiler_builtins(cnum)
+}
+
 fn out_filename(sess: &Session,
                 crate_type: config::CrateType,
                 outputs: &OutputFilenames,
@@ -698,7 +716,10 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
         let skip_object_files = native_libs.iter().any(|lib| {
             lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib)
         });
-        ab.add_rlib(path, &name.as_str(), sess.lto(), skip_object_files).unwrap();
+        ab.add_rlib(path,
+                    &name.as_str(),
+                    sess.lto() && !ignored_for_lto(sess, cnum),
+                    skip_object_files).unwrap();
 
         all_native_libs.extend(sess.cstore.native_libraries(cnum));
     });
@@ -1247,7 +1268,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
             lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib)
         });
 
-        if !sess.lto() && crate_type != config::CrateTypeDylib && !skip_native {
+        if (!sess.lto() || ignored_for_lto(sess, cnum)) &&
+           crate_type != config::CrateTypeDylib &&
+           !skip_native {
             cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
             return
         }
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 562d7171156..1703a121e17 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -1200,8 +1200,7 @@ fn spawn_work<'a>(sess: &'a Session,
     let crate_types = sess.crate_types.borrow().clone();
     let mut each_linked_rlib_for_lto = Vec::new();
     drop(link::each_linked_rlib(sess, &mut |cnum, path| {
-        // `#![no_builtins]` crates don't participate in LTO.
-        if sess.cstore.is_no_builtins(cnum) {
+        if link::ignored_for_lto(sess, cnum) {
             return
         }
         each_linked_rlib_for_lto.push((cnum, path.to_path_buf()));
diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs
index 2787812f962..8f9146283ef 100644
--- a/src/librustc_trans/declare.rs
+++ b/src/librustc_trans/declare.rs
@@ -30,7 +30,6 @@ use context::CrateContext;
 use common;
 use type_::Type;
 use value::Value;
-use syntax::attr;
 
 use std::ffi::CString;
 
@@ -88,16 +87,6 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty:
         }
     }
 
-    // If we're compiling the compiler-builtins crate, e.g. the equivalent of
-    // compiler-rt, then we want to implicitly compile everything with hidden
-    // visibility as we're going to link this object all over the place but
-    // don't want the symbols to get exported.
-    if attr::contains_name(ccx.tcx().hir.krate_attrs(), "compiler_builtins") {
-        unsafe {
-            llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
-        }
-    }
-
     match ccx.tcx().sess.opts.cg.opt_level.as_ref().map(String::as_ref) {
         Some("s") => {
             llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn);
diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs
index 2a6e7c5ace6..200f6dee334 100644
--- a/src/librustc_trans/trans_item.rs
+++ b/src/librustc_trans/trans_item.rs
@@ -162,6 +162,18 @@ impl<'a, 'tcx> TransItem<'tcx> {
             llvm::SetUniqueComdat(ccx.llmod(), lldecl);
         }
 
+        // If we're compiling the compiler-builtins crate, e.g. the equivalent of
+        // compiler-rt, then we want to implicitly compile everything with hidden
+        // visibility as we're going to link this object all over the place but
+        // don't want the symbols to get exported.
+        if linkage != llvm::Linkage::InternalLinkage &&
+           linkage != llvm::Linkage::PrivateLinkage &&
+           attr::contains_name(ccx.tcx().hir.krate_attrs(), "compiler_builtins") {
+            unsafe {
+                llvm::LLVMRustSetVisibility(lldecl, llvm::Visibility::Hidden);
+            }
+        }
+
         debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance);
         if common::is_inline_instance(ccx.tcx(), &instance) {
             attributes::inline(lldecl, attributes::InlineAttr::Hint);
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index b516cbd08ca..09c16816934 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -19,7 +19,7 @@ collections = { path = "../libcollections" }
 core = { path = "../libcore" }
 libc = { path = "../rustc/libc_shim" }
 rand = { path = "../librand" }
-compiler_builtins = { path = "../libcompiler_builtins" }
+compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 std_unicode = { path = "../libstd_unicode" }
 unwind = { path = "../libunwind" }
diff --git a/src/rustc/compiler_builtins_shim/Cargo.toml b/src/rustc/compiler_builtins_shim/Cargo.toml
new file mode 100644
index 00000000000..e0026078a5d
--- /dev/null
+++ b/src/rustc/compiler_builtins_shim/Cargo.toml
@@ -0,0 +1,24 @@
+# See libc_shim/Cargo.toml for why this exists
+
+[package]
+name = "compiler_builtins"
+authors = ["The Rust Project Developers"]
+version = "0.0.0"
+build = "../../libcompiler_builtins/build.rs"
+
+[lib]
+path = "../../libcompiler_builtins/src/lib.rs"
+test = false
+doctest = false
+
+[dependencies]
+core = { path = "../../libcore" }
+
+[build-dependencies]
+gcc = "0.3"
+
+[features]
+c = []
+default = ["c", "rustbuild", "compiler-builtins"]
+rustbuild = []
+compiler-builtins = []
diff --git a/src/test/run-pass/auxiliary/clibrary.rs b/src/rustc/compiler_builtins_shim/build.rs
index 7438ba21bfc..546f60482e7 100644
--- a/src/test/run-pass/auxiliary/clibrary.rs
+++ b/src/rustc/compiler_builtins_shim/build.rs
@@ -1,4 +1,4 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,8 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// no-prefer-dynamic
-#![crate_type = "staticlib"]
+#![deny(warnings)]
 
-#[no_mangle]
-pub extern "C" fn foo(x:i32) -> i32 { x }
+// See comments in Cargo.toml for why this exists
+
+fn main() {
+    println!("cargo:rustc-cfg=stdbuild");
+    println!("cargo:rerun-if-changed=build.rs");
+}
diff --git a/src/test/run-pass/lib-defaults.rs b/src/test/run-pass/lib-defaults.rs
index a38080f8cfe..6e5dccae0a0 100644
--- a/src/test/run-pass/lib-defaults.rs
+++ b/src/test/run-pass/lib-defaults.rs
@@ -8,16 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:clibrary.rs
-// compile-flags: -lclibrary
+// compile-flags: -lrust_test_helpers
 
-#[link(name = "clibrary", kind = "static")]
+#[link(name = "rust_test_helpers", kind = "static")]
 extern "C" {
-    pub fn foo(x:i32) -> i32;
+    pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
 }
 
 fn main() {
     unsafe {
-        foo(42);
+        rust_dbg_extern_identity_u32(42);
     }
 }
diff --git a/src/test/run-pass/rfc1717/library-override.rs b/src/test/run-pass/rfc1717/library-override.rs
index d6ef96c5add..26713a25543 100644
--- a/src/test/run-pass/rfc1717/library-override.rs
+++ b/src/test/run-pass/rfc1717/library-override.rs
@@ -8,16 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:clibrary.rs
-// compile-flags: -lstatic=wronglibrary:clibrary
+// compile-flags: -lstatic=wronglibrary:rust_test_helpers
 
 #[link(name = "wronglibrary", kind = "dylib")]
 extern "C" {
-    pub fn foo(x:i32) -> i32;
+    pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
 }
 
 fn main() {
     unsafe {
-        foo(42);
+        rust_dbg_extern_identity_u32(42);
     }
 }
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index bcf86e4489b..020570e61dc 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -54,6 +54,7 @@ fn filter_dirs(path: &Path) -> bool {
         "src/jemalloc",
         "src/llvm",
         "src/libbacktrace",
+        "src/libcompiler_builtins",
         "src/compiler-rt",
         "src/rustllvm",
         "src/liblibc",