about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs114
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs205
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs17
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs59
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs162
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs33
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs12
8 files changed, 282 insertions, 339 deletions
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index caf16c1939d..8b696dc6fba 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -7,16 +7,13 @@ use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 
-use rustc_ast::LlvmAsmDialect;
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_codegen_ssa::mir::operand::OperandValue;
-use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_hir as hir;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::{bug, span_bug, ty::Instance};
-use rustc_span::{Pos, Span, Symbol};
+use rustc_span::{Pos, Span};
 use rustc_target::abi::*;
 use rustc_target::asm::*;
 
@@ -24,100 +21,6 @@ use libc::{c_char, c_uint};
 use tracing::debug;
 
 impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
-    fn codegen_llvm_inline_asm(
-        &mut self,
-        ia: &hir::LlvmInlineAsmInner,
-        outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
-        mut inputs: Vec<&'ll Value>,
-        span: Span,
-    ) -> bool {
-        let mut ext_constraints = vec![];
-        let mut output_types = vec![];
-
-        // Prepare the output operands
-        let mut indirect_outputs = vec![];
-        for (i, (out, &place)) in ia.outputs.iter().zip(&outputs).enumerate() {
-            if out.is_rw {
-                let operand = self.load_operand(place);
-                if let OperandValue::Immediate(_) = operand.val {
-                    inputs.push(operand.immediate());
-                }
-                ext_constraints.push(i.to_string());
-            }
-            if out.is_indirect {
-                let operand = self.load_operand(place);
-                if let OperandValue::Immediate(_) = operand.val {
-                    indirect_outputs.push(operand.immediate());
-                }
-            } else {
-                output_types.push(place.layout.llvm_type(self.cx));
-            }
-        }
-        if !indirect_outputs.is_empty() {
-            indirect_outputs.extend_from_slice(&inputs);
-            inputs = indirect_outputs;
-        }
-
-        let clobbers = ia.clobbers.iter().map(|s| format!("~{{{}}}", &s));
-
-        // Default per-arch clobbers
-        // Basically what clang does
-        let arch_clobbers = match &self.sess().target.arch[..] {
-            "x86" | "x86_64" => &["~{dirflag}", "~{fpsr}", "~{flags}"][..],
-            "mips" | "mips64" => &["~{$1}"],
-            _ => &[],
-        };
-
-        let all_constraints = ia
-            .outputs
-            .iter()
-            .map(|out| out.constraint.to_string())
-            .chain(ia.inputs.iter().map(|s| s.to_string()))
-            .chain(ext_constraints)
-            .chain(clobbers)
-            .chain(arch_clobbers.iter().map(|s| (*s).to_string()))
-            .collect::<Vec<String>>()
-            .join(",");
-
-        debug!("Asm Constraints: {}", &all_constraints);
-
-        // Depending on how many outputs we have, the return type is different
-        let num_outputs = output_types.len();
-        let output_type = match num_outputs {
-            0 => self.type_void(),
-            1 => output_types[0],
-            _ => self.type_struct(&output_types, false),
-        };
-
-        let asm = ia.asm.as_str();
-        let r = inline_asm_call(
-            self,
-            &asm,
-            &all_constraints,
-            &inputs,
-            output_type,
-            ia.volatile,
-            ia.alignstack,
-            ia.dialect,
-            &[span],
-            false,
-            None,
-        );
-        if r.is_none() {
-            return false;
-        }
-        let r = r.unwrap();
-
-        // Again, based on how many outputs we have
-        let outputs = ia.outputs.iter().zip(&outputs).filter(|&(o, _)| !o.is_indirect);
-        for (i, (_, &place)) in outputs.enumerate() {
-            let v = if num_outputs == 1 { r } else { self.extract_value(r, i as u64) };
-            OperandValue::Immediate(v).store(self, place);
-        }
-
-        true
-    }
-
     fn codegen_inline_asm(
         &mut self,
         template: &[InlineAsmTemplatePiece],
@@ -142,9 +45,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                         for &(_, feature) in reg_class.supported_types(asm_arch) {
                             if let Some(feature) = feature {
                                 let codegen_fn_attrs = self.tcx.codegen_fn_attrs(instance.def_id());
-                                let feature_name = Symbol::intern(feature);
-                                if self.tcx.sess.target_features.contains(&feature_name)
-                                    || codegen_fn_attrs.target_features.contains(&feature_name)
+                                if self.tcx.sess.target_features.contains(&feature)
+                                    || codegen_fn_attrs.target_features.contains(&feature)
                                 {
                                     return true;
                                 }
@@ -349,9 +251,9 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             InlineAsmArch::X86 | InlineAsmArch::X86_64
                 if !options.contains(InlineAsmOptions::ATT_SYNTAX) =>
             {
-                LlvmAsmDialect::Intel
+                llvm::AsmDialect::Intel
             }
-            _ => LlvmAsmDialect::Att,
+            _ => llvm::AsmDialect::Att,
         };
         let result = inline_asm_call(
             self,
@@ -455,7 +357,7 @@ pub(crate) fn inline_asm_call<'ll>(
     output: &'ll llvm::Type,
     volatile: bool,
     alignstack: bool,
-    dia: LlvmAsmDialect,
+    dia: llvm::AsmDialect,
     line_spans: &[Span],
     unwind: bool,
     dest_catch_funclet: Option<(
@@ -498,7 +400,7 @@ pub(crate) fn inline_asm_call<'ll>(
                 cons.len(),
                 volatile,
                 alignstack,
-                llvm::AsmDialect::from_generic(dia),
+                dia,
                 can_throw,
             );
 
@@ -522,7 +424,7 @@ pub(crate) fn inline_asm_call<'ll>(
             // we just encode the start position of each line.
             // FIXME: Figure out a way to pass the entire line spans.
             let mut srcloc = vec![];
-            if dia == LlvmAsmDialect::Intel && line_spans.len() > 1 {
+            if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
                 // LLVM inserts an extra line to add the ".intel_syntax", so add
                 // a dummy srcloc entry for it.
                 //
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 2fb5a0f9faf..5703a72c686 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -1,6 +1,7 @@
 //! A helper class for dealing with static archives
 
-use std::ffi::{CStr, CString};
+use std::env;
+use std::ffi::{CStr, CString, OsString};
 use std::io;
 use std::mem;
 use std::path::{Path, PathBuf};
@@ -158,54 +159,127 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
             output_path.with_extension("lib")
         };
 
-        // we've checked for \0 characters in the library name already
-        let dll_name_z = CString::new(lib_name).unwrap();
-        // All import names are Rust identifiers and therefore cannot contain \0 characters.
-        // FIXME: when support for #[link_name] implemented, ensure that import.name values don't
-        // have any \0 characters
-        let import_name_and_ordinal_vector: Vec<(CString, Option<u16>)> = dll_imports
+        let mingw_gnu_toolchain = self.config.sess.target.llvm_target.ends_with("pc-windows-gnu");
+
+        let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = dll_imports
             .iter()
             .map(|import: &DllImport| {
                 if self.config.sess.target.arch == "x86" {
-                    (LlvmArchiveBuilder::i686_decorated_name(import), import.ordinal)
+                    (
+                        LlvmArchiveBuilder::i686_decorated_name(import, mingw_gnu_toolchain),
+                        import.ordinal,
+                    )
                 } else {
-                    (CString::new(import.name.to_string()).unwrap(), import.ordinal)
+                    (import.name.to_string(), import.ordinal)
                 }
             })
             .collect();
 
-        let output_path_z = rustc_fs_util::path_to_c_string(&output_path);
+        if mingw_gnu_toolchain {
+            // The binutils linker used on -windows-gnu targets cannot read the import
+            // libraries generated by LLVM: in our attempts, the linker produced an .EXE
+            // that loaded but crashed with an AV upon calling one of the imported
+            // functions.  Therefore, use binutils to create the import library instead,
+            // by writing a .DEF file to the temp dir and calling binutils's dlltool.
+            let def_file_path =
+                tmpdir.as_ref().join(format!("{}_imports", lib_name)).with_extension("def");
+
+            let def_file_content = format!(
+                "EXPORTS\n{}",
+                import_name_and_ordinal_vector
+                    .into_iter()
+                    .map(|(name, ordinal)| {
+                        match ordinal {
+                            Some(n) => format!("{} @{} NONAME", name, n),
+                            None => name,
+                        }
+                    })
+                    .collect::<Vec<String>>()
+                    .join("\n")
+            );
 
-        tracing::trace!("invoking LLVMRustWriteImportLibrary");
-        tracing::trace!("  dll_name {:#?}", dll_name_z);
-        tracing::trace!("  output_path {}", output_path.display());
-        tracing::trace!(
-            "  import names: {}",
-            dll_imports.iter().map(|import| import.name.to_string()).collect::<Vec<_>>().join(", "),
-        );
+            match std::fs::write(&def_file_path, def_file_content) {
+                Ok(_) => {}
+                Err(e) => {
+                    self.config.sess.fatal(&format!("Error writing .DEF file: {}", e));
+                }
+            };
 
-        let ffi_exports: Vec<LLVMRustCOFFShortExport> = import_name_and_ordinal_vector
-            .iter()
-            .map(|(name_z, ordinal)| LLVMRustCOFFShortExport::new(name_z.as_ptr(), *ordinal))
-            .collect();
-        let result = unsafe {
-            crate::llvm::LLVMRustWriteImportLibrary(
-                dll_name_z.as_ptr(),
-                output_path_z.as_ptr(),
-                ffi_exports.as_ptr(),
-                ffi_exports.len(),
-                llvm_machine_type(&self.config.sess.target.arch) as u16,
-                !self.config.sess.target.is_like_msvc,
-            )
-        };
+            let dlltool = find_binutils_dlltool(self.config.sess);
+            let result = std::process::Command::new(dlltool)
+                .args([
+                    "-d",
+                    def_file_path.to_str().unwrap(),
+                    "-D",
+                    lib_name,
+                    "-l",
+                    output_path.to_str().unwrap(),
+                ])
+                .output();
+
+            match result {
+                Err(e) => {
+                    self.config.sess.fatal(&format!("Error calling dlltool: {}", e.to_string()));
+                }
+                Ok(output) if !output.status.success() => self.config.sess.fatal(&format!(
+                    "Dlltool could not create import library: {}\n{}",
+                    String::from_utf8_lossy(&output.stdout),
+                    String::from_utf8_lossy(&output.stderr)
+                )),
+                _ => {}
+            }
+        } else {
+            // we've checked for \0 characters in the library name already
+            let dll_name_z = CString::new(lib_name).unwrap();
+
+            let output_path_z = rustc_fs_util::path_to_c_string(&output_path);
+
+            tracing::trace!("invoking LLVMRustWriteImportLibrary");
+            tracing::trace!("  dll_name {:#?}", dll_name_z);
+            tracing::trace!("  output_path {}", output_path.display());
+            tracing::trace!(
+                "  import names: {}",
+                dll_imports
+                    .iter()
+                    .map(|import| import.name.to_string())
+                    .collect::<Vec<_>>()
+                    .join(", "),
+            );
 
-        if result == crate::llvm::LLVMRustResult::Failure {
-            self.config.sess.fatal(&format!(
-                "Error creating import library for {}: {}",
-                lib_name,
-                llvm::last_error().unwrap_or("unknown LLVM error".to_string())
-            ));
-        }
+            // All import names are Rust identifiers and therefore cannot contain \0 characters.
+            // FIXME: when support for #[link_name] is implemented, ensure that the import names
+            // still don't contain any \0 characters.  Also need to check that the names don't
+            // contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
+            // in definition files.
+            let cstring_import_name_and_ordinal_vector: Vec<(CString, Option<u16>)> =
+                import_name_and_ordinal_vector
+                    .into_iter()
+                    .map(|(name, ordinal)| (CString::new(name).unwrap(), ordinal))
+                    .collect();
+
+            let ffi_exports: Vec<LLVMRustCOFFShortExport> = cstring_import_name_and_ordinal_vector
+                .iter()
+                .map(|(name_z, ordinal)| LLVMRustCOFFShortExport::new(name_z.as_ptr(), *ordinal))
+                .collect();
+            let result = unsafe {
+                crate::llvm::LLVMRustWriteImportLibrary(
+                    dll_name_z.as_ptr(),
+                    output_path_z.as_ptr(),
+                    ffi_exports.as_ptr(),
+                    ffi_exports.len(),
+                    llvm_machine_type(&self.config.sess.target.arch) as u16,
+                    !self.config.sess.target.is_like_msvc,
+                )
+            };
+
+            if result == crate::llvm::LLVMRustResult::Failure {
+                self.config.sess.fatal(&format!(
+                    "Error creating import library for {}: {}",
+                    lib_name,
+                    llvm::last_error().unwrap_or("unknown LLVM error".to_string())
+                ));
+            }
+        };
 
         self.add_archive(&output_path, |_| false).unwrap_or_else(|e| {
             self.config.sess.fatal(&format!(
@@ -332,22 +406,61 @@ impl<'a> LlvmArchiveBuilder<'a> {
         }
     }
 
-    fn i686_decorated_name(import: &DllImport) -> CString {
+    fn i686_decorated_name(import: &DllImport, mingw: bool) -> String {
         let name = import.name;
-        // We verified during construction that `name` does not contain any NULL characters, so the
-        // conversion to CString is guaranteed to succeed.
-        CString::new(match import.calling_convention {
-            DllCallingConvention::C => format!("_{}", name),
-            DllCallingConvention::Stdcall(arg_list_size) => format!("_{}@{}", name, arg_list_size),
+        let prefix = if mingw { "" } else { "_" };
+
+        match import.calling_convention {
+            DllCallingConvention::C => format!("{}{}", prefix, name),
+            DllCallingConvention::Stdcall(arg_list_size) => {
+                format!("{}{}@{}", prefix, name, arg_list_size)
+            }
             DllCallingConvention::Fastcall(arg_list_size) => format!("@{}@{}", name, arg_list_size),
             DllCallingConvention::Vectorcall(arg_list_size) => {
                 format!("{}@@{}", name, arg_list_size)
             }
-        })
-        .unwrap()
+        }
     }
 }
 
 fn string_to_io_error(s: String) -> io::Error {
     io::Error::new(io::ErrorKind::Other, format!("bad archive: {}", s))
 }
+
+fn find_binutils_dlltool(sess: &Session) -> OsString {
+    assert!(sess.target.options.is_like_windows && !sess.target.options.is_like_msvc);
+    if let Some(dlltool_path) = &sess.opts.debugging_opts.dlltool {
+        return dlltool_path.clone().into_os_string();
+    }
+
+    let mut tool_name: OsString = if sess.host.arch != sess.target.arch {
+        // We are cross-compiling, so we need the tool with the prefix matching our target
+        if sess.target.arch == "x86" {
+            "i686-w64-mingw32-dlltool"
+        } else {
+            "x86_64-w64-mingw32-dlltool"
+        }
+    } else {
+        // We are not cross-compiling, so we just want `dlltool`
+        "dlltool"
+    }
+    .into();
+
+    if sess.host.options.is_like_windows {
+        // If we're compiling on Windows, add the .exe suffix
+        tool_name.push(".exe");
+    }
+
+    // NOTE: it's not clear how useful it is to explicitly search PATH.
+    for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
+        let full_path = dir.join(&tool_name);
+        if full_path.is_file() {
+            return full_path.into_os_string();
+        }
+    }
+
+    // The user didn't specify the location of the dlltool binary, and we weren't able
+    // to find the appropriate one on the PATH.  Just return the name of the tool
+    // and let the invocation fail with a hopefully useful error message.
+    tool_name
+}
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index ddba43cd1f1..6afa649b6de 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -349,13 +349,6 @@ fn fat_lto(
             );
             save_temp_bitcode(cgcx, &module, "lto.after-restriction");
         }
-
-        if cgcx.no_landing_pads {
-            unsafe {
-                llvm::LLVMRustMarkAllFunctionsNounwind(llmod);
-            }
-            save_temp_bitcode(cgcx, &module, "lto.after-nounwind");
-        }
     }
 
     Ok(LtoModuleCodegen::Fat { module: Some(module), _serialized_bitcode: serialized_bitcode })
@@ -770,16 +763,6 @@ pub unsafe fn optimize_thin_module(
             return Err(write::llvm_err(&diag_handler, msg));
         }
 
-        // Like with "fat" LTO, get some better optimizations if landing pads
-        // are disabled by removing all landing pads.
-        if cgcx.no_landing_pads {
-            let _timer = cgcx
-                .prof
-                .generic_activity_with_arg("LLVM_thin_lto_remove_landing_pads", thin_module.name());
-            llvm::LLVMRustMarkAllFunctionsNounwind(llmod);
-            save_temp_bitcode(cgcx, &module, "thin-lto-after-nounwind");
-        }
-
         // Up next comes the per-module local analyses that we do for Thin LTO.
         // Each of these functions is basically copied from the LLVM
         // implementation and then tailored to suit this implementation. Ideally
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 5217fa2758f..8a9450c20dd 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -731,27 +731,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     }
 
     fn fptoui_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> {
-        if !self.fptoint_sat_broken_in_llvm() {
-            let src_ty = self.cx.val_ty(val);
-            let float_width = self.cx.float_width(src_ty);
-            let int_width = self.cx.int_width(dest_ty);
-            let name = format!("llvm.fptoui.sat.i{}.f{}", int_width, float_width);
-            return Some(self.call_intrinsic(&name, &[val]));
-        }
-
-        None
+        self.fptoint_sat(false, val, dest_ty)
     }
 
     fn fptosi_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> {
-        if !self.fptoint_sat_broken_in_llvm() {
-            let src_ty = self.cx.val_ty(val);
-            let float_width = self.cx.float_width(src_ty);
-            let int_width = self.cx.int_width(dest_ty);
-            let name = format!("llvm.fptosi.sat.i{}.f{}", int_width, float_width);
-            return Some(self.call_intrinsic(&name, &[val]));
-        }
-
-        None
+        self.fptoint_sat(true, val, dest_ty)
     }
 
     fn fptoui(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
@@ -1455,4 +1439,43 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
             _ => false,
         }
     }
+
+    fn fptoint_sat(
+        &mut self,
+        signed: bool,
+        val: &'ll Value,
+        dest_ty: &'ll Type,
+    ) -> Option<&'ll Value> {
+        if !self.fptoint_sat_broken_in_llvm() {
+            let src_ty = self.cx.val_ty(val);
+            let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector
+            {
+                assert_eq!(self.cx.vector_length(src_ty), self.cx.vector_length(dest_ty));
+                (
+                    self.cx.element_type(src_ty),
+                    self.cx.element_type(dest_ty),
+                    Some(self.cx.vector_length(src_ty)),
+                )
+            } else {
+                (src_ty, dest_ty, None)
+            };
+            let float_width = self.cx.float_width(float_ty);
+            let int_width = self.cx.int_width(int_ty);
+
+            let instr = if signed { "fptosi" } else { "fptoui" };
+            let name = if let Some(vector_length) = vector_length {
+                format!(
+                    "llvm.{}.sat.v{}i{}.v{}f{}",
+                    instr, vector_length, int_width, vector_length, float_width
+                )
+            } else {
+                format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width)
+            };
+            let f =
+                self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
+            Some(self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None))
+        } else {
+            None
+        }
+    }
 }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 5c02e3d0fa7..3d5fd2f354e 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -27,18 +27,18 @@ use rustc_fs_util::path_to_c_string;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::bug;
 use rustc_middle::mir::{self, GeneratorLayout};
 use rustc_middle::ty::layout::{self, IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{
     self, AdtKind, GeneratorSubsts, Instance, ParamEnv, Ty, TyCtxt, COMMON_VTABLE_ENTRIES,
 };
-use rustc_middle::{bug, span_bug};
 use rustc_query_system::ich::NodeIdHashingMode;
 use rustc_session::config::{self, DebugInfo};
 use rustc_span::symbol::Symbol;
 use rustc_span::FileNameDisplayPreference;
-use rustc_span::{self, SourceFile, SourceFileHash, Span};
+use rustc_span::{self, SourceFile, SourceFileHash};
 use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, TagEncoding};
 use rustc_target::abi::{Int, Pointer, F32, F64};
 use rustc_target::abi::{Primitive, Size, VariantIdx, Variants};
@@ -381,9 +381,8 @@ fn fixed_vec_metadata<'ll, 'tcx>(
     unique_type_id: UniqueTypeId,
     array_or_slice_type: Ty<'tcx>,
     element_type: Ty<'tcx>,
-    span: Span,
 ) -> MetadataCreationResult<'ll> {
-    let element_type_metadata = type_metadata(cx, element_type, span);
+    let element_type_metadata = type_metadata(cx, element_type);
 
     return_if_metadata_created_in_meantime!(cx, unique_type_id);
 
@@ -416,11 +415,10 @@ fn vec_slice_metadata<'ll, 'tcx>(
     slice_ptr_type: Ty<'tcx>,
     element_type: Ty<'tcx>,
     unique_type_id: UniqueTypeId,
-    span: Span,
 ) -> MetadataCreationResult<'ll> {
     let data_ptr_type = cx.tcx.mk_imm_ptr(element_type);
 
-    let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
+    let data_ptr_metadata = type_metadata(cx, data_ptr_type);
 
     return_if_metadata_created_in_meantime!(cx, unique_type_id);
 
@@ -442,7 +440,7 @@ fn vec_slice_metadata<'ll, 'tcx>(
         },
         MemberDescription {
             name: "length".to_owned(),
-            type_metadata: type_metadata(cx, cx.tcx.types.usize, span),
+            type_metadata: type_metadata(cx, cx.tcx.types.usize),
             offset: pointer_size,
             size: usize_size,
             align: usize_align,
@@ -452,8 +450,6 @@ fn vec_slice_metadata<'ll, 'tcx>(
         },
     ];
 
