Skip to content

Performance regression since 1.93 related to MaybeUninit being wrongfully initialized #157743

Description

@glandium

Since rustc 1.93 (likely #147827), initializing newtype wrapper of a struct that contains an integer type and a MaybeUninit field generates code to initialize the entire struct at -O2, instead of writing only the initialized integer field.

First bad nightly: nightly-2025-11-24 (commit c23ed3e)
Last good nightly: nightly-2025-11-23 (commit 94b49fd)
Still broken as of: 1.98.0-nightly (2026-06-11, LLVM 22.1.6)

Real-world impact: this caused a 22% performance regression in a specific test in the Firefox performance suite, as reported in https://bugzilla.mozilla.org/show_bug.cgi?id=2046376.
The hot call site creates a struct of three empty SmallVecs (from the smallvec crate with the union feature enabled). With rustc 1.93 the hot path now calls memset for 1224-bytes instead of three 8-byte stores.

Minimal reproducer

use std::mem::MaybeUninit;

pub struct Vec { cap: usize, data: MaybeUninit<[u64; 2]> }
pub struct Wrap(Vec);

#[no_mangle]
#[inline(never)]
pub fn make() -> Wrap {
    Wrap(Vec { cap: 0, data: MaybeUninit::uninit() })
}

https://godbolt.org/z/KnarEEon8

1.92 generates:

make:
        movq    %rdi, %rax
        movq    $0, 16(%rdi)
        retq

1.93 generates:

make:
        movq    %rdi, %rax
        xorps   %xmm0, %xmm0
        movups  %xmm0, (%rdi)
        movq    $0, 16(%rdi)
        retq

With larger arrays in the MaybeUninit, more movups happen, up to the point where it may choose to use memset instead.
IOW, 19.3 is initializing the whole struct instead. Without the wrapping, the MaybeUninit is properly not initialized.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.llvm-fixed-upstreamIssue expected to be fixed by the next major LLVM upgrade, or backported fixesregression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions