Skip to content

Commit bc9d559

Browse files
committed
Auto merge of #152864 - TKanX:bugfix/123183-array-cast-abi-noundef, r=RalfJung
perf(codegen): Restore `noundef` On `PassMode::Cast` Args In Rust ABI ### Summary: #### Problem: Small aggregate arguments passed via `PassMode::Cast` in the Rust ABI (e.g. `[u32; 2]` cast to `i64`) are missing `noundef` in the emitted LLVM IR, even when the type contains no uninit bytes: ```rust #[no_mangle] pub fn f(v: [u32; 2]) -> u32 { v[0] } ``` ```llvm ; expected: define i32 @f(i64 noundef %0) ; actual: define i32 @f(i64 %0) ← noundef missing ``` This blocks LLVM from applying optimizations that require value-defined semantics on function arguments. #### Root Cause: `adjust_for_rust_abi` calls `arg.cast_to(Reg::Integer)`, which internally creates a `CastTarget` with `ArgAttributes::new()` — always empty. Any validity attribute that was present before the cast is silently dropped. This affects all `PassMode::Cast` arguments and return values in the Rust ABI: plain arrays, newtype wrappers, and any `BackendRepr::Memory` type small enough to fit in a register. A prior attempt (rust-lang/rust#127210) used `Ty`/`repr` attributes to detect padding. #### Solution: After `adjust_for_rust_abi`, iterate all `PassMode::Cast` args and the return value. For each, call `layout_is_noundef` on the original layout; if it returns `true`, set `NoUndef` on the `CastTarget`'s `attrs`. `layout_is_noundef` uses only the computed layout — `BackendRepr`, `FieldsShape`, `Variants`, `Scalar::is_uninit_valid()` — and never touches `Ty` or repr attributes. **Anything it cannot prove returns `false`.** Covered cases: - `Scalar` / `ScalarPair` (both halves initialized, fields contiguous) - `FieldsShape::Array` (element type recursively uninit-free) - `FieldsShape::Arbitrary` with `Variants::Single` (fields cover `0..size` with no gaps, each recursively uninit-free) — handles newtype wrappers, multi-field structs, single-variant enums, `repr(transparent)`, `repr(C)` wrappers Conservatively excluded with FIXMEs: - Multi-variant enums (per-variant padding analysis needed) - Foreign-ABI casts (cast target may exceed layout size, needs a size guard) ### Changes: - `compiler/rustc_ty_utils/src/abi.rs`: add restoration loop after `adjust_for_rust_abi`; add `layout_is_noundef` and `fields_cover_layout`. - `tests/codegen-llvm/abi-noundef-cast.rs`: new FileCheck test covering arrays, newtype wrappers (`repr(Rust)`, `repr(transparent)`, `repr(C)`), multi-field structs, single-variant enums, return values, and negative cases (`MaybeUninit`, struct with trailing padding). - `tests/codegen-llvm/debuginfo-dse.rs`: update one CHECK pattern — `Aggregate_4xi8` (`struct { i8, i8, i8, i8 }`) now correctly gets `noundef`. Fixes rust-lang/rust#123183. r? @RalfJung
2 parents d68889e + 4673fcf commit bc9d559

File tree

0 file changed

+0
-0
lines changed

    0 file changed

    +0
    -0
    lines changed

    0 commit comments

    Comments
     (0)