From 9e9467adc6736c45326d44ba8f5eb3809e3b9749 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Fri, 24 Jul 2026 19:43:05 +0900 Subject: [PATCH] codegen: handle OperandValue::Uninit in codegen_return_terminator When adding `OperandValue::Uninit` to skip stores for entirely-uninit constants, we missed the `PassMode::Direct | PassMode::Pair` branch of `codegen_return_terminator`, which called `immediate_or_packed_pair` unconditionally. A function directly returning an all-uninit value (e.g. `MaybeUninit::uninit()`) would hit that branch and ICE in `OperandRef::immediate`, as reported against tokio and reduced by tmiasko. --- compiler/rustc_codegen_ssa/src/mir/block.rs | 8 ++++---- tests/codegen-llvm/uninit-return-value.rs | 13 +++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 tests/codegen-llvm/uninit-return-value.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 5d9c1a876f0cb..111604ce1ffc7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -580,10 +580,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { PassMode::Direct(_) | PassMode::Pair(..) => { let op = self.codegen_consume(bx, mir::Place::return_place().as_ref()); - if let Ref(place_val) = op.val { - bx.load_from_place(bx.backend_type(op.layout), place_val) - } else { - op.immediate_or_packed_pair(bx) + match op.val { + Ref(place_val) => bx.load_from_place(bx.backend_type(op.layout), place_val), + Uninit => bx.cx().const_undef(bx.cx().immediate_backend_type(op.layout)), + _ => op.immediate_or_packed_pair(bx), } } diff --git a/tests/codegen-llvm/uninit-return-value.rs b/tests/codegen-llvm/uninit-return-value.rs new file mode 100644 index 0000000000000..3a4debb1d4f78 --- /dev/null +++ b/tests/codegen-llvm/uninit-return-value.rs @@ -0,0 +1,13 @@ +// Regression test for https://github.com/rust-lang/rust/issues/159815 + +#![crate_type = "lib"] + +use std::mem::MaybeUninit; + +// CHECK-LABEL: @f +#[no_mangle] +pub fn f() -> MaybeUninit<*const ()> { + // CHECK: start: + // CHECK-NEXT: ret ptr undef + const { MaybeUninit::uninit() } +}