diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index f3eb1e04d07dc..08c6a951ffb9b 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2485,20 +2485,39 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
         if let LinkerFlavor::Gcc = flavor {
             match ld_impl {
                 LdImpl::Lld => {
-                    let tools_path =
-                        sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
-                    let lld_path = tools_path
-                        .into_iter()
-                        .map(|p| p.join("gcc-ld"))
-                        .find(|p| {
-                            p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()
-                        })
-                        .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found"));
-                    cmd.cmd().arg({
-                        let mut arg = OsString::from("-B");
-                        arg.push(lld_path);
-                        arg
-                    });
+                    if sess.target.lld_flavor == LldFlavor::Ld64 {
+                        let tools_path =
+                            sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
+                        let ld64_exe = tools_path
+                            .into_iter()
+                            .map(|p| p.join("gcc-ld"))
+                            .map(|p| {
+                                p.join(if sess.host.is_like_windows { "ld64.exe" } else { "ld64" })
+                            })
+                            .find(|p| p.exists())
+                            .unwrap_or_else(|| sess.fatal("rust-lld (as ld64) not found"));
+                        cmd.cmd().arg({
+                            let mut arg = OsString::from("-fuse-ld=");
+                            arg.push(ld64_exe);
+                            arg
+                        });
+                    } else {
+                        let tools_path =
+                            sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
+                        let lld_path = tools_path
+                            .into_iter()
+                            .map(|p| p.join("gcc-ld"))
+                            .find(|p| {
+                                p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" })
+                                    .exists()
+                            })
+                            .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found"));
+                        cmd.cmd().arg({
+                            let mut arg = OsString::from("-B");
+                            arg.push(lld_path);
+                            arg
+                        });
+                    }
                 }
             }
         } else {
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index cff0b3651e170..0a0c548fecd0e 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -1,6 +1,6 @@
 use std::env;
 
-use crate::spec::{FramePointer, SplitDebuginfo, TargetOptions};
+use crate::spec::{FramePointer, LldFlavor, SplitDebuginfo, TargetOptions};
 
 pub fn opts(os: &str) -> TargetOptions {
     // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
@@ -35,6 +35,7 @@ pub fn opts(os: &str) -> TargetOptions {
         abi_return_struct_as_int: true,
         emit_debug_gdb_scripts: false,
         eh_frame_header: false,
+        lld_flavor: LldFlavor::Ld64,
 
         // The historical default for macOS targets is to run `dsymutil` which
         // generates a packed version of debuginfo split from the main file.
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index d25989954783a..2a6a05e8e509d 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -1121,6 +1121,10 @@ impl Step for Assemble {
                 &lld_install.join("bin").join(&src_exe),
                 &gcc_ld_dir.join(exe("ld", target_compiler.host)),
             );
+            builder.copy(
+                &lld_install.join("bin").join(&src_exe),
+                &gcc_ld_dir.join(exe("ld64", target_compiler.host)),
+            );
         }
 
         // Similarly, copy `llvm-dwp` into libdir for Split DWARF. Only copy it when the LLVM
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 64075e18366bf..d0bcdb179e39d 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -412,6 +412,8 @@ impl Step for Rustc {
                 let gcc_lld_dir = dst_dir.join("gcc-ld");
                 t!(fs::create_dir(&gcc_lld_dir));
                 builder.copy(&src_dir.join(&rust_lld), &gcc_lld_dir.join(exe("ld", compiler.host)));
+                builder
+                    .copy(&src_dir.join(&rust_lld), &gcc_lld_dir.join(exe("ld64", compiler.host)));
             }
 
             // Copy over llvm-dwp if it's there