diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 64ebe585dd837..a0bd677fb9f75 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -254,6 +254,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: attributes::emit_uwtable(llfn, true); } + // FIXME: none of these three functions interact with source level attributes. set_frame_pointer_elimination(cx, llfn); set_instrument_function(cx, llfn); set_probestack(cx, llfn); diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 367c1f4811cdb..b26969a50120f 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -14,6 +14,7 @@ use tracing::debug; use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; use rustc_middle::ty::{self, Instance, TypeFoldable}; +use rustc_target::spec::RelocModel; /// Codegens a reference to a fn/method item, monomorphizing and /// inlining as it goes. @@ -170,17 +171,19 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value } } } - } - // MinGW: For backward compatibility we rely on the linker to decide whether it - // should use dllimport for functions. - if cx.use_dll_storage_attrs - && tcx.is_dllimport_foreign_item(instance_def_id) - && tcx.sess.target.env != "gnu" - { - unsafe { + // MinGW: For backward compatibility we rely on the linker to decide whether it + // should use dllimport for functions. + if cx.use_dll_storage_attrs + && tcx.is_dllimport_foreign_item(instance_def_id) + && tcx.sess.target.env != "gnu" + { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); } + + if cx.tcx.sess.relocation_model() == RelocModel::Static { + llvm::LLVMRustSetDSOLocal(llfn, true); + } } llfn diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 82cd1be3b3b45..84d4fbdec34c2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1031,6 +1031,7 @@ extern "C" { pub fn LLVMSetSection(Global: &Value, Section: *const c_char); pub fn LLVMRustGetVisibility(Global: &Value) -> Visibility; pub fn LLVMRustSetVisibility(Global: &Value, Viz: Visibility); + pub fn LLVMRustSetDSOLocal(Global: &Value, is_dso_local: bool); pub fn LLVMGetAlignment(Global: &Value) -> c_uint; pub fn LLVMSetAlignment(Global: &Value, Bytes: c_uint); pub fn LLVMSetDLLStorageClass(V: &Value, C: DLLStorageClass); diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 992e83d08fcae..fc1f364e9c6bc 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -10,7 +10,9 @@ pub use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty::layout::FnAbiExt; use rustc_middle::ty::{self, Instance, TypeFoldable}; +use rustc_session::config::CrateType; use rustc_target::abi::LayoutOf; +use rustc_target::spec::RelocModel; use tracing::debug; impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { @@ -35,6 +37,9 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { unsafe { llvm::LLVMRustSetLinkage(g, base::linkage_to_llvm(linkage)); llvm::LLVMRustSetVisibility(g, base::visibility_to_llvm(visibility)); + if self.should_assume_dso_local(linkage, visibility) { + llvm::LLVMRustSetDSOLocal(g, true); + } } self.instances.borrow_mut().insert(instance, g); @@ -79,6 +84,42 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { attributes::from_fn_attrs(self, lldecl, instance); + unsafe { + if self.should_assume_dso_local(linkage, visibility) { + llvm::LLVMRustSetDSOLocal(lldecl, true); + } + } + self.instances.borrow_mut().insert(instance, lldecl); } } + +impl CodegenCx<'ll, 'tcx> { + /// Whether a definition (NB: not declaration!) can be assumed to be local to a group of + /// libraries that form a single DSO or executable. + pub(crate) unsafe fn should_assume_dso_local( + &self, + linkage: Linkage, + visibility: Visibility, + ) -> bool { + if matches!(linkage, Linkage::Internal | Linkage::Private) { + return true; + } + + if visibility != Visibility::Default && linkage != Linkage::ExternalWeak { + return true; + } + + // Static relocation model should force copy relocations everywhere. + if self.tcx.sess.relocation_model() == RelocModel::Static { + return true; + } + + // Symbols from executables can't really be imported any further. + if self.tcx.sess.crate_types().iter().all(|ty| *ty == CrateType::Executable) { + return true; + } + + return false; + } +} diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 2bb22fd4447fb..d6db69c748fb5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1636,6 +1636,10 @@ extern "C" void LLVMRustSetVisibility(LLVMValueRef V, LLVMSetVisibility(V, fromRust(RustVisibility)); } +extern "C" void LLVMRustSetDSOLocal(LLVMValueRef Global, bool is_dso_local) { + unwrap(Global)->setDSOLocal(is_dso_local); +} + struct LLVMRustModuleBuffer { std::string data; }; diff --git a/src/test/assembly/static-relocation-model.rs b/src/test/assembly/static-relocation-model.rs new file mode 100644 index 0000000000000..0463045c15686 --- /dev/null +++ b/src/test/assembly/static-relocation-model.rs @@ -0,0 +1,44 @@ +// min-llvm-version: 12.0.0 +// needs-llvm-components: aarch64 x86 +// revisions:X64 A64 +// assembly-output: emit-asm +// [X64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=static +// [A64] compile-flags: --target aarch64-unknown-linux-gnu -Crelocation-model=static + +#![feature(no_core, lang_items)] +#![no_core] +#![crate_type="rlib"] + +#[lang="sized"] +trait Sized {} + +#[lang="copy"] +trait Copy {} + +impl Copy for u8 {} + +extern "C" { + fn chaenomeles(); +} + +// CHECK-LABEL: banana: +// x64: movb chaenomeles, %{{[a,z]+}} +// A64: adrp [[REG:[a-z0-9]+]], chaenomeles +// A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG]], :lo12:chaenomeles] +#[no_mangle] +pub fn banana() -> u8 { + unsafe { + *(chaenomeles as *mut u8) + } +} + +// CHECK-LABEL: peach: +// x64: movb banana, %{{[a,z]+}} +// A64: adrp [[REG2:[a-z0-9]+]], banana +// A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:banana] +#[no_mangle] +pub fn peach() -> u8 { + unsafe { + *(banana as *mut u8) + } +} diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs index 6cb2728359b95..613b0bf50e534 100644 --- a/src/test/codegen/abi-efiapi.rs +++ b/src/test/codegen/abi-efiapi.rs @@ -23,8 +23,8 @@ trait Copy { } //x86_64: define win64cc void @has_efiapi //i686: define void @has_efiapi -//aarch64: define void @has_efiapi -//arm: define void @has_efiapi -//riscv: define void @has_efiapi +//aarch64: define dso_local void @has_efiapi +//arm: define dso_local void @has_efiapi +//riscv: define dso_local void @has_efiapi #[no_mangle] pub extern "efiapi" fn has_efiapi() {} diff --git a/src/test/codegen/abi-repr-ext.rs b/src/test/codegen/abi-repr-ext.rs index f93ccd794117d..9dba1718acd8b 100644 --- a/src/test/codegen/abi-repr-ext.rs +++ b/src/test/codegen/abi-repr-ext.rs @@ -6,7 +6,7 @@ pub enum Type { Type2 = 1 } -// CHECK: define signext i8 @test() +// CHECK: define{{( dso_local)?}} signext i8 @test() #[no_mangle] pub extern "C" fn test() -> Type { Type::Type1 diff --git a/src/test/codegen/abi-sysv64.rs b/src/test/codegen/abi-sysv64.rs index 89c9bcee052fb..bb910d573b338 100644 --- a/src/test/codegen/abi-sysv64.rs +++ b/src/test/codegen/abi-sysv64.rs @@ -1,17 +1,21 @@ // Checks if the correct annotation for the sysv64 ABI is passed to // llvm. Also checks that the abi-sysv64 feature gate allows usage // of the sysv64 abi. - -// ignore-arm -// ignore-aarch64 -// ignore-riscv64 sysv64 not supported - -// compile-flags: -C no-prepopulate-passes +// +// needs-llvm-components: x86 +// compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu #![crate_type = "lib"] +#![no_core] +#![feature(abi_x86_interrupt, no_core, lang_items)] + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} // CHECK: define x86_64_sysvcc i64 @has_sysv64_abi #[no_mangle] pub extern "sysv64" fn has_sysv64_abi(a: i64) -> i64 { - a * 2 + a } diff --git a/src/test/codegen/abi-x86-interrupt.rs b/src/test/codegen/abi-x86-interrupt.rs index 25c155c949dcd..119004d261d60 100644 --- a/src/test/codegen/abi-x86-interrupt.rs +++ b/src/test/codegen/abi-x86-interrupt.rs @@ -2,17 +2,20 @@ // llvm. Also checks that the abi_x86_interrupt feature gate allows usage // of the x86-interrupt abi. -// ignore-arm -// ignore-aarch64 -// ignore-riscv64 x86-interrupt is not supported - -// compile-flags: -C no-prepopulate-passes +// needs-llvm-components: x86 +// compile-flags: -C no-prepopulate-passes --target=x86_64-unknown-linux-gnu #![crate_type = "lib"] -#![feature(abi_x86_interrupt)] +#![no_core] +#![feature(abi_x86_interrupt, no_core, lang_items)] + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} // CHECK: define x86_intrcc i64 @has_x86_interrupt_abi #[no_mangle] pub extern "x86-interrupt" fn has_x86_interrupt_abi(a: i64) -> i64 { - a * 2 + a } diff --git a/src/test/codegen/cdylib-external-inline-fns.rs b/src/test/codegen/cdylib-external-inline-fns.rs index 519be6b6a99a4..9118afd43d88b 100644 --- a/src/test/codegen/cdylib-external-inline-fns.rs +++ b/src/test/codegen/cdylib-external-inline-fns.rs @@ -2,42 +2,42 @@ #![crate_type = "cdylib"] -// CHECK: define void @a() +// CHECK: define{{( dso_local)?}} void @a() #[no_mangle] #[inline] pub extern "C" fn a() {} -// CHECK: define void @b() +// CHECK: define{{( dso_local)?}} void @b() #[export_name = "b"] #[inline] pub extern "C" fn b() {} -// CHECK: define void @c() +// CHECK: define{{( dso_local)?}} void @c() #[no_mangle] #[inline] extern "C" fn c() {} -// CHECK: define void @d() +// CHECK: define{{( dso_local)?}} void @d() #[export_name = "d"] #[inline] extern "C" fn d() {} -// CHECK: define void @e() +// CHECK: define{{( dso_local)?}} void @e() #[no_mangle] #[inline(always)] pub extern "C" fn e() {} -// CHECK: define void @f() +// CHECK: define{{( dso_local)?}} void @f() #[export_name = "f"] #[inline(always)] pub extern "C" fn f() {} -// CHECK: define void @g() +// CHECK: define{{( dso_local)?}} void @g() #[no_mangle] #[inline(always)] extern "C" fn g() {} -// CHECK: define void @h() +// CHECK: define{{( dso_local)?}} void @h() #[export_name = "h"] #[inline(always)] extern "C" fn h() {} diff --git a/src/test/codegen/dealloc-no-unwind.rs b/src/test/codegen/dealloc-no-unwind.rs index f047c7a180ce2..3812ef44ff2ac 100644 --- a/src/test/codegen/dealloc-no-unwind.rs +++ b/src/test/codegen/dealloc-no-unwind.rs @@ -1,4 +1,3 @@ -// // no-system-llvm // compile-flags: -O @@ -15,7 +14,7 @@ impl Drop for A { #[no_mangle] pub fn a(a: Box) { - // CHECK-LABEL: define void @a + // CHECK-LABEL: define{{.*}}void @a // CHECK: call void @__rust_dealloc // CHECK-NEXT: call void @foo let _a = A; diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs index 41820b057f1ef..70349b2ec4f6b 100644 --- a/src/test/codegen/external-no-mangle-fns.rs +++ b/src/test/codegen/external-no-mangle-fns.rs @@ -4,30 +4,30 @@ #![crate_type = "lib"] #![no_std] -// CHECK: define void @a() +// CHECK: define{{( dso_local)?}} void @a() #[no_mangle] fn a() {} -// CHECK: define void @b() +// CHECK: define{{( dso_local)?}} void @b() #[no_mangle] pub fn b() {} mod private { - // CHECK: define void @c() + // CHECK: define{{( dso_local)?}} void @c() #[no_mangle] fn c() {} - // CHECK: define void @d() + // CHECK: define{{( dso_local)?}} void @d() #[no_mangle] pub fn d() {} } const HIDDEN: () = { - // CHECK: define void @e() + // CHECK: define{{( dso_local)?}} void @e() #[no_mangle] fn e() {} - // CHECK: define void @f() + // CHECK: define{{( dso_local)?}} void @f() #[no_mangle] pub fn f() {} }; @@ -38,13 +38,13 @@ const HIDDEN: () = { // CHECK-NEXT: define internal #[inline(never)] fn x() { - // CHECK: define void @g() + // CHECK: define{{( dso_local)?}} void @g() #[no_mangle] fn g() { x(); } - // CHECK: define void @h() + // CHECK: define{{( dso_local)?}} void @h() #[no_mangle] pub fn h() {} @@ -54,22 +54,22 @@ fn x() { } } -// CHECK: define void @i() +// CHECK: define{{( dso_local)?}} void @i() #[no_mangle] #[inline] fn i() {} -// CHECK: define void @j() +// CHECK: define{{( dso_local)?}} void @j() #[no_mangle] #[inline] pub fn j() {} -// CHECK: define void @k() +// CHECK: define{{( dso_local)?}} void @k() #[no_mangle] #[inline(always)] fn k() {} -// CHECK: define void @l() +// CHECK: define{{( dso_local)?}} void @l() #[no_mangle] #[inline(always)] pub fn l() {} diff --git a/src/test/codegen/fewer-names.rs b/src/test/codegen/fewer-names.rs index 53a926d49efe7..7307e0379dfa0 100644 --- a/src/test/codegen/fewer-names.rs +++ b/src/test/codegen/fewer-names.rs @@ -7,11 +7,11 @@ #[no_mangle] pub fn sum(x: u32, y: u32) -> u32 { -// YES-LABEL: define i32 @sum(i32 %0, i32 %1) +// YES-LABEL: define{{.*}}i32 @sum(i32 %0, i32 %1) // YES-NEXT: %3 = add i32 %1, %0 // YES-NEXT: ret i32 %3 -// NO-LABEL: define i32 @sum(i32 %x, i32 %y) +// NO-LABEL: define{{.*}}i32 @sum(i32 %x, i32 %y) // NO-NEXT: start: // NO-NEXT: %z = add i32 %y, %x // NO-NEXT: ret i32 %z diff --git a/src/test/codegen/ffi-const.rs b/src/test/codegen/ffi-const.rs index 67baf6fdd3e03..d9cfa5429b5bb 100644 --- a/src/test/codegen/ffi-const.rs +++ b/src/test/codegen/ffi-const.rs @@ -5,7 +5,7 @@ pub fn bar() { unsafe { foo() } } extern "C" { - // CHECK-LABEL: declare void @foo() + // CHECK-LABEL: declare{{.*}}void @foo() // CHECK-SAME: [[ATTRS:#[0-9]+]] // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readnone{{.*}} } #[ffi_const] pub fn foo(); diff --git a/src/test/codegen/ffi-pure.rs b/src/test/codegen/ffi-pure.rs index 3afb0856c9d72..5bdb2ee912a17 100644 --- a/src/test/codegen/ffi-pure.rs +++ b/src/test/codegen/ffi-pure.rs @@ -5,7 +5,7 @@ pub fn bar() { unsafe { foo() } } extern "C" { - // CHECK-LABEL: declare void @foo() + // CHECK-LABEL: declare{{.*}}void @foo() // CHECK-SAME: [[ATTRS:#[0-9]+]] // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readonly{{.*}} } #[ffi_pure] pub fn foo(); diff --git a/src/test/codegen/ffi-returns-twice.rs b/src/test/codegen/ffi-returns-twice.rs index 75301dfd346eb..0fbe03f0bb6f1 100644 --- a/src/test/codegen/ffi-returns-twice.rs +++ b/src/test/codegen/ffi-returns-twice.rs @@ -5,8 +5,7 @@ pub fn bar() { unsafe { foo() } } extern "C" { - // CHECK-LABEL: declare void @foo() - // CHECK-SAME: [[ATTRS:#[0-9]+]] - // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}returns_twice{{.*}} } + // CHECK: declare{{( dso_local)?}} void @foo(){{.*}}[[ATTRS:#[0-9]+]] + // CHECK: attributes [[ATTRS]] = { {{.*}}returns_twice{{.*}} } #[ffi_returns_twice] pub fn foo(); } diff --git a/src/test/codegen/intrinsics/nontemporal.rs b/src/test/codegen/intrinsics/nontemporal.rs index 3a41fb4fab3b7..d13f3e51ba4c7 100644 --- a/src/test/codegen/intrinsics/nontemporal.rs +++ b/src/test/codegen/intrinsics/nontemporal.rs @@ -5,7 +5,7 @@ #[no_mangle] pub fn a(a: &mut u32, b: u32) { - // CHECK-LABEL: define void @a + // CHECK-LABEL: define{{.*}}void @a // CHECK: store i32 %b, i32* %a, align 4, !nontemporal unsafe { std::intrinsics::nontemporal_store(a, b); diff --git a/src/test/codegen/issue-32031.rs b/src/test/codegen/issue-32031.rs index cf672266bc773..82ba325572ab4 100644 --- a/src/test/codegen/issue-32031.rs +++ b/src/test/codegen/issue-32031.rs @@ -5,7 +5,7 @@ #[no_mangle] pub struct F32(f32); -// CHECK: define float @add_newtype_f32(float %a, float %b) +// CHECK: define{{.*}}float @add_newtype_f32(float %a, float %b) #[inline(never)] #[no_mangle] pub fn add_newtype_f32(a: F32, b: F32) -> F32 { @@ -15,7 +15,7 @@ pub fn add_newtype_f32(a: F32, b: F32) -> F32 { #[no_mangle] pub struct F64(f64); -// CHECK: define double @add_newtype_f64(double %a, double %b) +// CHECK: define{{.*}}double @add_newtype_f64(double %a, double %b) #[inline(never)] #[no_mangle] pub fn add_newtype_f64(a: F64, b: F64) -> F64 { diff --git a/src/test/codegen/lto-removes-invokes.rs b/src/test/codegen/lto-removes-invokes.rs index b8f9f36c8e780..3979a97dc01ba 100644 --- a/src/test/codegen/lto-removes-invokes.rs +++ b/src/test/codegen/lto-removes-invokes.rs @@ -10,7 +10,7 @@ fn main() { fn foo() { let _a = Box::new(3); bar(); -// CHECK-LABEL: define void @foo +// CHECK-LABEL: define dso_local void @foo // CHECK: call void @bar } diff --git a/src/test/codegen/naked-functions.rs b/src/test/codegen/naked-functions.rs index 43a6be465bcf8..c8cd69232821e 100644 --- a/src/test/codegen/naked-functions.rs +++ b/src/test/codegen/naked-functions.rs @@ -4,7 +4,7 @@ #![feature(naked_functions)] // CHECK: Function Attrs: naked -// CHECK-NEXT: define void @naked_empty() +// CHECK-NEXT: define{{.*}}void @naked_empty() #[no_mangle] #[naked] pub fn naked_empty() { @@ -15,14 +15,14 @@ pub fn naked_empty() { // CHECK: Function Attrs: naked #[no_mangle] #[naked] -// CHECK-NEXT: define void @naked_with_args(i{{[0-9]+( %a)?}}) +// CHECK-NEXT: define{{.*}}void @naked_with_args(i{{[0-9]+( %a)?}}) pub fn naked_with_args(a: isize) { // CHECK-NEXT: {{.+}}: // CHECK: ret void } // CHECK: Function Attrs: naked -// CHECK-NEXT: define i{{[0-9]+}} @naked_with_return() +// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_return() #[no_mangle] #[naked] pub fn naked_with_return() -> isize { @@ -32,7 +32,7 @@ pub fn naked_with_return() -> isize { } // CHECK: Function Attrs: naked -// CHECK-NEXT: define i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+( %a)?}}) +// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+( %a)?}}) #[no_mangle] #[naked] pub fn naked_with_args_and_return(a: isize) -> isize { diff --git a/src/test/codegen/optimize-attr-1.rs b/src/test/codegen/optimize-attr-1.rs index a8be10ba3ce0a..22abe06e7a9e4 100644 --- a/src/test/codegen/optimize-attr-1.rs +++ b/src/test/codegen/optimize-attr-1.rs @@ -6,7 +6,7 @@ #![feature(optimize_attribute)] #![crate_type="rlib"] -// CHECK-LABEL: define i32 @nothing +// CHECK-LABEL: define{{.*}}i32 @nothing // CHECK-SAME: [[NOTHING_ATTRS:#[0-9]+]] // NO-OPT: ret i32 4 // SIZE-OPT: ret i32 4 @@ -16,7 +16,7 @@ pub fn nothing() -> i32 { 2 + 2 } -// CHECK-LABEL: define i32 @size +// CHECK-LABEL: define{{.*}}i32 @size // CHECK-SAME: [[SIZE_ATTRS:#[0-9]+]] // NO-OPT: ret i32 6 // SIZE-OPT: ret i32 6 @@ -27,7 +27,7 @@ pub fn size() -> i32 { 3 + 3 } -// CHECK-LABEL: define i32 @speed +// CHECK-LABEL: define{{.*}}i32 @speed // NO-OPT-SAME: [[NOTHING_ATTRS]] // SPEED-OPT-SAME: [[NOTHING_ATTRS]] // SIZE-OPT-SAME: [[SPEED_ATTRS:#[0-9]+]] diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs index 847b94fac78ce..4ac637dc6f144 100644 --- a/src/test/codegen/repr-transparent-aggregates-1.rs +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -34,19 +34,19 @@ pub enum TeBigS { Variant(BigS), } -// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], %BigS* [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]]) +// CHECK: define{{.*}}void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], %BigS* [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]]) #[no_mangle] pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} } -// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], %TsBigS* [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]]) +// CHECK: define{{.*}}void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], %TsBigS* [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]]) #[no_mangle] pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } -// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], %TuBigS* [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]]) +// CHECK: define{{.*}}void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], %TuBigS* [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]]) #[no_mangle] pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } -// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]]) +// CHECK: define{{.*}}void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]]) #[no_mangle] pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } @@ -70,18 +70,18 @@ pub enum TeBigU { Variant(BigU), } -// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], %BigU* [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]]) +// CHECK: define{{.*}}void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], %BigU* [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]]) #[no_mangle] pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} } -// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], %TsBigU* [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]]) +// CHECK: define{{.*}}void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], %TsBigU* [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]]) #[no_mangle] pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } -// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], %TuBigU* [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]]) +// CHECK: define{{.*}}void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], %TuBigU* [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]]) #[no_mangle] pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } -// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]]) +// CHECK: define{{.*}}void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]]) #[no_mangle] pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs index 29997313511b2..7add522c15893 100644 --- a/src/test/codegen/repr-transparent.rs +++ b/src/test/codegen/repr-transparent.rs @@ -17,21 +17,21 @@ pub struct Zst2(()); #[repr(transparent)] pub struct F32(f32); -// CHECK: define float @test_F32(float %_1) +// CHECK: define{{.*}}float @test_F32(float %_1) #[no_mangle] pub extern "C" fn test_F32(_: F32) -> F32 { loop {} } #[repr(transparent)] pub struct Ptr(*mut u8); -// CHECK: define i8* @test_Ptr(i8* %_1) +// CHECK: define{{.*}}i8* @test_Ptr(i8* %_1) #[no_mangle] pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { loop {} } #[repr(transparent)] pub struct WithZst(u64, Zst1); -// CHECK: define i64 @test_WithZst(i64 %_1) +// CHECK: define{{.*}}i64 @test_WithZst(i64 %_1) #[no_mangle] pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} } @@ -39,14 +39,14 @@ pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} } pub struct WithZeroSizedArray(*const f32, [i8; 0]); // Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever. -// CHECK: define i32* @test_WithZeroSizedArray(i32* %_1) +// CHECK: define{{.*}}i32* @test_WithZeroSizedArray(i32* %_1) #[no_mangle] pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} } #[repr(transparent)] pub struct Generic(T); -// CHECK: define double @test_Generic(double %_1) +// CHECK: define{{.*}}double @test_Generic(double %_1) #[no_mangle] pub extern "C" fn test_Generic(_: Generic) -> Generic { loop {} } @@ -56,14 +56,14 @@ pub struct GenericPlusZst(T, Zst2); #[repr(u8)] pub enum Bool { True, False, FileNotFound } -// CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %_1) +// CHECK: define{{( dso_local)?}}{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %_1) #[no_mangle] pub extern "C" fn test_Gpz(_: GenericPlusZst) -> GenericPlusZst { loop {} } #[repr(transparent)] pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>); -// CHECK: define i16* @test_LifetimePhantom(i16* %_1) +// CHECK: define{{.*}}i16* @test_LifetimePhantom(i16* %_1) #[no_mangle] pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom) -> LifetimePhantom { loop {} } @@ -73,28 +73,28 @@ pub struct UnitPhantom { val: T, unit: PhantomData } pub struct Px; -// CHECK: define float @test_UnitPhantom(float %_1) +// CHECK: define{{.*}}float @test_UnitPhantom(float %_1) #[no_mangle] pub extern "C" fn test_UnitPhantom(_: UnitPhantom) -> UnitPhantom { loop {} } #[repr(transparent)] pub struct TwoZsts(Zst1, i8, Zst2); -// CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %_1) +// CHECK: define{{( dso_local)?}}{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %_1) #[no_mangle] pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} } #[repr(transparent)] pub struct Nested1(Zst2, Generic); -// CHECK: define double @test_Nested1(double %_1) +// CHECK: define{{.*}}double @test_Nested1(double %_1) #[no_mangle] pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 { loop {} } #[repr(transparent)] pub struct Nested2(Nested1, Zst1); -// CHECK: define double @test_Nested2(double %_1) +// CHECK: define{{.*}}double @test_Nested2(double %_1) #[no_mangle] pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 { loop {} } @@ -104,7 +104,7 @@ struct f32x4(f32, f32, f32, f32); #[repr(transparent)] pub struct Vector(f32x4); -// CHECK: define <4 x float> @test_Vector(<4 x float> %_1) +// CHECK: define{{.*}}<4 x float> @test_Vector(<4 x float> %_1) #[no_mangle] pub extern "C" fn test_Vector(_: Vector) -> Vector { loop {} } @@ -114,7 +114,7 @@ impl Mirror for T { type It = Self; } #[repr(transparent)] pub struct StructWithProjection(::It); -// CHECK: define float @test_Projection(float %_1) +// CHECK: define{{.*}}float @test_Projection(float %_1) #[no_mangle] pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} } @@ -123,7 +123,7 @@ pub enum EnumF32 { Variant(F32) } -// CHECK: define float @test_EnumF32(float %_1) +// CHECK: define{{.*}}float @test_EnumF32(float %_1) #[no_mangle] pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} } @@ -132,7 +132,7 @@ pub enum EnumF32WithZsts { Variant(Zst1, F32, Zst2) } -// CHECK: define float @test_EnumF32WithZsts(float %_1) +// CHECK: define{{.*}}float @test_EnumF32WithZsts(float %_1) #[no_mangle] pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} } @@ -141,7 +141,7 @@ pub union UnionF32 { field: F32, } -// CHECK: define float @test_UnionF32(float %_1) +// CHECK: define{{.*}}float @test_UnionF32(float %_1) #[no_mangle] pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} } @@ -152,7 +152,7 @@ pub union UnionF32WithZsts { zst2: Zst2, } -// CHECK: define float @test_UnionF32WithZsts(float %_1) +// CHECK: define{{.*}}float @test_UnionF32WithZsts(float %_1) #[no_mangle] pub extern "C" fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} } diff --git a/src/test/codegen/sanitizer-recover.rs b/src/test/codegen/sanitizer-recover.rs index 433d32abd37c6..7ce0fa0a20fc2 100644 --- a/src/test/codegen/sanitizer-recover.rs +++ b/src/test/codegen/sanitizer-recover.rs @@ -16,27 +16,27 @@ // MSAN-RECOVER: @__msan_keep_going = weak_odr {{.*}}constant i32 1 // MSAN-RECOVER-LTO: @__msan_keep_going = weak_odr {{.*}}constant i32 1 -// ASAN-LABEL: define i32 @penguin( +// ASAN-LABEL: define dso_local i32 @penguin( // ASAN: call void @__asan_report_load4(i64 %0) // ASAN: unreachable // ASAN: } // -// ASAN-RECOVER-LABEL: define i32 @penguin( +// ASAN-RECOVER-LABEL: define dso_local i32 @penguin( // ASAN-RECOVER: call void @__asan_report_load4_noabort( // ASAN-RECOVER-NOT: unreachable // ASAN: } // -// MSAN-LABEL: define i32 @penguin( +// MSAN-LABEL: define dso_local i32 @penguin( // MSAN: call void @__msan_warning{{(_with_origin_noreturn\(i32 0\)|_noreturn\(\))}} // MSAN: unreachable // MSAN: } // -// MSAN-RECOVER-LABEL: define i32 @penguin( +// MSAN-RECOVER-LABEL: define dso_local i32 @penguin( // MSAN-RECOVER: call void @__msan_warning{{(_with_origin\(i32 0\)|\(\))}} // MSAN-RECOVER-NOT: unreachable // MSAN-RECOVER: } // -// MSAN-RECOVER-LTO-LABEL: define i32 @penguin( +// MSAN-RECOVER-LTO-LABEL: define dso_local i32 @penguin( // MSAN-RECOVER-LTO: call void @__msan_warning{{(_with_origin\(i32 0\)|\(\))}} // MSAN-RECOVER-LTO-NOT: unreachable // MSAN-RECOVER-LTO: } diff --git a/src/test/codegen/scalar-pair-bool.rs b/src/test/codegen/scalar-pair-bool.rs index 4704c8ad797d8..473272158d099 100644 --- a/src/test/codegen/scalar-pair-bool.rs +++ b/src/test/codegen/scalar-pair-bool.rs @@ -2,25 +2,25 @@ #![crate_type = "lib"] -// CHECK: define { i8, i8 } @pair_bool_bool(i1 zeroext %pair.0, i1 zeroext %pair.1) +// CHECK: define{{.*}}{ i8, i8 } @pair_bool_bool(i1 zeroext %pair.0, i1 zeroext %pair.1) #[no_mangle] pub fn pair_bool_bool(pair: (bool, bool)) -> (bool, bool) { pair } -// CHECK: define { i8, i32 } @pair_bool_i32(i1 zeroext %pair.0, i32 %pair.1) +// CHECK: define{{.*}}{ i8, i32 } @pair_bool_i32(i1 zeroext %pair.0, i32 %pair.1) #[no_mangle] pub fn pair_bool_i32(pair: (bool, i32)) -> (bool, i32) { pair } -// CHECK: define { i32, i8 } @pair_i32_bool(i32 %pair.0, i1 zeroext %pair.1) +// CHECK: define{{.*}}{ i32, i8 } @pair_i32_bool(i32 %pair.0, i1 zeroext %pair.1) #[no_mangle] pub fn pair_i32_bool(pair: (i32, bool)) -> (i32, bool) { pair } -// CHECK: define { i8, i8 } @pair_and_or(i1 zeroext %_1.0, i1 zeroext %_1.1) +// CHECK: define{{.*}}{ i8, i8 } @pair_and_or(i1 zeroext %_1.0, i1 zeroext %_1.1) #[no_mangle] pub fn pair_and_or((a, b): (bool, bool)) -> (bool, bool) { // Make sure it can operate directly on the unpacked args @@ -30,7 +30,7 @@ pub fn pair_and_or((a, b): (bool, bool)) -> (bool, bool) { (a && b, a || b) } -// CHECK: define void @pair_branches(i1 zeroext %_1.0, i1 zeroext %_1.1) +// CHECK: define{{.*}}void @pair_branches(i1 zeroext %_1.0, i1 zeroext %_1.1) #[no_mangle] pub fn pair_branches((a, b): (bool, bool)) { // Make sure it can branch directly on the unpacked bool args diff --git a/src/test/codegen/staticlib-external-inline-fns.rs b/src/test/codegen/staticlib-external-inline-fns.rs index 8876ab7376afe..432c063e826e0 100644 --- a/src/test/codegen/staticlib-external-inline-fns.rs +++ b/src/test/codegen/staticlib-external-inline-fns.rs @@ -2,42 +2,42 @@ #![crate_type = "staticlib"] -// CHECK: define void @a() +// CHECK: define{{.*}}void @a() #[no_mangle] #[inline] pub extern "C" fn a() {} -// CHECK: define void @b() +// CHECK: define{{.*}}void @b() #[export_name = "b"] #[inline] pub extern "C" fn b() {} -// CHECK: define void @c() +// CHECK: define{{.*}}void @c() #[no_mangle] #[inline] extern "C" fn c() {} -// CHECK: define void @d() +// CHECK: define{{.*}}void @d() #[export_name = "d"] #[inline] extern "C" fn d() {} -// CHECK: define void @e() +// CHECK: define{{.*}}void @e() #[no_mangle] #[inline(always)] pub extern "C" fn e() {} -// CHECK: define void @f() +// CHECK: define{{.*}}void @f() #[export_name = "f"] #[inline(always)] pub extern "C" fn f() {} -// CHECK: define void @g() +// CHECK: define{{.*}}void @g() #[no_mangle] #[inline(always)] extern "C" fn g() {} -// CHECK: define void @h() +// CHECK: define{{.*}}void @h() #[export_name = "h"] #[inline(always)] extern "C" fn h() {} diff --git a/src/test/codegen/transmute-scalar.rs b/src/test/codegen/transmute-scalar.rs index 78b4aa3fb885d..e9584929f3a9e 100644 --- a/src/test/codegen/transmute-scalar.rs +++ b/src/test/codegen/transmute-scalar.rs @@ -5,7 +5,7 @@ // FIXME(eddyb) all of these tests show memory stores and loads, even after a // scalar `bitcast`, more special-casing is required to remove `alloca` usage. -// CHECK: define i32 @f32_to_bits(float %x) +// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float %x) // CHECK: %2 = bitcast float %x to i32 // CHECK-NEXT: store i32 %2, i32* %0 // CHECK-NEXT: %3 = load i32, i32* %0 @@ -15,7 +15,7 @@ pub fn f32_to_bits(x: f32) -> u32 { unsafe { std::mem::transmute(x) } } -// CHECK: define i8 @bool_to_byte(i1 zeroext %b) +// CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 zeroext %b) // CHECK: %1 = zext i1 %b to i8 // CHECK-NEXT: store i8 %1, i8* %0 // CHECK-NEXT: %2 = load i8, i8* %0 @@ -25,7 +25,7 @@ pub fn bool_to_byte(b: bool) -> u8 { unsafe { std::mem::transmute(b) } } -// CHECK: define zeroext i1 @byte_to_bool(i8 %byte) +// CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8 %byte) // CHECK: %1 = trunc i8 %byte to i1 // CHECK-NEXT: %2 = zext i1 %1 to i8 // CHECK-NEXT: store i8 %2, i8* %0 @@ -37,7 +37,7 @@ pub unsafe fn byte_to_bool(byte: u8) -> bool { std::mem::transmute(byte) } -// CHECK: define i8* @ptr_to_ptr(i16* %p) +// CHECK-LABEL: define{{.*}}i8* @ptr_to_ptr(i16* %p) // CHECK: %2 = bitcast i16* %p to i8* // CHECK-NEXT: store i8* %2, i8** %0 // CHECK-NEXT: %3 = load i8*, i8** %0 @@ -54,7 +54,7 @@ pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 { // Tests below show the non-special-cased behavior (with the possible // future special-cased instructions in the "NOTE(eddyb)" comments). -// CHECK: define [[USIZE:i[0-9]+]] @ptr_to_int(i16* %p) +// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(i16* %p) // NOTE(eddyb) see above, the following two CHECK lines should ideally be this: // %2 = ptrtoint i16* %p to [[USIZE]] @@ -69,7 +69,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize { unsafe { std::mem::transmute(p) } } -// CHECK: define i16* @int_to_ptr([[USIZE]] %i) +// CHECK: define{{.*}}i16* @int_to_ptr([[USIZE]] %i) // NOTE(eddyb) see above, the following two CHECK lines should ideally be this: // %2 = inttoptr [[USIZE]] %i to i16* diff --git a/src/test/codegen/unwind-extern-imports.rs b/src/test/codegen/unwind-extern-imports.rs index a2ba24aca259b..e28397eb1392d 100644 --- a/src/test/codegen/unwind-extern-imports.rs +++ b/src/test/codegen/unwind-extern-imports.rs @@ -6,28 +6,28 @@ extern "C" { // CHECK: Function Attrs:{{.*}}nounwind -// CHECK-NEXT: declare void @extern_fn +// CHECK-NEXT: declare{{.*}}void @extern_fn fn extern_fn(); // CHECK-NOT: Function Attrs:{{.*}}nounwind -// CHECK: declare void @unwinding_extern_fn +// CHECK: declare{{.*}}void @unwinding_extern_fn #[unwind(allowed)] fn unwinding_extern_fn(); // CHECK-NOT: nounwind -// CHECK: declare void @aborting_extern_fn +// CHECK: declare{{.*}}void @aborting_extern_fn #[unwind(aborts)] fn aborting_extern_fn(); // FIXME: we want to have the attribute here } extern "Rust" { // CHECK-NOT: nounwind -// CHECK: declare void @rust_extern_fn +// CHECK: declare{{.*}}void @rust_extern_fn fn rust_extern_fn(); // CHECK-NOT: nounwind -// CHECK: declare void @rust_unwinding_extern_fn +// CHECK: declare{{.*}}void @rust_unwinding_extern_fn #[unwind(allowed)] fn rust_unwinding_extern_fn(); // CHECK-NOT: nounwind -// CHECK: declare void @rust_aborting_extern_fn +// CHECK: declare{{.*}}void @rust_aborting_extern_fn #[unwind(aborts)] fn rust_aborting_extern_fn(); // FIXME: we want to have the attribute here } diff --git a/src/test/codegen/var-names.rs b/src/test/codegen/var-names.rs index 3140a7c6b6cc2..8f1b038708e66 100644 --- a/src/test/codegen/var-names.rs +++ b/src/test/codegen/var-names.rs @@ -2,7 +2,7 @@ #![crate_type = "lib"] -// CHECK-LABEL: define i32 @test(i32 %a, i32 %b) +// CHECK-LABEL: define{{.*}}i32 @test(i32 %a, i32 %b) #[no_mangle] pub fn test(a: u32, b: u32) -> u32 { let c = a + b;