Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forbid disabling SSE on x86 targets that have SSE in their "baseline" #133611

Closed
RalfJung opened this issue Nov 29, 2024 · 1 comment · Fixed by #135408
Closed

Forbid disabling SSE on x86 targets that have SSE in their "baseline" #133611

RalfJung opened this issue Nov 29, 2024 · 1 comment · Fixed by #135408
Labels
A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-discussion Category: Discussion or questions that doesn't represent real issues. O-x86_32 Target: x86 processors, 32 bit (like i686-*) (IA-32) O-x86_64 Target: x86-64 processors (like x86_64-*) (also known as amd64 and x64) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@RalfJung
Copy link
Member

RalfJung commented Nov 29, 2024

Passing -Ctarget-feature=-sse on an x86-64 target currently produces an ugly LLVM error.
Doing the same on a x86-32 target leads to unsound floating-point behavior.

Therefore, I think we should deprecate and eventually fully forbid toggling the sse/sse2 target features on x86 targets, except for those targets that do not have these features to begin with (e.g. i586-unknown-linux-gnu).

I am implementing some machinery here that could help with that, but properly implementing this will be tricky since one can also use -Ctarget-cpu to disable these target features.

Once this is implemented, we have some options for improving the Rust ABI on these targets as well:

  • on x86-32, we could use SSE registers to return float values, instead of PassMode::Indirect
  • on all x86 targets, we could pass SIMD vectors of up to 128 bits in registers rather than indirectly

Here, compiler team triage decided "Current Tier 1 x86 targets require SSE-based floats at minimum". The concrete proposal above got MCP'd in rust-lang/compiler-team#808.

Open questions

How do we best implement this? It's non trivial since -Ctarget-cpu can alter the sse/sse2 feature gates, so our usual approach of just checking which target features got toggled with -Ctarget-feature does not work.

To make things worse, the way we control whether sse/sse2 is available in the "basline" is via the base.cpu field, not via the explicit list of target features, so if we want to do things "only if the baseline has SSE", that's non-trivial to implement. Maybe we should just add a bool field to the target spec that directly controls "use SSE registers for Rust ABI" or "requires SSE registers" or so?

Cc @bjorn3 @workingjubilee @Amanieu

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 29, 2024
@jieyouxu jieyouxu added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. O-x86_32 Target: x86 processors, 32 bit (like i686-*) (IA-32) O-x86_64 Target: x86-64 processors (like x86_64-*) (also known as amd64 and x64) C-discussion Category: Discussion or questions that doesn't represent real issues. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Nov 29, 2024
bors added a commit to rust-lang-ci/rust that referenced this issue Jan 5, 2025
…s, r=workingjubilee

Add a notion of "some ABIs require certain target features"

I think I finally found the right shape for the data and checks that I recently added in rust-lang#133099, rust-lang#133417, rust-lang#134337: we have a notion of "this ABI requires the following list of target features, and it is incompatible with the following list of target features". Both `-Ctarget-feature` and `#[target_feature]` are updated to ensure we follow the rules of the ABI.  This removes all the "toggleability" stuff introduced before, though we do keep the notion of a fully "forbidden" target feature -- this is needed to deal with target features that are actual ABI switches, and hence are needed to even compute the list of required target features.

We always explicitly (un)set all required and in-conflict features, just to avoid potential trouble caused by the default features of whatever the base CPU is. We do this *before* applying `-Ctarget-feature` to maintain backward compatibility; this poses a slight risk of missing some implicit feature dependencies in LLVM but has the advantage of not breaking users that deliberately toggle ABI-relevant target features. They get a warning but the feature does get toggled the way they requested.

For now, our logic supports x86, ARM, and RISC-V (just like the previous logic did). Unsurprisingly, RISC-V is the nicest. ;)

As a side-effect this also (unstably) allows *enabling* `x87` when that is harmless. I used the opportunity to mark SSE2 as required on x86-64, to better match the actual logic in LLVM and because all x86-64 chips do have SSE2. This infrastructure also prepares us for requiring SSE on x86-32 when we want to use that for our ABI (and for float semantics sanity), see rust-lang#133611, but no such change is happening in this PR.

r? `@workingjubilee`
@RalfJung
Copy link
Member Author

RalfJung commented Jan 7, 2025

With #134794 there would be a fairly straight-forward way to implement this: add a way for a target to explicitly request a "hardfloat-with-sse" ABI (I am imagining a new rust_abi field in our target specs), and mark sse2 as required target feature for that ABI.

