From 3695af697efa26b0ea3b67739ade3ecc3929154e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 19 Feb 2024 15:02:49 +0100 Subject: [PATCH 1/3] Set writable and dead_on_unwind attributes for sret arguments --- compiler/rustc_codegen_llvm/src/abi.rs | 13 +++++++++++++ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 ++ compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h | 2 ++ compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 10 ++++++++++ tests/codegen/function-arguments.rs | 2 +- .../codegen/loongarch-abi/loongarch64-lp64d-abi.rs | 2 +- tests/codegen/maybeuninit-rvo.rs | 3 ++- 7 files changed, 31 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index f918facc86db1..94d67859f2f30 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -2,6 +2,7 @@ use crate::attributes; use crate::builder::Builder; use crate::context::CodegenCx; use crate::llvm::{self, Attribute, AttributePlace}; +use crate::llvm_util; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; @@ -420,6 +421,18 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { cx.type_array(cx.type_i8(), self.ret.layout.size.bytes()), ); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]); + if cx.sess().opts.optimize != config::OptLevel::No + && llvm_util::get_version() >= (18, 0, 0) + { + attributes::apply_to_llfn( + llfn, + llvm::AttributePlace::Argument(i), + &[ + llvm::AttributeKind::Writable.create_attr(cx.llcx), + llvm::AttributeKind::DeadOnUnwind.create_attr(cx.llcx), + ], + ); + } } PassMode::Cast { cast, pad_i32: _ } => { cast.attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 5509baaa3e94c..96265043a1cc2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -200,6 +200,8 @@ pub enum AttributeKind { AllocAlign = 39, SanitizeSafeStack = 40, FnRetThunkExtern = 41, + Writable = 42, + DeadOnUnwind = 43, } /// LLVMIntPredicate diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h index 6d578c97f3fe1..a493abbbc7e5a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h +++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h @@ -91,6 +91,8 @@ enum LLVMRustAttribute { AllocAlign = 39, SanitizeSafeStack = 40, FnRetThunkExtern = 41, + Writable = 42, + DeadOnUnwind = 43, }; typedef struct OpaqueRustString *RustStringRef; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 37c2da4c23a1a..fb5a56155fddf 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -312,6 +312,16 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) { return Attribute::SafeStack; case FnRetThunkExtern: return Attribute::FnRetThunkExtern; +#if LLVM_VERSION_GE(18, 0) + case Writable: + return Attribute::Writable; + case DeadOnUnwind: + return Attribute::DeadOnUnwind; +#else + case Writable: + case DeadOnUnwind: + report_fatal_error("Not supported on this LLVM version"); +#endif } report_fatal_error("bad AttributeKind"); } diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs index 468ec0a77533b..570d32f78faa4 100644 --- a/tests/codegen/function-arguments.rs +++ b/tests/codegen/function-arguments.rs @@ -198,7 +198,7 @@ pub fn notunpin_box(x: Box) -> Box { x } -// CHECK: @struct_return(ptr noalias nocapture noundef sret([32 x i8]) align 4 dereferenceable(32){{( %_0)?}}) +// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias nocapture noundef{{( writable)?}} sret([32 x i8]) align 4 dereferenceable(32){{( %_0)?}}) #[no_mangle] pub fn struct_return() -> S { S { diff --git a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs index c9be4f6d383a9..d978f2d252541 100644 --- a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs +++ b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs @@ -260,7 +260,7 @@ pub struct IntDoubleInt { #[no_mangle] pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {} -// CHECK: define void @f_ret_int_double_int_s(ptr noalias nocapture noundef sret([24 x i8]) align 8 dereferenceable(24) %_0) +// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias nocapture noundef{{( writable)?}} sret([24 x i8]) align 8 dereferenceable(24) %_0) #[no_mangle] pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt { IntDoubleInt { a: 1, b: 2., c: 3 } diff --git a/tests/codegen/maybeuninit-rvo.rs b/tests/codegen/maybeuninit-rvo.rs index 954514c736bd4..d6b9ee8d11d8b 100644 --- a/tests/codegen/maybeuninit-rvo.rs +++ b/tests/codegen/maybeuninit-rvo.rs @@ -1,4 +1,5 @@ //@ compile-flags: -O +//@ min-llvm-version: 18 #![feature(c_unwind)] #![crate_type = "lib"] @@ -24,7 +25,7 @@ extern "C-unwind" { pub fn new_from_uninit_unwind() -> Foo { // CHECK-LABEL: new_from_uninit - // CHECK: call void @llvm.memcpy. + // CHECK-NOT: call void @llvm.memcpy. let mut x = std::mem::MaybeUninit::uninit(); unsafe { init_unwind(x.as_mut_ptr()); From 137775dd631769bd83c90ec8f12bb17db9e6d411 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 9 Apr 2024 10:05:26 +0900 Subject: [PATCH 2/3] Fix incorrect CHECK-LABEL --- tests/codegen/maybeuninit-rvo.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/codegen/maybeuninit-rvo.rs b/tests/codegen/maybeuninit-rvo.rs index d6b9ee8d11d8b..d21e878c818be 100644 --- a/tests/codegen/maybeuninit-rvo.rs +++ b/tests/codegen/maybeuninit-rvo.rs @@ -24,7 +24,7 @@ extern "C-unwind" { } pub fn new_from_uninit_unwind() -> Foo { - // CHECK-LABEL: new_from_uninit + // CHECK-LABEL: new_from_uninit_unwind // CHECK-NOT: call void @llvm.memcpy. let mut x = std::mem::MaybeUninit::uninit(); unsafe { From 976267b5141ef9a72ba3cb9edf01ca3bc53ec81e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 25 Apr 2024 11:44:32 +0900 Subject: [PATCH 3/3] Add needs-unwind to codegen test When compiled with -C panic=abort we'd generate an extra panic_cannot_unwind shim in the variant calling C-unwind. --- tests/codegen/maybeuninit-rvo.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/codegen/maybeuninit-rvo.rs b/tests/codegen/maybeuninit-rvo.rs index d21e878c818be..cc5da39a9cac8 100644 --- a/tests/codegen/maybeuninit-rvo.rs +++ b/tests/codegen/maybeuninit-rvo.rs @@ -1,4 +1,5 @@ //@ compile-flags: -O +//@ needs-unwind //@ min-llvm-version: 18 #![feature(c_unwind)] #![crate_type = "lib"]