Skip to content

Mark SimdInto/SimdFrom blanket impls #[inline(always)] - #417

Merged
Shnatsel merged 1 commit into
linebender:mainfrom
Novum:inline-simd-into
Oct 20, 2026
Merged

Shnatsel merged 1 commit into
linebender:mainfrom
Novum:inline-simd-into

Conversation

@Novum

@Novum Novum commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

These impls sit on the return path of nearly every SIMD operation, converting the native register back into the vector type. Unlike every other conversion in the crate they had no inline attribute, so rustc treats them as ordinary generic functions that only get inlined when local ThinLTO runs across codegen units.

That happens in a default release build, so the problem goes unnoticed there. It does not happen with lto = "off", or at opt-level 1, where generic instances are shared across crates. In those builds every operation makes an out-of-line call that is compiled without the caller's target features, so the vector is passed through memory.

In an AVX-512 heavy workload this made those builds about 16x slower than a default release build. With the attributes all builds produce the same inlined code.

These impls sit on the return path of nearly every SIMD operation, converting the native register back into the vector type. Unlike every other conversion in the crate they had no inline attribute, so rustc treats them as ordinary generic functions that only get inlined when local ThinLTO runs across codegen units.

That happens in a default release build, so the problem goes unnoticed there. It does not happen with lto = "off", or at opt-level 1, where generic instances are shared across crates. In those builds every operation makes an out-of-line call that is compiled without the caller's target features, so the vector is passed through memory.

In an AVX-512 heavy workload this made those builds about 16x slower than a default release build. With the attributes all builds produce the same inlined code.

@Shnatsel Shnatsel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default release build uses thin crate-local LTO, unless -C codegen-units=1 is passed, in which case it isn't needed. This form of LTO is specifically compensating for multiple codegen units, and going to cause a lot of inlining issues if disabled. I don't think we should treat it as an optimization target in general.

But these annotations are simple and innocuous enough so I'm happy to merge this.

@Shnatsel
Shnatsel added this pull request to the merge queue Oct 20, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 20, 2026
@Shnatsel
Shnatsel added this pull request to the merge queue Oct 20, 2026
@Novum

Novum commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

Not sure I understand, I was running into this problem without LTO but with opt-level=1. Things were like 20x slower because of the missing inlining here.

This is often done in bigger projects because dev is just way too slow at runtime. So some optimization is enabled.

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 20, 2026
@Shnatsel

Copy link
Copy Markdown
Contributor

Ah, I see. I missed the opt-level=1 part, sorry.

@Shnatsel

Copy link
Copy Markdown
Contributor

Not sure what's up with CI, I will try merging again later in hopes that it's a transient issue with Github.

@Shnatsel
Shnatsel added this pull request to the merge queue Oct 20, 2026
Merged via the queue into linebender:main with commit 14d7c90 Oct 20, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants