Skip to content

Commit 4189005

Browse files
committed
explicitly start va_list lifetime
1 parent 05abce5 commit 4189005

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
520520
LocalRef::Place(va_list) => {
521521
bx.va_end(va_list.val.llval);
522522

523-
// Explicitly end the lifetime of the `va_list`, this matters for LLVM.
523+
// Explicitly end the lifetime of the `va_list`, improves LLVM codegen.
524524
bx.lifetime_end(va_list.val.llval, va_list.layout.size);
525525
}
526526
_ => bug!("C-variadic function must have a `VaList` place"),

compiler/rustc_codegen_ssa/src/mir/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,10 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
438438

439439
if fx.fn_abi.c_variadic && arg_index == fx.fn_abi.args.len() {
440440
let va_list = PlaceRef::alloca(bx, bx.layout_of(arg_ty));
441+
442+
// Explicitly start the lifetime of the `va_list`, improves LLVM codegen.
443+
bx.lifetime_start(va_list.val.llval, va_list.layout.size);
444+
441445
bx.va_start(va_list.val.llval);
442446

443447
return LocalRef::Place(va_list);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ add-core-stubs
2+
//@ compile-flags: -Copt-level=3
3+
#![feature(c_variadic)]
4+
#![crate_type = "lib"]
5+
6+
// Check that `%args` explicitly has its lifetime start and end. Being explicit can improve
7+
// instruction and register selection, see e.g. https://github.com/rust-lang/rust/pull/144549
8+
9+
#[unsafe(no_mangle)]
10+
unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
11+
// CHECK: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %args)
12+
// CHECK: call void @llvm.va_start.p0(ptr nonnull %args)
13+
14+
let b = args.arg::<f64>();
15+
let c = args.arg::<f64>();
16+
17+
a + b + c
18+
19+
// CHECK: call void @llvm.va_end.p0(ptr nonnull %args)
20+
// CHECK: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %args)
21+
}

0 commit comments

Comments
 (0)