about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/session/mod.rs5
-rw-r--r--src/librustc_llvm/ffi.rs1
-rw-r--r--src/librustc_trans/back/lto.rs15
-rw-r--r--src/rustllvm/PassWrapper.cpp15
4 files changed, 32 insertions, 4 deletions
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 0de1c20dbde..54bcc64d068 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -791,10 +791,7 @@ impl Session {
         // As a result 16 was chosen here! Mostly because it was a power of 2
         // and most benchmarks agreed it was roughly a local optimum. Not very
         // scientific.
-        match self.opts.optimize {
-            config::OptLevel::No => 16,
-            _ => 1, // FIXME(#46346) this should be 16
-        }
+        16
     }
 
     /// Returns whether ThinLTO is enabled for this compilation
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index cb385923067..7d653494465 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -1732,4 +1732,5 @@ extern "C" {
                                            CU1: *mut *mut c_void,
                                            CU2: *mut *mut c_void);
     pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void);
+    pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef);
 }
diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs
index ba8c26bc819..29871684092 100644
--- a/src/librustc_trans/back/lto.rs
+++ b/src/librustc_trans/back/lto.rs
@@ -726,6 +726,21 @@ impl ThinModule {
         run_pass_manager(cgcx, tm, llmod, config, true);
         cgcx.save_temp_bitcode(&mtrans, "thin-lto-after-pm");
         timeline.record("thin-done");
+
+        // FIXME: this is a hack around a bug in LLVM right now. Discovered in
+        // #46910 it was found out that on 32-bit MSVC LLVM will hit a codegen
+        // error if there's an available_externally function in the LLVM module.
+        // Typically we don't actually use these functions but ThinLTO makes
+        // heavy use of them when inlining across modules.
+        //
+        // Tracked upstream at https://bugs.llvm.org/show_bug.cgi?id=35736 this
+        // function call (and its definition on the C++ side of things)
+        // shouldn't be necessary eventually and we can safetly delete these few
+        // lines.
+        llvm::LLVMRustThinLTORemoveAvailableExternally(llmod);
+        cgcx.save_temp_bitcode(&mtrans, "thin-lto-after-rm-ae");
+        timeline.record("no-ae");
+
         Ok(mtrans)
     }
 }
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 776e4a3e65a..4e326c9e199 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -1182,6 +1182,15 @@ LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
   MD->addOperand(Unit);
 }
 
+extern "C" void
+LLVMRustThinLTORemoveAvailableExternally(LLVMModuleRef Mod) {
+  Module *M = unwrap(Mod);
+  for (Function &F : M->functions()) {
+    if (F.hasAvailableExternallyLinkage())
+      F.deleteBody();
+  }
+}
+
 #else
 
 extern "C" bool
@@ -1272,4 +1281,10 @@ extern "C" void
 LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod) {
   report_fatal_error("ThinLTO not available");
 }
+
+extern "C" void
+LLVMRustThinLTORemoveAvailableExternally(LLVMModuleRef Mod) {
+  report_fatal_error("ThinLTO not available");
+}
+
 #endif // LLVM_VERSION_GE(4, 0)