about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-02-19 15:02:49 +0100
committerNikita Popov <npopov@redhat.com>2024-04-25 11:43:47 +0900
commit3695af697efa26b0ea3b67739ade3ecc3929154e (patch)
tree0b34ec36942c528246b5f3a85014f6952d8d99c3
parentaa067fb984d36462548bb785da221bfaf38253f0 (diff)
downloadrust-3695af697efa26b0ea3b67739ade3ecc3929154e.tar.gz
rust-3695af697efa26b0ea3b67739ade3ecc3929154e.zip
Set writable and dead_on_unwind attributes for sret arguments
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp10
-rw-r--r--tests/codegen/function-arguments.rs2
-rw-r--r--tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs2
-rw-r--r--tests/codegen/maybeuninit-rvo.rs3
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 f918facc86d..94d67859f2f 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 5509baaa3e9..96265043a1c 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 6d578c97f3f..a493abbbc7e 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 37c2da4c23a..fb5a56155fd 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 468ec0a7753..570d32f78fa 100644
--- a/tests/codegen/function-arguments.rs
+++ b/tests/codegen/function-arguments.rs
@@ -198,7 +198,7 @@ pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> {
   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 c9be4f6d383..d978f2d2525 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 954514c736b..d6b9ee8d11d 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());