From 418900562cb189e68b21acd49116ed8235646578 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 3 Sep 2025 00:05:50 +0200 Subject: [PATCH 1/6] explicitly start `va_list` lifetime --- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 4 ++++ tests/codegen-llvm/c-variadic-lifetime.rs | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/codegen-llvm/c-variadic-lifetime.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 5f6976f5d0051..6492ef73956b0 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -520,7 +520,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { LocalRef::Place(va_list) => { bx.va_end(va_list.val.llval); - // Explicitly end the lifetime of the `va_list`, this matters for LLVM. + // Explicitly end the lifetime of the `va_list`, improves LLVM codegen. bx.lifetime_end(va_list.val.llval, va_list.layout.size); } _ => bug!("C-variadic function must have a `VaList` place"), diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 06873313e2ecd..6b109e8b8e2f4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -438,6 +438,10 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( if fx.fn_abi.c_variadic && arg_index == fx.fn_abi.args.len() { let va_list = PlaceRef::alloca(bx, bx.layout_of(arg_ty)); + + // Explicitly start the lifetime of the `va_list`, improves LLVM codegen. + bx.lifetime_start(va_list.val.llval, va_list.layout.size); + bx.va_start(va_list.val.llval); return LocalRef::Place(va_list); diff --git a/tests/codegen-llvm/c-variadic-lifetime.rs b/tests/codegen-llvm/c-variadic-lifetime.rs new file mode 100644 index 0000000000000..5b2f8af18c817 --- /dev/null +++ b/tests/codegen-llvm/c-variadic-lifetime.rs @@ -0,0 +1,21 @@ +//@ add-core-stubs +//@ compile-flags: -Copt-level=3 +#![feature(c_variadic)] +#![crate_type = "lib"] + +// Check that `%args` explicitly has its lifetime start and end. Being explicit can improve +// instruction and register selection, see e.g. https://github.com/rust-lang/rust/pull/144549 + +#[unsafe(no_mangle)] +unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { + // CHECK: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %args) + // CHECK: call void @llvm.va_start.p0(ptr nonnull %args) + + let b = args.arg::(); + let c = args.arg::(); + + a + b + c + + // CHECK: call void @llvm.va_end.p0(ptr nonnull %args) + // CHECK: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %args) +} From fa9e1f99f42b562117d42a6f86e7744526113c2a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 27 Jul 2025 21:21:07 +0200 Subject: [PATCH 2/6] implement `va_arg` for arm in rustc itself --- compiler/rustc_codegen_llvm/src/va_arg.rs | 15 +++++++++++++ tests/assembly-llvm/c-variadic-arm.rs | 26 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tests/assembly-llvm/c-variadic-arm.rs diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 7eb5d30205887..ab08125217ff5 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -908,6 +908,21 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( ) } "aarch64" => emit_aapcs_va_arg(bx, addr, target_ty), + "arm" => { + // Types wider than 16 bytes are not currently supported. Clang has special logic for + // such types, but `VaArgSafe` is not implemented for any type that is this large. + assert!(bx.cx.size_of(target_ty).bytes() <= 16); + + emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes4, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ) + } "s390x" => emit_s390x_va_arg(bx, addr, target_ty), "powerpc" => emit_powerpc_va_arg(bx, addr, target_ty), "powerpc64" | "powerpc64le" => emit_ptr_va_arg( diff --git a/tests/assembly-llvm/c-variadic-arm.rs b/tests/assembly-llvm/c-variadic-arm.rs new file mode 100644 index 0000000000000..36aecf097c222 --- /dev/null +++ b/tests/assembly-llvm/c-variadic-arm.rs @@ -0,0 +1,26 @@ +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 +//@ only-arm +//@ ignore-thumb +#![no_std] +#![crate_type = "lib"] +#![feature(c_variadic)] + +// Check that the assembly that rustc generates matches what clang emits. + +#[unsafe(no_mangle)] +unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { + // CHECK-LABEL: variadic + // CHECK: sub sp, sp, #12 + + // CHECK: vldr + let b = args.arg::(); + // CHECK: vldr + let c = args.arg::(); + + // CHECK: vadd.f64 + // CHECK: vadd.f64 + a + b + c + + // CHECK: add sp, sp, #12 +} From 4fec3aa2a4e087c981a083dca59e7434cac52625 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Wed, 3 Sep 2025 16:59:03 -0700 Subject: [PATCH 3/6] In the rustc_llvm build script, don't consider arm64* to be 32-bit --- compiler/rustc_llvm/build.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index d01f79dcade0b..804f46374d570 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -254,7 +254,10 @@ fn main() { println!("cargo:rustc-link-lib=kstat"); } - if (target.starts_with("arm") && !target.contains("freebsd") && !target.contains("ohos")) + if (target.starts_with("arm") + && !target.starts_with("arm64") + && !target.contains("freebsd") + && !target.contains("ohos")) || target.starts_with("mips-") || target.starts_with("mipsel-") || target.starts_with("powerpc-") From 91241a1d255bde9d1bc3399c1c1f779bb17f1cfa Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 2 Jul 2025 22:09:46 +0000 Subject: [PATCH 4/6] Ensure indirect is first projection in try_as_place. --- compiler/rustc_mir_transform/src/gvn.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 5a13394543b4a..7f005accc655f 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1654,6 +1654,11 @@ impl<'tcx> VnState<'_, 'tcx> { let place = Place { local, projection: self.tcx.mk_place_elems(projection.as_slice()) }; return Some(place); + } else if projection.last() == Some(&PlaceElem::Deref) { + // `Deref` can only be the first projection in a place. + // If we are here, we failed to find a local, and we already have a `Deref`. + // Trying to add projections will only result in an ill-formed place. + return None; } else if let Value::Projection(pointer, proj) = *self.get(index) && (allow_complex_projection || proj.is_stable_offset()) && let Some(proj) = self.try_as_place_elem(self.ty(index), proj, loc) From 4b5d0e02ca2647bf1efb2ecd3303c21ead64d2ea Mon Sep 17 00:00:00 2001 From: Soroush Mirzaei Date: Sun, 7 Sep 2025 11:14:00 -0400 Subject: [PATCH 5/6] docs(std): add error docs for path canonicalize --- library/std/src/path.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 19663e4a9df62..70ba502d68421 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -3037,6 +3037,14 @@ impl Path { /// /// This is an alias to [`fs::canonicalize`]. /// + /// # Errors + /// + /// This method will return an error in the following situations, but is not + /// limited to just these cases: + /// + /// * `path` does not exist. + /// * A non-final component in path is not a directory. + /// /// # Examples /// /// ```no_run From 02602ef65125ac743cc0a61c5afe7c0c5acbad56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Sun, 7 Sep 2025 18:01:39 +0200 Subject: [PATCH 6/6] Implement 'Sum' and 'Product' for 'f16' and 'f128'; --- library/core/src/iter/traits/accum.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs index 73122369b41dd..3b805139ded17 100644 --- a/library/core/src/iter/traits/accum.rs +++ b/library/core/src/iter/traits/accum.rs @@ -203,7 +203,7 @@ macro_rules! float_sum_product { integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize } saturating_integer_sum_product! { u8 u16 u32 u64 u128 usize } -float_sum_product! { f32 f64 } +float_sum_product! { f16 f32 f64 f128 } #[stable(feature = "iter_arith_traits_result", since = "1.16.0")] impl Sum> for Result