Skip to content

Commit 7642ceb

Browse files
Auto merge of #145093 - nikic:dead-on-return, r=<try>
Set dead_on_return attribute for indirect arguments
2 parents 2886b36 + 9c1bbfa commit 7642ceb

File tree

7 files changed

+38
-6
lines changed

7 files changed

+38
-6
lines changed

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::attributes::{self, llfn_attrs_from_instance};
2424
use crate::builder::Builder;
2525
use crate::context::CodegenCx;
2626
use crate::llvm::{self, Attribute, AttributePlace};
27+
use crate::llvm_util;
2728
use crate::type_::Type;
2829
use crate::type_of::LayoutLlvmExt;
2930
use crate::value::Value;
@@ -500,7 +501,16 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
500501
}
501502
}
502503
PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => {
503-
apply(attrs);
504+
let i = apply(attrs);
505+
if cx.sess().opts.optimize != config::OptLevel::No
506+
&& llvm_util::get_version() >= (21, 0, 0)
507+
{
508+
attributes::apply_to_llfn(
509+
llfn,
510+
llvm::AttributePlace::Argument(i),
511+
&[llvm::AttributeKind::DeadOnReturn.create_attr(cx.llcx)],
512+
);
513+
}
504514
}
505515
PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => {
506516
assert!(!on_stack);

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ pub(crate) enum AttributeKind {
249249
FnRetThunkExtern = 41,
250250
Writable = 42,
251251
DeadOnUnwind = 43,
252+
DeadOnReturn = 44,
252253
}
253254

254255
/// LLVMIntPredicate

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ enum class LLVMRustAttributeKind {
277277
FnRetThunkExtern = 41,
278278
Writable = 42,
279279
DeadOnUnwind = 43,
280+
DeadOnReturn = 44,
280281
};
281282

282283
static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
@@ -369,6 +370,12 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
369370
return Attribute::Writable;
370371
case LLVMRustAttributeKind::DeadOnUnwind:
371372
return Attribute::DeadOnUnwind;
373+
case LLVMRustAttributeKind::DeadOnReturn:
374+
#if LLVM_VERSION_GE(21, 0)
375+
return Attribute::DeadOnReturn;
376+
#else
377+
report_fatal_error("DeadOnReturn attribute requires LLVM 21 or later");
378+
#endif
372379
}
373380
report_fatal_error("bad LLVMRustAttributeKind");
374381
}

tests/codegen-llvm/addr-of-mutate.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// Test for the absence of `readonly` on the argument when it is mutated via `&raw const`.
66
// See <https://github.com/rust-lang/rust/issues/111502>.
77

8-
// CHECK: i8 @foo(ptr noalias{{( nocapture)?}} noundef align 1{{( captures\(none\))?}} dereferenceable(128) %x)
8+
// CHECK: i8 @foo(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef align 1{{( captures\(none\))?}} dereferenceable(128) %x)
99
#[no_mangle]
1010
pub fn foo(x: [u8; 128]) -> u8 {
1111
let ptr = core::ptr::addr_of!(x).cast_mut();
@@ -15,7 +15,7 @@ pub fn foo(x: [u8; 128]) -> u8 {
1515
x[0]
1616
}
1717

18-
// CHECK: i1 @second(ptr noalias{{( nocapture)?}} noundef align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
18+
// CHECK: i1 @second(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
1919
#[no_mangle]
2020
pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
2121
let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut();
@@ -24,7 +24,7 @@ pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
2424
}
2525

2626
// If going through a deref (and there are no other mutating accesses), then `readonly` is fine.
27-
// CHECK: i1 @third(ptr noalias{{( nocapture)?}} noundef readonly align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
27+
// CHECK: i1 @third(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef readonly align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
2828
#[no_mangle]
2929
pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
3030
let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut();

tests/codegen-llvm/dead_on_return.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ compile-flags: -C opt-level=3
2+
//@ min-llvm-version: 21
3+
4+
#![crate_type = "lib"]
5+
#![allow(unused_assignments, unused_variables)]
6+
7+
// Check that the old string is deallocated, but a new one is not initialized.
8+
#[unsafe(no_mangle)]
9+
pub fn test(mut s: String) {
10+
// CHECK-LABEL: @test
11+
// CHECK: __rust_dealloc
12+
// CHECK-NOT: store
13+
s = String::new();
14+
}

tests/codegen-llvm/function-arguments.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {}
134134
#[no_mangle]
135135
pub fn notunpin_borrow(_: &NotUnpin) {}
136136

137-
// CHECK: @indirect_struct(ptr noalias{{( nocapture)?}} noundef readonly align 4{{( captures\(none\))?}} dereferenceable(32) %_1)
137+
// CHECK: @indirect_struct(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef readonly align 4{{( captures\(none\))?}} dereferenceable(32) %_1)
138138
#[no_mangle]
139139
pub fn indirect_struct(_: S) {}
140140

tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ pub struct IntDoubleInt {
256256
c: i32,
257257
}
258258

259-
// CHECK: define void @f_int_double_int_s_arg(ptr noalias{{( nocapture)?}} noundef align 8{{( captures\(none\))?}} dereferenceable(24) %a)
259+
// CHECK: define void @f_int_double_int_s_arg(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef align 8{{( captures\(none\))?}} dereferenceable(24) %a)
260260
#[no_mangle]
261261
pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
262262

0 commit comments

Comments
 (0)