Set writable and dead_on_unwind attributes for sret arguments
This commit is contained in:
parent
aa067fb984
commit
3695af697e
@ -2,6 +2,7 @@
|
|||||||
use crate::builder::Builder;
|
use crate::builder::Builder;
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
use crate::llvm::{self, Attribute, AttributePlace};
|
use crate::llvm::{self, Attribute, AttributePlace};
|
||||||
|
use crate::llvm_util;
|
||||||
use crate::type_::Type;
|
use crate::type_::Type;
|
||||||
use crate::type_of::LayoutLlvmExt;
|
use crate::type_of::LayoutLlvmExt;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
@ -420,6 +421,18 @@ fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
|
|||||||
cx.type_array(cx.type_i8(), self.ret.layout.size.bytes()),
|
cx.type_array(cx.type_i8(), self.ret.layout.size.bytes()),
|
||||||
);
|
);
|
||||||
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]);
|
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: _ } => {
|
PassMode::Cast { cast, pad_i32: _ } => {
|
||||||
cast.attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn);
|
cast.attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn);
|
||||||
|
@ -200,6 +200,8 @@ pub enum AttributeKind {
|
|||||||
AllocAlign = 39,
|
AllocAlign = 39,
|
||||||
SanitizeSafeStack = 40,
|
SanitizeSafeStack = 40,
|
||||||
FnRetThunkExtern = 41,
|
FnRetThunkExtern = 41,
|
||||||
|
Writable = 42,
|
||||||
|
DeadOnUnwind = 43,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LLVMIntPredicate
|
/// LLVMIntPredicate
|
||||||
|
@ -91,6 +91,8 @@ enum LLVMRustAttribute {
|
|||||||
AllocAlign = 39,
|
AllocAlign = 39,
|
||||||
SanitizeSafeStack = 40,
|
SanitizeSafeStack = 40,
|
||||||
FnRetThunkExtern = 41,
|
FnRetThunkExtern = 41,
|
||||||
|
Writable = 42,
|
||||||
|
DeadOnUnwind = 43,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct OpaqueRustString *RustStringRef;
|
typedef struct OpaqueRustString *RustStringRef;
|
||||||
|
@ -312,6 +312,16 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
|
|||||||
return Attribute::SafeStack;
|
return Attribute::SafeStack;
|
||||||
case FnRetThunkExtern:
|
case FnRetThunkExtern:
|
||||||
return Attribute::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");
|
report_fatal_error("bad AttributeKind");
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> {
|
|||||||
x
|
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]
|
#[no_mangle]
|
||||||
pub fn struct_return() -> S {
|
pub fn struct_return() -> S {
|
||||||
S {
|
S {
|
||||||
|
@ -260,7 +260,7 @@ pub struct IntDoubleInt {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
|
pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
|
||||||
IntDoubleInt { a: 1, b: 2., c: 3 }
|
IntDoubleInt { a: 1, b: 2., c: 3 }
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//@ compile-flags: -O
|
//@ compile-flags: -O
|
||||||
|
//@ min-llvm-version: 18
|
||||||
#![feature(c_unwind)]
|
#![feature(c_unwind)]
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ pub fn new_from_uninit() -> Foo {
|
|||||||
|
|
||||||
pub fn new_from_uninit_unwind() -> Foo {
|
pub fn new_from_uninit_unwind() -> Foo {
|
||||||
// CHECK-LABEL: new_from_uninit
|
// CHECK-LABEL: new_from_uninit
|
||||||
// CHECK: call void @llvm.memcpy.
|
// CHECK-NOT: call void @llvm.memcpy.
|
||||||
let mut x = std::mem::MaybeUninit::uninit();
|
let mut x = std::mem::MaybeUninit::uninit();
|
||||||
unsafe {
|
unsafe {
|
||||||
init_unwind(x.as_mut_ptr());
|
init_unwind(x.as_mut_ptr());
|
||||||
|
Loading…
Reference in New Issue
Block a user