-    let file_metadata = unknown_file_metadata(cx);
-
     let metadata = composite_type_metadata(
         cx,
         slice_ptr_type,
@@ -461,8 +457,6 @@ fn vec_slice_metadata<'ll, 'tcx>(
         unique_type_id,
         member_descriptions,
         NO_SCOPE_METADATA,
-        file_metadata,
-        span,
     );
     MetadataCreationResult::new(metadata, false)
 }
@@ -471,7 +465,6 @@ fn subroutine_type_metadata<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     unique_type_id: UniqueTypeId,
     signature: ty::PolyFnSig<'tcx>,
-    span: Span,
 ) -> MetadataCreationResult<'ll> {
     let signature =
         cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), signature);
@@ -480,12 +473,12 @@ fn subroutine_type_metadata<'ll, 'tcx>(
         // return type
         match signature.output().kind() {
             ty::Tuple(tys) if tys.is_empty() => None,
-            _ => Some(type_metadata(cx, signature.output(), span)),
+            _ => Some(type_metadata(cx, signature.output())),
         },
     )
     .chain(
         // regular arguments
-        signature.inputs().iter().map(|argument_type| Some(type_metadata(cx, argument_type, span))),
+        signature.inputs().iter().map(|argument_type| Some(type_metadata(cx, argument_type))),
     )
     .collect();
 
@@ -541,8 +534,6 @@ fn trait_pointer_metadata<'ll, 'tcx>(
         None => (NO_SCOPE_METADATA, compute_debuginfo_type_name(cx.tcx, trait_type, true)),
     };
 
-    let file_metadata = unknown_file_metadata(cx);
-
     let layout = cx.layout_of(cx.tcx.mk_mut_ptr(trait_type));
 
     assert_eq!(abi::FAT_PTR_ADDR, 0);
@@ -553,11 +544,7 @@ fn trait_pointer_metadata<'ll, 'tcx>(
     let member_descriptions = vec![
         MemberDescription {
             name: "pointer".to_owned(),
-            type_metadata: type_metadata(
-                cx,
-                cx.tcx.mk_mut_ptr(cx.tcx.types.u8),
-                rustc_span::DUMMY_SP,
-            ),
+            type_metadata: type_metadata(cx, cx.tcx.mk_mut_ptr(cx.tcx.types.u8)),
             offset: layout.fields.offset(0),
             size: data_ptr_field.size,
             align: data_ptr_field.align.abi,
@@ -567,7 +554,7 @@ fn trait_pointer_metadata<'ll, 'tcx>(
         },
         MemberDescription {
             name: "vtable".to_owned(),
-            type_metadata: type_metadata(cx, vtable_field.ty, rustc_span::DUMMY_SP),
+            type_metadata: type_metadata(cx, vtable_field.ty),
             offset: layout.fields.offset(1),
             size: vtable_field.size,
             align: vtable_field.align.abi,
@@ -584,16 +571,10 @@ fn trait_pointer_metadata<'ll, 'tcx>(
         unique_type_id,
         member_descriptions,
         containing_scope,
-        file_metadata,
-        rustc_span::DUMMY_SP,
     )
 }
 
-pub fn type_metadata<'ll, 'tcx>(
-    cx: &CodegenCx<'ll, 'tcx>,
-    t: Ty<'tcx>,
-    usage_site_span: Span,
-) -> &'ll DIType {
+pub fn type_metadata<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
     // Get the unique type ID of this type.
     let unique_type_id = {
         let mut type_map = debug_context(cx).type_map.borrow_mut();
@@ -630,14 +611,14 @@ pub fn type_metadata<'ll, 'tcx>(
     debug!("type_metadata: {:?}", t);
 
     let ptr_metadata = |ty: Ty<'tcx>| match *ty.kind() {
-        ty::Slice(typ) => Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)),
-        ty::Str => Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id, usage_site_span)),
+        ty::Slice(typ) => Ok(vec_slice_metadata(cx, t, typ, unique_type_id)),
+        ty::Str => Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id)),
         ty::Dynamic(..) => Ok(MetadataCreationResult::new(
             trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
             false,
         )),
         _ => {
-            let pointee_metadata = type_metadata(cx, ty, usage_site_span);
+            let pointee_metadata = type_metadata(cx, ty);
 
             if let Some(metadata) =
                 debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id)
@@ -656,10 +637,8 @@ pub fn type_metadata<'ll, 'tcx>(
         ty::Tuple(elements) if elements.is_empty() => {
             MetadataCreationResult::new(basic_type_metadata(cx, t), false)
         }
-        ty::Array(typ, _) | ty::Slice(typ) => {
-            fixed_vec_metadata(cx, unique_type_id, t, typ, usage_site_span)
-        }
-        ty::Str => fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8, usage_site_span),
+        ty::Array(typ, _) | ty::Slice(typ) => fixed_vec_metadata(cx, unique_type_id, t, typ),
+        ty::Str => fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8),
         ty::Dynamic(..) => {
             MetadataCreationResult::new(trait_pointer_metadata(cx, t, None, unique_type_id), false)
         }
@@ -710,8 +689,7 @@ pub fn type_metadata<'ll, 'tcx>(
             type_map.borrow_mut().register_type_with_metadata(t, temp_type);
 
             let fn_metadata =
-                subroutine_type_metadata(cx, unique_type_id, t.fn_sig(cx.tcx), usage_site_span)
-                    .metadata;
+                subroutine_type_metadata(cx, unique_type_id, t.fn_sig(cx.tcx)).metadata;
 
             type_map.borrow_mut().remove_type(t);
 
@@ -721,15 +699,8 @@ pub fn type_metadata<'ll, 'tcx>(
         ty::Closure(def_id, substs) => {
             let upvar_tys: Vec<_> = substs.as_closure().upvar_tys().collect();
             let containing_scope = get_namespace_for_item(cx, def_id);
-            prepare_tuple_metadata(
-                cx,
-                t,
-                &upvar_tys,
-                unique_type_id,
-                usage_site_span,
-                Some(containing_scope),
-            )
-            .finalize(cx)
+            prepare_tuple_metadata(cx, t, &upvar_tys, unique_type_id, Some(containing_scope))
+                .finalize(cx)
         }
         ty::Generator(def_id, substs, _) => {
             let upvar_tys: Vec<_> = substs
@@ -737,25 +708,18 @@ pub fn type_metadata<'ll, 'tcx>(
                 .prefix_tys()
                 .map(|t| cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
                 .collect();
-            prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span, upvar_tys)
-                .finalize(cx)
+            prepare_enum_metadata(cx, t, def_id, unique_type_id, upvar_tys).finalize(cx)
         }
         ty::Adt(def, ..) => match def.adt_kind() {
-            AdtKind::Struct => {
-                prepare_struct_metadata(cx, t, unique_type_id, usage_site_span).finalize(cx)
-            }
-            AdtKind::Union => {
-                prepare_union_metadata(cx, t, unique_type_id, usage_site_span).finalize(cx)
-            }
+            AdtKind::Struct => prepare_struct_metadata(cx, t, unique_type_id).finalize(cx),
+            AdtKind::Union => prepare_union_metadata(cx, t, unique_type_id).finalize(cx),
             AdtKind::Enum => {
-                prepare_enum_metadata(cx, t, def.did, unique_type_id, usage_site_span, vec![])
-                    .finalize(cx)
+                prepare_enum_metadata(cx, t, def.did, unique_type_id, vec![]).finalize(cx)
             }
         },
         ty::Tuple(elements) => {
             let tys: Vec<_> = elements.iter().map(|k| k.expect_ty()).collect();
-            prepare_tuple_metadata(cx, t, &tys, unique_type_id, usage_site_span, NO_SCOPE_METADATA)
-                .finalize(cx)
+            prepare_tuple_metadata(cx, t, &tys, unique_type_id, NO_SCOPE_METADATA).finalize(cx)
         }
         // Type parameters from polymorphized functions.
         ty::Param(_) => MetadataCreationResult::new(param_type_metadata(cx, t), false),
@@ -770,8 +734,7 @@ pub fn type_metadata<'ll, 'tcx>(
             let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
                 Some(metadata) => metadata,
                 None => {
-                    span_bug!(
-                        usage_site_span,
+                    bug!(
                         "expected type metadata for unique \
                                type ID '{}' to already be in \
                                the `debuginfo::TypeMap` but it \
@@ -785,8 +748,7 @@ pub fn type_metadata<'ll, 'tcx>(
             match type_map.find_metadata_for_type(t) {
                 Some(metadata) => {
                     if metadata != metadata_for_uid {
-                        span_bug!(
-                            usage_site_span,
+                        bug!(
                             "mismatch between `Ty` and \
                                    `UniqueTypeId` maps in \
                                    `debuginfo::TypeMap`. \
@@ -1283,7 +1245,6 @@ impl<'ll, 'tcx> MemberDescriptionFactory<'ll, 'tcx> {
 struct StructMemberDescriptionFactory<'tcx> {
     ty: Ty<'tcx>,
     variant: &'tcx ty::VariantDef,
-    span: Span,
 }
 
 impl<'tcx> StructMemberDescriptionFactory<'tcx> {
@@ -1305,7 +1266,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
                 let field = layout.field(cx, i);
                 MemberDescription {
                     name,
-                    type_metadata: type_metadata(cx, field.ty, self.span),
+                    type_metadata: type_metadata(cx, field.ty),
                     offset: layout.fields.offset(i),
                     size: field.size,
                     align: field.align.abi,
@@ -1322,7 +1283,6 @@ fn prepare_struct_metadata<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     struct_type: Ty<'tcx>,
     unique_type_id: UniqueTypeId,
-    span: Span,
 ) -> RecursiveTypeDescription<'ll, 'tcx> {
     let struct_name = compute_debuginfo_type_name(cx.tcx, struct_type, false);
 
@@ -1348,7 +1308,7 @@ fn prepare_struct_metadata<'ll, 'tcx>(
         unique_type_id,
         struct_metadata_stub,
         struct_metadata_stub,
-        StructMDF(StructMemberDescriptionFactory { ty: struct_type, variant, span }),
+        StructMDF(StructMemberDescriptionFactory { ty: struct_type, variant }),
     )
 }
 
@@ -1385,7 +1345,6 @@ fn closure_saved_names_of_captured_variables(tcx: TyCtxt<'_>, def_id: DefId) ->
 struct TupleMemberDescriptionFactory<'tcx> {
     ty: Ty<'tcx>,
     component_types: Vec<Ty<'tcx>>,
-    span: Span,
 }
 
 impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
@@ -1412,7 +1371,7 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
                 };
                 MemberDescription {
                     name,
-                    type_metadata: type_metadata(cx, component_type, self.span),
+                    type_metadata: type_metadata(cx, component_type),
                     offset: layout.fields.offset(i),
                     size,
                     align,
@@ -1430,7 +1389,6 @@ fn prepare_tuple_metadata<'ll, 'tcx>(
     tuple_type: Ty<'tcx>,
     component_types: &[Ty<'tcx>],
     unique_type_id: UniqueTypeId,
-    span: Span,
     containing_scope: Option<&'ll DIScope>,
 ) -> RecursiveTypeDescription<'ll, 'tcx> {
     let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false);
@@ -1453,7 +1411,6 @@ fn prepare_tuple_metadata<'ll, 'tcx>(
         TupleMDF(TupleMemberDescriptionFactory {
             ty: tuple_type,
             component_types: component_types.to_vec(),
-            span,
         }),
     )
 }
@@ -1465,7 +1422,6 @@ fn prepare_tuple_metadata<'ll, 'tcx>(
 struct UnionMemberDescriptionFactory<'tcx> {
     layout: TyAndLayout<'tcx>,
     variant: &'tcx ty::VariantDef,
-    span: Span,
 }
 
 impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
@@ -1481,7 +1437,7 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
                 let field = self.layout.field(cx, i);
                 MemberDescription {
                     name: f.name.to_string(),
-                    type_metadata: type_metadata(cx, field.ty, self.span),
+                    type_metadata: type_metadata(cx, field.ty),
                     offset: Size::ZERO,
                     size: field.size,
                     align: field.align.abi,
@@ -1498,7 +1454,6 @@ fn prepare_union_metadata<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     union_type: Ty<'tcx>,
     unique_type_id: UniqueTypeId,
-    span: Span,
 ) -> RecursiveTypeDescription<'ll, 'tcx> {
     let union_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
 
@@ -1518,7 +1473,7 @@ fn prepare_union_metadata<'ll, 'tcx>(
         unique_type_id,
         union_metadata_stub,
         union_metadata_stub,
-        UnionMDF(UnionMemberDescriptionFactory { layout: cx.layout_of(union_type), variant, span }),
+        UnionMDF(UnionMemberDescriptionFactory { layout: cx.layout_of(union_type), variant }),
     )
 }
 
@@ -1573,7 +1528,6 @@ struct EnumMemberDescriptionFactory<'ll, 'tcx> {
     layout: TyAndLayout<'tcx>,
     tag_type_metadata: Option<&'ll DIType>,
     common_members: Vec<Option<&'ll DIType>>,
-    span: Span,
 }
 
 impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
@@ -1605,7 +1559,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
         // msvc, then we need to use a different, fallback encoding of the debuginfo.
         let fallback = cpp_like_debuginfo(cx.tcx);
         // This will always find the metadata in the type map.
-        let self_metadata = type_metadata(cx, self.enum_type, self.span);
+        let self_metadata = type_metadata(cx, self.enum_type);
 
         match self.layout.variants {
             Variants::Single { index } => {
@@ -1617,7 +1571,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
 
                 let variant_info = variant_info_for(index);
                 let (variant_type_metadata, member_description_factory) =
-                    describe_enum_variant(cx, self.layout, variant_info, self_metadata, self.span);
+                    describe_enum_variant(cx, self.layout, variant_info, self_metadata);
 
                 let member_descriptions = member_description_factory.create_member_descriptions(cx);
 
@@ -1682,13 +1636,8 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
                     .map(|(i, _)| {
                         let variant = self.layout.for_variant(cx, i);
                         let variant_info = variant_info_for(i);
-                        let (variant_type_metadata, member_desc_factory) = describe_enum_variant(
-                            cx,
-                            variant,
-                            variant_info,
-                            self_metadata,
-                            self.span,
-                        );
+                        let (variant_type_metadata, member_desc_factory) =
+                            describe_enum_variant(cx, variant, variant_info, self_metadata);
 
                         let member_descriptions =
                             member_desc_factory.create_member_descriptions(cx);
@@ -1807,7 +1756,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
                             tag.value.size(cx).bits(),
                             tag.value.align(cx).abi.bits() as u32,
                             create_DIArray(DIB(cx), &tags),
-                            type_metadata(cx, discr_enum_ty, self.span),
+                            type_metadata(cx, discr_enum_ty),
                             true,
                         )
                     };
@@ -1818,7 +1767,6 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
                         dataful_variant_layout,
                         variant_info,
                         self_metadata,
-                        self.span,
                     );
 
                     let member_descriptions = member_desc_factory.create_member_descriptions(cx);
@@ -1864,13 +1812,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
                             let variant = self.layout.for_variant(cx, i);
                             let variant_info = variant_info_for(i);
                             let (variant_type_metadata, member_desc_factory) =
-                                describe_enum_variant(
-                                    cx,
-                                    variant,
-                                    variant_info,
-                                    self_metadata,
-                                    self.span,
-                                );
+                                describe_enum_variant(cx, variant, variant_info, self_metadata);
 
                             let member_descriptions =
                                 member_desc_factory.create_member_descriptions(cx);
@@ -1908,7 +1850,6 @@ struct VariantMemberDescriptionFactory<'tcx> {
     /// Cloned from the `layout::Struct` describing the variant.
     offsets: Vec<Size>,
     args: Vec<(String, Ty<'tcx>)>,
-    span: Span,
 }
 
 impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
@@ -1923,7 +1864,7 @@ impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
                 let (size, align) = cx.size_and_align_of(ty);
                 MemberDescription {
                     name: name.to_string(),
-                    type_metadata: type_metadata(cx, ty, self.span),
+                    type_metadata: type_metadata(cx, ty),
                     offset: self.offsets[i],
                     size,
                     align,
@@ -2011,7 +1952,6 @@ fn describe_enum_variant<'ll, 'tcx>(
     layout: layout::TyAndLayout<'tcx>,
     variant: VariantInfo<'_, 'tcx>,
     containing_scope: &'ll DIScope,
-    span: Span,
 ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) {
     let metadata_stub = variant.map_struct_name(|variant_name| {
         let unique_type_id = debug_context(cx)
@@ -2033,8 +1973,7 @@ fn describe_enum_variant<'ll, 'tcx>(
         .map(|i| (variant.field_name(i), layout.field(cx, i).ty))
         .collect();
 
-    let member_description_factory =
-        VariantMDF(VariantMemberDescriptionFactory { offsets, args, span });
+    let member_description_factory = VariantMDF(VariantMemberDescriptionFactory { offsets, args });
 
     (metadata_stub, member_description_factory)
 }
@@ -2044,7 +1983,6 @@ fn prepare_enum_metadata<'ll, 'tcx>(
     enum_type: Ty<'tcx>,
     enum_def_id: DefId,
     unique_type_id: UniqueTypeId,
-    span: Span,
     outer_field_tys: Vec<Ty<'tcx>>,
 ) -> RecursiveTypeDescription<'ll, 'tcx> {
     let tcx = cx.tcx;
@@ -2109,8 +2047,7 @@ fn prepare_enum_metadata<'ll, 'tcx>(
             Some(discriminant_type_metadata) => discriminant_type_metadata,
             None => {
                 let (discriminant_size, discriminant_align) = (discr.size(cx), discr.align(cx));
-                let discriminant_base_type_metadata =
-                    type_metadata(cx, discr.to_ty(tcx), rustc_span::DUMMY_SP);
+                let discriminant_base_type_metadata = type_metadata(cx, discr.to_ty(tcx));
 
                 let item_name;
                 let discriminant_name = match enum_type.kind() {
@@ -2202,7 +2139,6 @@ fn prepare_enum_metadata<'ll, 'tcx>(
                 layout,
                 tag_type_metadata: discriminant_type_metadata,
                 common_members: vec![],
-                span,
             }),
         );
     }
@@ -2272,11 +2208,8 @@ fn prepare_enum_metadata<'ll, 'tcx>(
     let outer_fields = match layout.variants {
         Variants::Single { .. } => vec![],
         Variants::Multiple { .. } => {
-            let tuple_mdf = TupleMemberDescriptionFactory {
-                ty: enum_type,
-                component_types: outer_field_tys,
-                span,
-            };
+            let tuple_mdf =
+                TupleMemberDescriptionFactory { ty: enum_type, component_types: outer_field_tys };
             tuple_mdf
                 .create_member_descriptions(cx)
                 .into_iter()
@@ -2352,7 +2285,6 @@ fn prepare_enum_metadata<'ll, 'tcx>(
             layout,
             tag_type_metadata: None,
             common_members: outer_fields,
-            span,
         }),
     )
 }
@@ -2368,11 +2300,6 @@ fn composite_type_metadata<'ll, 'tcx>(
     composite_type_unique_id: UniqueTypeId,
     member_descriptions: Vec<MemberDescription<'ll>>,
     containing_scope: Option<&'ll DIScope>,
-
-    // Ignore source location information as long as it
-    // can't be reconstructed for non-local crates.
-    _file_metadata: &'ll DIFile,
-    _definition_span: Span,
 ) -> &'ll DICompositeType {
     // Create the (empty) struct metadata node ...
     let composite_type_metadata = create_struct_stub(
@@ -2450,8 +2377,7 @@ fn compute_type_parameters<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -
                     if let GenericArgKind::Type(ty) = kind.unpack() {
                         let actual_type =
                             cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
-                        let actual_type_metadata =
-                            type_metadata(cx, actual_type, rustc_span::DUMMY_SP);
+                        let actual_type_metadata = type_metadata(cx, actual_type);
                         let name = name.as_str();
                         Some(unsafe {
                             Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
@@ -2593,7 +2519,7 @@ pub fn create_global_var_metadata<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId, g
 
     let is_local_to_unit = is_node_local_to_unit(cx, def_id);
     let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all());
-    let type_metadata = type_metadata(cx, variable_type, span);
+    let type_metadata = type_metadata(cx, variable_type);
     let var_name = tcx.item_name(def_id);
     let var_name = var_name.as_str();
     let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name;
@@ -2648,7 +2574,7 @@ fn vtable_type_metadata<'ll, 'tcx>(
     //        things simple instead of adding some ad-hoc disambiguation scheme.
     let vtable_type = tcx.mk_array(tcx.mk_imm_ptr(tcx.types.unit), vtable_entries.len() as u64);
 
-    type_metadata(cx, vtable_type, rustc_span::DUMMY_SP)
+    type_metadata(cx, vtable_type)
 }
 
 /// Creates debug information for the given vtable, which is for the
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index d1cea147a7a..61e49fab6ff 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -390,7 +390,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             signature.push(if fn_abi.ret.is_ignore() {
                 None
             } else {
-                Some(type_metadata(cx, fn_abi.ret.layout.ty, rustc_span::DUMMY_SP))
+                Some(type_metadata(cx, fn_abi.ret.layout.ty))
             });
 
             // Arguments types
@@ -415,15 +415,11 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                         }
                         _ => t,
                     };
-                    Some(type_metadata(cx, t, rustc_span::DUMMY_SP))
+                    Some(type_metadata(cx, t))
                 }));
             } else {
-                signature.extend(
-                    fn_abi
-                        .args
-                        .iter()
-                        .map(|arg| Some(type_metadata(cx, arg.layout.ty, rustc_span::DUMMY_SP))),
-                );
+                signature
+                    .extend(fn_abi.args.iter().map(|arg| Some(type_metadata(cx, arg.layout.ty))));
             }
 
             create_DIArray(DIB(cx), &signature[..])
@@ -453,8 +449,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                         if let GenericArgKind::Type(ty) = kind.unpack() {
                             let actual_type =
                                 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
-                            let actual_type_metadata =
-                                type_metadata(cx, actual_type, rustc_span::DUMMY_SP);
+                            let actual_type_metadata = type_metadata(cx, actual_type);
                             let name = name.as_str();
                             Some(unsafe {
                                 Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
@@ -509,7 +504,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                             if cx.sess().opts.debuginfo == DebugInfo::Full
                                 && !impl_self_ty.needs_subst()
                             {
-                                Some(type_metadata(cx, impl_self_ty, rustc_span::DUMMY_SP))
+                                Some(type_metadata(cx, impl_self_ty))
                             } else {
                                 Some(namespace::item_namespace(cx, def.did))
                             }
@@ -584,7 +579,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         let loc = self.lookup_debug_loc(span.lo());
         let file_metadata = file_metadata(self, &loc.file);
 
-        let type_metadata = type_metadata(self, variable_type, span);
+        let type_metadata = type_metadata(self, variable_type);
 
         let (argument_index, dwarf_tag) = match variable_kind {
             ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 1e795efa2e1..5adfa18035a 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -7,7 +7,6 @@ use crate::type_of::LayoutLlvmExt;
 use crate::va_arg::emit_va_arg;
 use crate::value::Value;
 
-use rustc_ast as ast;
 use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh};
 use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
@@ -351,7 +350,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     self.type_void(),
                     true,
                     false,
-                    ast::LlvmAsmDialect::Att,
+                    llvm::AsmDialect::Att,
                     &[span],
                     false,
                     None,
@@ -1689,7 +1688,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
     bitwise_red!(simd_reduce_all: vector_reduce_and, true);
     bitwise_red!(simd_reduce_any: vector_reduce_or, true);
 
-    if name == sym::simd_cast {
+    if name == sym::simd_cast || name == sym::simd_as {
         require_simd!(ret_ty, "return");
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
         require!(
@@ -1715,14 +1714,26 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
         let (in_style, in_width) = match in_elem.kind() {
             // vectors of pointer-sized integers should've been
             // disallowed before here, so this unwrap is safe.
-            ty::Int(i) => (Style::Int(true), i.bit_width().unwrap()),
-            ty::Uint(u) => (Style::Int(false), u.bit_width().unwrap()),
+            ty::Int(i) => (
+                Style::Int(true),
+                i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
+            ),
+            ty::Uint(u) => (
+                Style::Int(false),
+                u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
+            ),
             ty::Float(f) => (Style::Float, f.bit_width()),
             _ => (Style::Unsupported, 0),
         };
         let (out_style, out_width) = match out_elem.kind() {
-            ty::Int(i) => (Style::Int(true), i.bit_width().unwrap()),
-            ty::Uint(u) => (Style::Int(false), u.bit_width().unwrap()),
+            ty::Int(i) => (
+                Style::Int(true),
+                i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
+            ),
+            ty::Uint(u) => (
+                Style::Int(false),
+                u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
+            ),
             ty::Float(f) => (Style::Float, f.bit_width()),
             _ => (Style::Unsupported, 0),
         };
@@ -1749,10 +1760,10 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
                 });
             }
             (Style::Float, Style::Int(out_is_signed)) => {
-                return Ok(if out_is_signed {
-                    bx.fptosi(args[0].immediate(), llret_ty)
-                } else {
-                    bx.fptoui(args[0].immediate(), llret_ty)
+                return Ok(match (out_is_signed, name == sym::simd_as) {
+                    (false, false) => bx.fptoui(args[0].immediate(), llret_ty),
+                    (true, false) => bx.fptosi(args[0].immediate(), llret_ty),
+                    (_, true) => bx.cast_float_to_int(out_is_signed, args[0].immediate(), llret_ty),
                 });
             }
             (Style::Float, Style::Float) => {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index f2782f84f55..a1c7d2b4f61 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -423,22 +423,13 @@ pub enum MetadataType {
 }
 
 /// LLVMRustAsmDialect
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
 pub enum AsmDialect {
     Att,
     Intel,
 }
 
-impl AsmDialect {
-    pub fn from_generic(asm: rustc_ast::LlvmAsmDialect) -> Self {
-        match asm {
-            rustc_ast::LlvmAsmDialect::Att => AsmDialect::Att,
-            rustc_ast::LlvmAsmDialect::Intel => AsmDialect::Intel,
-        }
-    }
-}
-
 /// LLVMRustCodeGenOptLevel
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
@@ -2329,7 +2320,6 @@ extern "C" {
     pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
     pub fn LLVMRustAddAlwaysInlinePass(P: &PassManagerBuilder, AddLifetimes: bool);
     pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t);
-    pub fn LLVMRustMarkAllFunctionsNounwind(M: &Module);
 
     pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>;
     pub fn LLVMRustArchiveIteratorNew(AR: &Archive) -> &mut ArchiveIterator<'_>;