-
-
Notifications
You must be signed in to change notification settings - Fork 15.9k
Performance regression since 1.93 related to MaybeUninit being wrongfully initialized #157743
Copy link
Copy link
Closed
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.Category: This is a bug.P-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant 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 fixesIssue 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.Performance or correctness regression from one stable version to another.
Description
Activity
Metadata
Metadata
Assignees
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.Category: This is a bug.P-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant 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 fixesIssue 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.Performance or correctness regression from one stable version to another.
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
https://godbolt.org/z/KnarEEon8
1.92 generates:
1.93 generates:
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.