Skip to content

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

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

Merged
merged 1 commit into from
Feb 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions compiler/rustc_target/src/spec/base/apple/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::borrow::Cow;
use std::env;

use crate::spec::{
Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, SplitDebuginfo, StackProbeType,
StaticCow, TargetOptions, cvs,
Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi, SplitDebuginfo,
StackProbeType, StaticCow, TargetOptions, cvs,
};

#[cfg(test)]
Expand Down Expand Up @@ -103,7 +103,7 @@ pub(crate) fn base(
arch: Arch,
abi: TargetAbi,
) -> (TargetOptions, StaticCow<str>, StaticCow<str>) {
let opts = TargetOptions {
let mut opts = TargetOptions {
abi: abi.target_abi().into(),
llvm_floatabi: Some(FloatAbi::Hard),
os: os.into(),
Expand Down Expand Up @@ -154,6 +154,10 @@ pub(crate) fn base(

..Default::default()
};
if matches!(arch, Arch::I386 | Arch::I686) {
// All Apple x86-32 targets have SSE2.
opts.rustc_abi = Some(RustcAbi::X86Sse2);
}
(opts, unversioned_llvm_target(os, arch, abi), arch.target_arch())
}

Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,8 @@ impl ToJson for FloatAbi {
/// The Rustc-specific variant of the ABI used for this target.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum RustcAbi {
/// On x86-32 only: make use of SSE and SSE2 for ABI purposes.
X86Sse2,
/// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI.
X86Softfloat,
}
Expand All @@ -1118,6 +1120,7 @@ impl FromStr for RustcAbi {

fn from_str(s: &str) -> Result<RustcAbi, ()> {
Ok(match s {
"x86-sse2" => RustcAbi::X86Sse2,
"x86-softfloat" => RustcAbi::X86Softfloat,
_ => return Err(()),
})
Expand All @@ -1127,6 +1130,7 @@ impl FromStr for RustcAbi {
impl ToJson for RustcAbi {
fn to_json(&self) -> Json {
match *self {
RustcAbi::X86Sse2 => "x86-sse2",
RustcAbi::X86Softfloat => "x86-softfloat",
}
.to_json()
Expand Down Expand Up @@ -3264,6 +3268,11 @@ impl Target {
// Check consistency of Rust ABI declaration.
if let Some(rust_abi) = self.rustc_abi {
match rust_abi {
RustcAbi::X86Sse2 => check_matches!(
&*self.arch,
"x86",
"`x86-sse2` ABI is only valid for x86-32 targets"
),
RustcAbi::X86Softfloat => check_matches!(
&*self.arch,
"x86" | "x86_64",
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::spec::base::nto_qnx;
use crate::spec::{StackProbeType, Target, TargetOptions, base};
use crate::spec::{RustcAbi, StackProbeType, Target, TargetOptions, base};

pub(crate) fn target() -> Target {
let mut meta = nto_qnx::meta();
Expand All @@ -14,6 +14,7 @@ pub(crate) fn target() -> Target {
.into(),
arch: "x86".into(),
options: TargetOptions {
rustc_abi: Some(RustcAbi::X86Sse2),
cpu: "pentium4".into(),
max_atomic_width: Some(64),
pre_link_args: nto_qnx::pre_link_args(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::spec::Target;

pub(crate) fn target() -> Target {
let mut base = super::i686_unknown_linux_gnu::target();
base.rustc_abi = None; // overwrite the SSE2 ABI set by the base target
base.cpu = "pentium".into();
base.llvm_target = "i586-unknown-linux-gnu".into();
base
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::spec::Target;

pub(crate) fn target() -> Target {
let mut base = super::i686_unknown_linux_musl::target();
base.rustc_abi = None; // overwrite the SSE2 ABI set by the base target
base.cpu = "pentium".into();
base.llvm_target = "i586-unknown-linux-musl".into();
// FIXME(compiler-team#422): musl targets should be dynamically linked by default.
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/targets/i686_linux_android.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::spec::{SanitizerSet, StackProbeType, Target, TargetOptions, base};
use crate::spec::{RustcAbi, SanitizerSet, StackProbeType, Target, TargetOptions, base};

// See https://developer.android.com/ndk/guides/abis.html#x86
// for target ABI requirements.
Expand All @@ -8,6 +8,7 @@ pub(crate) fn target() -> Target {

base.max_atomic_width = Some(64);

base.rustc_abi = Some(RustcAbi::X86Sse2);
// https://developer.android.com/ndk/guides/abis.html#x86
base.cpu = "pentium4".into();
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".into();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, base};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::windows_gnu::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.frame_pointer = FramePointer::Always; // Required for backtraces
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, base};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::windows_gnullvm::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.frame_pointer = FramePointer::Always; // Required for backtraces
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{LinkerFlavor, Lld, SanitizerSet, Target, base};
use crate::spec::{LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::windows_msvc::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.supported_sanitizers = SanitizerSet::ADDRESS;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base};
use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::freebsd::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-znotext"]);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base};
use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::haiku::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, base};
use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, SanitizerSet, StackProbeType, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::linux_gnu::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
// Dear distribution packager, if you are changing the base CPU model with the goal of removing
// the SSE2 requirement, make sure to also set the `rustc_abi` to `None` above or else the compiler
// will complain that the chosen ABI cannot be realized with the given CPU features.
// Also note that x86 without SSE2 is *not* considered a Tier 1 target by the Rust project, and
// it has some known floating-point correctness issues mostly caused by a lack of people caring
// for LLVM's x87 support (double-rounding, value truncation; see
// <https://github.com/rust-lang/rust/issues/114479> for details). This can lead to incorrect
// math (Rust generally promises exact math, so this can break code in unexpected ways) and it
// can lead to memory safety violations if floating-point values are used e.g. to access an
// array. If users run into such issues and report bugs upstream and then it turns out that the
// bugs are caused by distribution patches, that leads to confusion and frustration.
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.supported_sanitizers = SanitizerSet::ADDRESS;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target, base};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::linux_musl::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
// If you want to change the base CPU, please see `i686_unknown_linux_gnu.rs`
// for an important comment.
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-melf_i386"]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetOptions, base};

pub(crate) fn target() -> Target {
let mut base = base::netbsd::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base};
use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::openbsd::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-fuse-ld=lld"]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, base};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::windows_uwp_gnu::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.frame_pointer = FramePointer::Always; // Required for backtraces
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{Target, base};
use crate::spec::{RustcAbi, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::windows_uwp_msvc::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, base};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::windows_gnu::opts();
base.vendor = "win7".into();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.frame_pointer = FramePointer::Always; // Required for backtraces
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::spec::{LinkerFlavor, Lld, SanitizerSet, Target, base};
use crate::spec::{LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::windows_msvc::opts();
base.vendor = "win7".into();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.supported_sanitizers = SanitizerSet::ADDRESS;
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base};
use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};

pub(crate) fn target() -> Target {
let mut base = base::vxworks::opts();
base.rustc_abi = Some(RustcAbi::X86Sse2);
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,13 @@ impl Target {
// x87 must be enabled, soft-float must be disabled.
FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
}
Some(RustcAbi::X86Sse2) => {
// Extended hardfloat ABI. x87 and SSE2 must be enabled, soft-float must be disabled.
FeatureConstraints {
required: &["x87", "sse2"],
incompatible: &["soft-float"],
}
}
Some(RustcAbi::X86Softfloat) => {
// Softfloat ABI, requires corresponding target feature. That feature trumps
// `x87` and all other FPU features so those do not matter.
Expand Down Expand Up @@ -817,6 +824,7 @@ impl Target {
// LLVM handles the rest.
FeatureConstraints { required: &["soft-float"], incompatible: &[] }
}
Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
}
}
"arm" => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
warning: target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly
|
= note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>

2 changes: 1 addition & 1 deletion tests/ui/sse-abi-checks.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Ensure we trigger abi_unsupported_vector_types for target features that are usually enabled
//! on a target, but disabled in this file via a `-C` flag.
//@ compile-flags: --crate-type=rlib --target=i686-unknown-linux-gnu -C target-feature=-sse,-sse2
//@ compile-flags: --crate-type=rlib --target=i586-unknown-linux-gnu -C target-feature=-sse,-sse2
//@ build-pass
//@ ignore-pass (test emits codegen-time warnings)
//@ needs-llvm-components: x86
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@ compile-flags: --target=i686-unknown-linux-gnu --crate-type=lib
//@ needs-llvm-components: x86
//@ compile-flags: -Ctarget-cpu=pentium
// For now this is just a warning.
//@ build-pass
//@error-pattern: must be enabled

#![feature(no_core, lang_items)]
#![no_core]

#[lang = "sized"]
pub trait Sized {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
warning: target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly
|
= note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>

warning: 1 warning emitted

Loading