If we do that, setting -Ctarget-cpu to a non-SSE model will not change the ABI; instead, sse2 will silently be enabled anyway. That would be sound from an ABI perspective but likely quite surprising. So instead of forcibly enabling ABI-required features no matter what the target spec and -Ctarget-cpu say, we should probably check if ABI-required features are enabled and emit a warning (and eventually an error) otherwise.

github-actions bot pushed a commit to rust-lang/miri that referenced this issue Jan 8, 2025
…ingjubilee

Add a notion of "some ABIs require certain target features"

I think I finally found the right shape for the data and checks that I recently added in rust-lang/rust#133099, rust-lang/rust#133417, rust-lang/rust#134337: we have a notion of "this ABI requires the following list of target features, and it is incompatible with the following list of target features". Both `-Ctarget-feature` and `#[target_feature]` are updated to ensure we follow the rules of the ABI.  This removes all the "toggleability" stuff introduced before, though we do keep the notion of a fully "forbidden" target feature -- this is needed to deal with target features that are actual ABI switches, and hence are needed to even compute the list of required target features.

We always explicitly (un)set all required and in-conflict features, just to avoid potential trouble caused by the default features of whatever the base CPU is. We do this *before* applying `-Ctarget-feature` to maintain backward compatibility; this poses a slight risk of missing some implicit feature dependencies in LLVM but has the advantage of not breaking users that deliberately toggle ABI-relevant target features. They get a warning but the feature does get toggled the way they requested.

For now, our logic supports x86, ARM, and RISC-V (just like the previous logic did). Unsurprisingly, RISC-V is the nicest. ;)

As a side-effect this also (unstably) allows *enabling* `x87` when that is harmless. I used the opportunity to mark SSE2 as required on x86-64, to better match the actual logic in LLVM and because all x86-64 chips do have SSE2. This infrastructure also prepares us for requiring SSE on x86-32 when we want to use that for our ABI (and for float semantics sanity), see rust-lang/rust#133611, but no such change is happening in this PR.

r? `@workingjubilee`
antoyo pushed a commit to rust-lang/rustc_codegen_gcc that referenced this issue Jan 13, 2025
…ingjubilee

Add a notion of "some ABIs require certain target features"

I think I finally found the right shape for the data and checks that I recently added in rust-lang/rust#133099, rust-lang/rust#133417, rust-lang/rust#134337: we have a notion of "this ABI requires the following list of target features, and it is incompatible with the following list of target features". Both `-Ctarget-feature` and `#[target_feature]` are updated to ensure we follow the rules of the ABI.  This removes all the "toggleability" stuff introduced before, though we do keep the notion of a fully "forbidden" target feature -- this is needed to deal with target features that are actual ABI switches, and hence are needed to even compute the list of required target features.

We always explicitly (un)set all required and in-conflict features, just to avoid potential trouble caused by the default features of whatever the base CPU is. We do this *before* applying `-Ctarget-feature` to maintain backward compatibility; this poses a slight risk of missing some implicit feature dependencies in LLVM but has the advantage of not breaking users that deliberately toggle ABI-relevant target features. They get a warning but the feature does get toggled the way they requested.

For now, our logic supports x86, ARM, and RISC-V (just like the previous logic did). Unsurprisingly, RISC-V is the nicest. ;)

As a side-effect this also (unstably) allows *enabling* `x87` when that is harmless. I used the opportunity to mark SSE2 as required on x86-64, to better match the actual logic in LLVM and because all x86-64 chips do have SSE2. This infrastructure also prepares us for requiring SSE on x86-32 when we want to use that for our ABI (and for float semantics sanity), see rust-lang/rust#133611, but no such change is happening in this PR.

r? `@workingjubilee`
workingjubilee added a commit to workingjubilee/rustc that referenced this issue Feb 10, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 10, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job:  aarch64-apple
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 10, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
fmease added a commit to fmease/rust that referenced this issue Feb 11, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 11, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 12, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 12, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 14, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 14, 2025
add x86-sse2 (32bit) ABI that requires SSE2 target feature

This is the first commit of rust-lang#135408:

