diff --git a/.gitmodules b/.gitmodules
index 003e50d0788e4..8d47f7323f197 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -39,8 +39,8 @@
 	url = https://github.com/rust-lang/edition-guide.git
 [submodule "src/llvm-project"]
 	path = src/llvm-project
-	url = https://github.com/rust-lang/llvm-project.git
-	branch = rustc/9.0-2019-12-19
+	url = https://github.com/nikic/llvm-project.git
+	branch = rustc/10.0-2020-01-18
 [submodule "src/doc/embedded-book"]
 	path = src/doc/embedded-book
 	url = https://github.com/rust-embedded/book.git
diff --git a/config.toml.example b/config.toml.example
index c9e17337ee23f..c8aff4af8ffe3 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -395,6 +395,11 @@
 # rustc to execute.
 #lld = false
 
+# Indicates whether LLD will be used to link Rust crates during bootstrap on
+# supported platforms. The LLD from the bootstrap distribution will be used
+# and not the LLD compiled during the bootstrap.
+#use-lld = false
+
 # Indicates whether some LLVM tools, like llvm-objdump, will be made available in the
 # sysroot.
 #llvm-tools = false
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index a8c00c8c3ca88..daa030c59d641 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -134,6 +134,11 @@ fn main() {
             cmd.arg(format!("-Clinker={}", host_linker));
         }
 
+        // Override linker flavor if necessary.
+        if let Ok(host_linker_flavor) = env::var("RUSTC_HOST_LINKER_FLAVOR") {
+            cmd.arg(format!("-Clinker-flavor={}", host_linker_flavor));
+        }
+
         if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
             if s == "true" {
                 cmd.arg("-C").arg("target-feature=+crt-static");
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 18f6fda760846..083964ff29645 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -692,7 +692,7 @@ impl<'a> Builder<'a> {
         cmd.env_remove("MAKEFLAGS");
         cmd.env_remove("MFLAGS");
 
-        if let Some(linker) = self.linker(compiler.host) {
+        if let Some(linker) = self.linker(compiler.host, true) {
             cmd.env("RUSTC_TARGET_LINKER", linker);
         }
         cmd
@@ -946,10 +946,31 @@ impl<'a> Builder<'a> {
             }
         }
 
-        if let Some(host_linker) = self.linker(compiler.host) {
+        // FIXME: Don't use LLD if we're compiling libtest, since it fails to link it.
+        // See https://github.com/rust-lang/rust/issues/68647.
+        let can_use_lld = mode != Mode::Std;
+
+        // FIXME: The beta compiler doesn't pick the `lld-link` flavor for `*-pc-windows-msvc`
+        // Remove `RUSTC_HOST_LINKER_FLAVOR` when this is fixed
+        let lld_linker_flavor = |linker: &Path, target: Interned<String>| {
+            compiler.stage == 0
+                && linker.file_name() == Some(OsStr::new("rust-lld"))
+                && target.contains("pc-windows-msvc")
+        };
+
+        if let Some(host_linker) = self.linker(compiler.host, can_use_lld) {
+            if lld_linker_flavor(host_linker, compiler.host) {
+                cargo.env("RUSTC_HOST_LINKER_FLAVOR", "lld-link");
+            }
+
             cargo.env("RUSTC_HOST_LINKER", host_linker);
         }
-        if let Some(target_linker) = self.linker(target) {
+
+        if let Some(target_linker) = self.linker(target, can_use_lld) {
+            if lld_linker_flavor(target_linker, target) {
+                rustflags.arg("-Clinker-flavor=lld-link");
+            }
+
             let target = crate::envify(&target);
             cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker);
         }
@@ -1047,6 +1068,9 @@ impl<'a> Builder<'a> {
         }
 
         if let Mode::Rustc | Mode::Codegen = mode {
+            if stage > 0 {
+                rustflags.arg("-Clto=thin");
+            }
             rustflags.arg("-Zunstable-options");
             rustflags.arg("-Wrustc::internal");
         }
@@ -1189,7 +1213,7 @@ impl<'a> Builder<'a> {
         // When we build Rust dylibs they're all intended for intermediate
         // usage, so make sure we pass the -Cprefer-dynamic flag instead of
         // linking all deps statically into the dylib.
-        if let Mode::Std | Mode::Rustc | Mode::Codegen = mode {
+        if let Mode::Std = mode {
             rustflags.arg("-Cprefer-dynamic");
         }
 
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 709cf2908eadf..ac530da3557da 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -82,6 +82,7 @@ pub struct Config {
     pub llvm_use_linker: Option<String>,
     pub llvm_allow_old_toolchain: Option<bool>,
 
+    pub use_lld: bool,
     pub lld_enabled: bool,
     pub lldb_enabled: bool,
     pub llvm_tools_enabled: bool,
@@ -321,6 +322,7 @@ struct Rust {
     save_toolstates: Option<String>,
     codegen_backends: Option<Vec<String>>,
     lld: Option<bool>,
+    use_lld: Option<bool>,
     llvm_tools: Option<bool>,
     lldb: Option<bool>,
     deny_warnings: Option<bool>,
@@ -565,6 +567,7 @@ impl Config {
             if let Some(true) = rust.incremental {
                 config.incremental = true;
             }
+            set(&mut config.use_lld, rust.use_lld);
             set(&mut config.lld_enabled, rust.lld);
             set(&mut config.lldb_enabled, rust.lldb);
             set(&mut config.llvm_tools_enabled, rust.llvm_tools);
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 0db4fb3890100..77b80e0f71deb 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -239,9 +239,10 @@ pub struct Build {
     hosts: Vec<Interned<String>>,
     targets: Vec<Interned<String>>,
 
-    // Stage 0 (downloaded) compiler and cargo or their local rust equivalents
+    // Stage 0 (downloaded) compiler, lld and cargo or their local rust equivalents
     initial_rustc: PathBuf,
     initial_cargo: PathBuf,
+    initial_lld: PathBuf,
 
     // Runtime state filled in later on
     // C/C++ compilers and archiver for all targets
@@ -343,9 +344,18 @@ impl Build {
         // we always try to use git for LLVM builds
         let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project"));
 
+        let initial_sysroot = config.initial_rustc.parent().unwrap().parent().unwrap();
+        let initial_lld = initial_sysroot
+            .join("lib")
+            .join("rustlib")
+            .join(config.build)
+            .join("bin")
+            .join("rust-lld");
+
         let mut build = Build {
             initial_rustc: config.initial_rustc.clone(),
             initial_cargo: config.initial_cargo.clone(),
+            initial_lld,
             local_rebuild: config.local_rebuild,
             fail_fast: config.cmd.fail_fast(),
             doc_tests: config.cmd.doc_tests(),
@@ -810,7 +820,7 @@ impl Build {
     }
 
     /// Returns the path to the linker for the given target if it needs to be overridden.
-    fn linker(&self, target: Interned<String>) -> Option<&Path> {
+    fn linker(&self, target: Interned<String>, can_use_lld: bool) -> Option<&Path> {
         if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.as_ref())
         {
             Some(linker)
@@ -819,6 +829,8 @@ impl Build {
             && !target.contains("msvc")
         {
             Some(self.cc(target))
+        } else if can_use_lld && self.config.use_lld && self.build == target {
+            Some(&self.initial_lld)
         } else {
             None
         }
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 8d9e62010015b..0374be1a59889 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -596,7 +596,7 @@ impl Step for RustdocTheme {
             .env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
             .env("RUSTDOC_CRATE_VERSION", builder.rust_version())
             .env("RUSTC_BOOTSTRAP", "1");
-        if let Some(linker) = builder.linker(self.compiler.host) {
+        if let Some(linker) = builder.linker(self.compiler.host, true) {
             cmd.env("RUSTC_TARGET_LINKER", linker);
         }
         try_run(builder, &mut cmd);
@@ -1035,7 +1035,7 @@ impl Step for Compiletest {
         flags.push("-Zunstable-options".to_string());
         flags.push(builder.config.cmd.rustc_args().join(" "));
 
-        if let Some(linker) = builder.linker(target) {
+        if let Some(linker) = builder.linker(target, false) {
             cmd.arg("--linker").arg(linker);
         }
 
@@ -1139,6 +1139,8 @@ impl Step for Compiletest {
             let llvm_config = builder.ensure(native::Llvm { target: builder.config.build });
             if !builder.config.dry_run {
                 let llvm_version = output(Command::new(&llvm_config).arg("--version"));
+                // Remove trailing newline from llvm-config output.
+                let llvm_version = llvm_version.trim_end();
                 cmd.arg("--llvm-version").arg(llvm_version);
             }
             if !builder.is_rust_llvm(target) {
diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml
index b6177b2cc9b25..8f4d9fe8dab81 100644
--- a/src/ci/azure-pipelines/try.yml
+++ b/src/ci/azure-pipelines/try.yml
@@ -14,60 +14,8 @@ jobs:
   - template: steps/run.yml
   strategy:
     matrix:
-      dist-x86_64-linux: {}
-      dist-x86_64-linux-alt:
-        IMAGE: dist-x86_64-linux
-
-# The macOS and Windows builds here are currently disabled due to them not being
-# overly necessary on `try` builds. We also don't actually have anything that
-# consumes the artifacts currently. Perhaps one day we can reenable, but for now
-# it helps free up capacity on Azure.
-# - job: macOS
-#   timeoutInMinutes: 600
-#   pool:
-#     vmImage: macos-10.13
-#   steps:
-#   - template: steps/run.yml
-#   strategy:
-#     matrix:
-#       dist-x86_64-apple:
-#         SCRIPT: ./x.py dist
-#         RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc
-#         DEPLOY: 1
-#         RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-#         MACOSX_DEPLOYMENT_TARGET: 10.7
-#         NO_LLVM_ASSERTIONS: 1
-#         NO_DEBUG_ASSERTIONS: 1
-#         DIST_REQUIRE_ALL_TOOLS: 1
-#
-#       dist-x86_64-apple-alt:
-#         SCRIPT: ./x.py dist
-#         RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc
-#         DEPLOY_ALT: 1
-#         RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-#         MACOSX_DEPLOYMENT_TARGET: 10.7
-#         NO_LLVM_ASSERTIONS: 1
-#         NO_DEBUG_ASSERTIONS: 1
-#
-# - job: Windows
-#   timeoutInMinutes: 600
-#   pool:
-#     vmImage: 'vs2017-win2016'
-#   steps:
-#   - template: steps/run.yml
-#   strategy:
-#     matrix:
-#       dist-x86_64-msvc:
-#         RUST_CONFIGURE_ARGS: >
-#           --build=x86_64-pc-windows-msvc
-#           --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
-#           --enable-full-tools
-#           --enable-profiler
-#         SCRIPT: python x.py dist
-#         DIST_REQUIRE_ALL_TOOLS: 1
-#         DEPLOY: 1
-#
-#       dist-x86_64-msvc-alt:
-#         RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
-#         SCRIPT: python x.py dist
-#         DEPLOY_ALT: 1
+      dist-various-2: {}
+      armhf-gnu: {}
+      arm-android: {}
+      dist-s390x-linux: {}
+      wasm32: {}
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index 7a5966269b301..449000d2b336b 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2018"
 [lib]
 name = "rustc_driver"
 path = "lib.rs"
-crate-type = ["dylib"]
+crate-type = ["rlib"]
 
 [dependencies]
 lazy_static = "1.0"
diff --git a/src/llvm-project b/src/llvm-project
index d7cdb4359223b..5d5c61a326044 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit d7cdb4359223be265da34ebeaa00b92b7c5419fd
+Subproject commit 5d5c61a3260448c9e82a3e6d4eb7e119e468862f
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 4ac7e0e6e1fc0..3a3f900f5e6a8 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -59,7 +59,11 @@ extern "C" void LLVMInitializePasses() {
 }
 
 extern "C" void LLVMTimeTraceProfilerInitialize() {
-#if LLVM_VERSION_GE(9, 0)
+#if LLVM_VERSION_GE(10, 0)
+  timeTraceProfilerInitialize(
+      /* TimeTraceGranularity */ 0,
+      /* ProcName */ "rustc");
+#elif LLVM_VERSION_GE(9, 0)
   timeTraceProfilerInitialize();
 #endif
 }
diff --git a/src/test/codegen/issue-45222.rs b/src/test/codegen/issue-45222.rs
index 7aadc8a095498..4c90952c85853 100644
--- a/src/test/codegen/issue-45222.rs
+++ b/src/test/codegen/issue-45222.rs
@@ -1,5 +1,7 @@
 // compile-flags: -O
 // ignore-debug: the debug assertions get in the way
+// Ignored due to a codegen regression in LLVM 10, see https://bugs.llvm.org/show_bug.cgi?id=44461.
+// ignore-llvm-version: 10.0
 
 #![crate_type = "lib"]
 
diff --git a/src/test/run-make-fulldeps/target-specs/my-awesome-platform.json b/src/test/run-make-fulldeps/target-specs/my-awesome-platform.json
index 8d028280a8da7..00de3de05f07a 100644
--- a/src/test/run-make-fulldeps/target-specs/my-awesome-platform.json
+++ b/src/test/run-make-fulldeps/target-specs/my-awesome-platform.json
@@ -1,5 +1,5 @@
 {
-    "data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
+    "data-layout": "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128",
     "linker-flavor": "gcc",
     "llvm-target": "i686-unknown-linux-gnu",
     "target-endian": "little",
diff --git a/src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json b/src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json
index 48040ae3da0ef..6d5e964ed4fee 100644
--- a/src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json
+++ b/src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json
@@ -1,6 +1,6 @@
 {
     "pre-link-args": {"gcc": ["-m64"]},
-    "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
+    "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
     "linker-flavor": "gcc",
     "llvm-target": "x86_64-unknown-linux-gnu",
     "target-endian": "little",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 555e79d3e065c..4b3b0538d321e 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -191,6 +191,7 @@ impl EarlyProps {
                 return true;
             }
             if let Some(ref actual_version) = config.llvm_version {
+                let actual_version = version_to_int(actual_version);
                 if line.starts_with("min-llvm-version") {
                     let min_version = line
                         .trim_end()
@@ -199,7 +200,7 @@ impl EarlyProps {
                         .expect("Malformed llvm version directive");
                     // Ignore if actual version is smaller the minimum required
                     // version
-                    &actual_version[..] < min_version
+                    actual_version < version_to_int(min_version)
                 } else if line.starts_with("min-system-llvm-version") {
                     let min_version = line
                         .trim_end()
@@ -208,7 +209,7 @@ impl EarlyProps {
                         .expect("Malformed llvm version directive");
                     // Ignore if using system LLVM and actual version
                     // is smaller the minimum required version
-                    config.system_llvm && &actual_version[..] < min_version
+                    config.system_llvm && actual_version < version_to_int(min_version)
                 } else if line.starts_with("ignore-llvm-version") {
                     // Syntax is: "ignore-llvm-version <version1> [- <version2>]"
                     let range_components = line
@@ -219,15 +220,15 @@ impl EarlyProps {
                         .take(3) // 3 or more = invalid, so take at most 3.
                         .collect::<Vec<&str>>();
                     match range_components.len() {
-                        1 => &actual_version[..] == range_components[0],
+                        1 => actual_version == version_to_int(range_components[0]),
                         2 => {
-                            let v_min = range_components[0];
-                            let v_max = range_components[1];
+                            let v_min = version_to_int(range_components[0]);
+                            let v_max = version_to_int(range_components[1]);
                             if v_max < v_min {
                                 panic!("Malformed LLVM version range: max < min")
                             }
                             // Ignore if version lies inside of range.
-                            &actual_version[..] >= v_min && &actual_version[..] <= v_max
+                            actual_version >= v_min && actual_version <= v_max
                         }
                         _ => panic!("Malformed LLVM version directive"),
                     }
@@ -238,6 +239,20 @@ impl EarlyProps {
                 false
             }
         }
+
+        fn version_to_int(version: &str) -> u32 {
+            let version_without_suffix = version.split('-').next().unwrap();
+            let components: Vec<u32> = version_without_suffix
+                .split('.')
+                .map(|s| s.parse().expect("Malformed version component"))
+                .collect();
+            match components.len() {
+                1 => components[0] * 10000,
+                2 => components[0] * 10000 + components[1] * 100,
+                3 => components[0] * 10000 + components[1] * 100 + components[2],
+                _ => panic!("Malformed version"),
+            }
+        }
     }
 }