The primary goal of this is to make SSE2 required for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but it is the easiest way to make a target feature required via the target spec. In a follow-up change (rust-lang#135408), we can actually make use of SSE2 for the ABI, but that is running into some infrastructure issues.

r? `@workingjubilee`

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 14, 2025
add x86-sse2 (32bit) ABI that requires SSE2 target feature

This is the first commit of rust-lang#135408:

The primary goal of this is to make SSE2 required for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but it is the easiest way to make a target feature required via the target spec. In a follow-up change (rust-lang#135408), we can actually make use of SSE2 for the ABI, but that is running into some infrastructure issues.

r? `@workingjubilee`

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 14, 2025
add x86-sse2 (32bit) ABI that requires SSE2 target feature

This is the first commit of rust-lang#135408:

The primary goal of this is to make SSE2 required for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but it is the easiest way to make a target feature required via the target spec. In a follow-up change (rust-lang#135408), we can actually make use of SSE2 for the ABI, but that is running into some infrastructure issues.

r? `@workingjubilee`

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 14, 2025
add x86-sse2 (32bit) ABI that requires SSE2 target feature

This is the first commit of rust-lang#135408:

The primary goal of this is to make SSE2 required for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but it is the easiest way to make a target feature required via the target spec. In a follow-up change (rust-lang#135408), we can actually make use of SSE2 for the ABI, but that is running into some infrastructure issues.

r? `@workingjubilee`

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
workingjubilee added a commit to workingjubilee/rustc that referenced this issue Feb 14, 2025
…bilee

add x86-sse2 (32bit) ABI that requires SSE2 target feature

This is the first commit of rust-lang#135408:

The primary goal of this is to make SSE2 required for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but it is the easiest way to make a target feature required via the target spec. In a follow-up change (rust-lang#135408), we can actually make use of SSE2 for the ABI, but that is running into some infrastructure issues.

r? `@workingjubilee`

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Feb 15, 2025
Rollup merge of rust-lang#137037 - RalfJung:x86-sse2-abi, r=workingjubilee

add x86-sse2 (32bit) ABI that requires SSE2 target feature

This is the first commit of rust-lang#135408:

The primary goal of this is to make SSE2 required for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but it is the easiest way to make a target feature required via the target spec. In a follow-up change (rust-lang#135408), we can actually make use of SSE2 for the ABI, but that is running into some infrastructure issues.

r? `@workingjubilee`

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
github-actions bot pushed a commit to rust-lang/miri that referenced this issue Feb 15, 2025
add x86-sse2 (32bit) ABI that requires SSE2 target feature

This is the first commit of rust-lang/rust#135408:

The primary goal of this is to make SSE2 required for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang/rust#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang/rust#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but it is the easiest way to make a target feature required via the target spec. In a follow-up change (rust-lang/rust#135408), we can actually make use of SSE2 for the ABI, but that is running into some infrastructure issues.

r? `@workingjubilee`

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 16, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 18, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 18, 2025
x86: make SSE2 required for i686 hardfloat targets and use it to pass SIMD types

The primary goal of this is to make SSE2 *required* for our i686 targets (at least for the ones that use Pentium 4 as their baseline), to ensure they cannot be affected by rust-lang#114479. This has been MCPd in rust-lang/compiler-team#808, and is tracked in rust-lang#133611.

We do this by defining a new ABI that these targets select, and making SSE2 required by the ABI (that's the first commit). That's kind of a hack, but (a) it is the easiest way to make a target feature required via the target spec, and (b) we actually *can* use SSE2 for the Rust ABI now that it is required, so the second commit goes ahead and does that. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 18, 2025
x86: use SSE2 to pass float and SIMD types

This builds on the new X86Sse2 ABI landed in rust-lang#137037 to actually make it a separate ABI from the default x86 ABI, and use SSE2 registers. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
try-job: x86_64-msvc-1
bors added a commit to rust-lang-ci/rust that referenced this issue Feb 18, 2025
x86: use SSE2 to pass float and SIMD types

This builds on the new X86Sse2 ABI landed in rust-lang#137037 to actually make it a separate ABI from the default x86 ABI, and use SSE2 registers. Specifically, we use it in two ways: to return `f64` values in a register rather than by-ptr, and to pass vectors of size up to 128bit in a register (or, well, whatever LLVM does when passing `<4 x float>` by-val, I don't actually know if this ends up in a register).

Cc `@workingjubilee`
Fixes rust-lang#133611

try-job: aarch64-apple
try-job: aarch64-gnu
try-job: aarch64-gnu-debug
try-job: test-various
try-job: x86_64-gnu-nopt
try-job: dist-i586-gnu-i586-i686-musl
try-job: x86_64-msvc-1
@bors bors closed this as completed in 17c1c32 Feb 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-discussion Category: Discussion or questions that doesn't represent real issues. O-x86_32 Target: x86 processors, 32 bit (like i686-*) (IA-32) O-x86_64 Target: x86-64 processors (like x86_64-*) (also known as amd64 and x64) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants