add x86-sse2 (32bit) ABI that requires SSE2 target feature · rust-lang/rust@2eff215 (original) (raw)

25 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@ use std::borrow::Cow;
2 2 use std::env;
3 3
4 4 use crate::spec::{
5 -Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, SplitDebuginfo, StackProbeType,
6 -StaticCow, TargetOptions, cvs,
5 +Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi, SplitDebuginfo,
6 +StackProbeType, StaticCow, TargetOptions, cvs,
7 7 };
8 8
9 9 #[cfg(test)]
@@ -103,7 +103,7 @@ pub(crate) fn base(
103 103 arch: Arch,
104 104 abi: TargetAbi,
105 105 ) -> (TargetOptions, StaticCow<str>, StaticCow<str>) {
106 -let opts = TargetOptions {
106 +let mut opts = TargetOptions {
107 107 abi: abi.target_abi().into(),
108 108 llvm_floatabi: Some(FloatAbi::Hard),
109 109 os: os.into(),
@@ -154,6 +154,10 @@ pub(crate) fn base(
154 154
155 155 ..Default::default()
156 156 };
157 +if matches!(arch, Arch::I386 | Arch::I686) {
158 +// All Apple x86-32 targets have SSE2.
159 + opts.rustc_abi = Some(RustcAbi::X86Sse2);
160 +}
157 161 (opts, unversioned_llvm_target(os, arch, abi), arch.target_arch())
158 162 }
159 163
Original file line number Diff line number Diff line change
@@ -1109,6 +1109,8 @@ impl ToJson for FloatAbi {
1109 1109 /// The Rustc-specific variant of the ABI used for this target.
1110 1110 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
1111 1111 pub enum RustcAbi {
1112 +/// On x86-32 only: make use of SSE and SSE2 for ABI purposes.
1113 + X86Sse2,
1112 1114 /// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI.
1113 1115 X86Softfloat,
1114 1116 }
@@ -1118,6 +1120,7 @@ impl FromStr for RustcAbi {
1118 1120
1119 1121 fn from_str(s: &str) -> Result<RustcAbi, ()> {
1120 1122 Ok(match s {
1123 +"x86-sse2" => RustcAbi::X86Sse2,
1121 1124 "x86-softfloat" => RustcAbi::X86Softfloat,
1122 1125 _ => return Err(()),
1123 1126 })
@@ -1127,6 +1130,7 @@ impl FromStr for RustcAbi {
1127 1130 impl ToJson for RustcAbi {
1128 1131 fn to_json(&self) -> Json {
1129 1132 match *self {
1133 +RustcAbi::X86Sse2 => "x86-sse2",
1130 1134 RustcAbi::X86Softfloat => "x86-softfloat",
1131 1135 }
1132 1136 .to_json()
@@ -3264,6 +3268,11 @@ impl Target {
3264 3268 // Check consistency of Rust ABI declaration.
3265 3269 if let Some(rust_abi) = self.rustc_abi {
3266 3270 match rust_abi {
3271 +RustcAbi::X86Sse2 => check_matches!(
3272 +&*self.arch,
3273 +"x86",
3274 +"`x86-sse2` ABI is only valid for x86-32 targets"
3275 +),
3267 3276 RustcAbi::X86Softfloat => check_matches!(
3268 3277 &*self.arch,
3269 3278 "x86" | "x86_64",
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
1 1 use crate::spec::base::nto_qnx;
2 -use crate::spec::{StackProbeType, Target, TargetOptions, base};
2 +use crate::spec::{RustcAbi, StackProbeType, Target, TargetOptions, base};
3 3
4 4 pub(crate) fn target() -> Target {
5 5 let mut meta = nto_qnx::meta();
@@ -14,6 +14,7 @@ pub(crate) fn target() -> Target {
14 14 .into(),
15 15 arch: "x86".into(),
16 16 options: TargetOptions {
17 +rustc_abi: Some(RustcAbi::X86Sse2),
17 18 cpu: "pentium4".into(),
18 19 max_atomic_width: Some(64),
19 20 pre_link_args: nto_qnx::pre_link_args(
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ use crate::spec::Target;
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = super::i686_unknown_linux_gnu::target();
5 + base.rustc_abi = None; // overwrite the SSE2 ABI set by the base target
5 6 base.cpu = "pentium".into();
6 7 base.llvm_target = "i586-unknown-linux-gnu".into();
7 8 base
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ use crate::spec::Target;
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = super::i686_unknown_linux_musl::target();
5 + base.rustc_abi = None; // overwrite the SSE2 ABI set by the base target
5 6 base.cpu = "pentium".into();
6 7 base.llvm_target = "i586-unknown-linux-musl".into();
7 8 // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
1 -use crate::spec::{SanitizerSet, StackProbeType, Target, TargetOptions, base};
1 +use crate::spec::{RustcAbi, SanitizerSet, StackProbeType, Target, TargetOptions, base};
2 2
3 3 // See https://developer.android.com/ndk/guides/abis.html#x86
4 4 // for target ABI requirements.
@@ -8,6 +8,7 @@ pub(crate) fn target() -> Target {
8 8
9 9 base.max_atomic_width = Some(64);
10 10
11 + base.rustc_abi = Some(RustcAbi::X86Sse2);
11 12 // https://developer.android.com/ndk/guides/abis.html#x86
12 13 base.cpu = "pentium4".into();
13 14 base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".into();
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, base};
1 +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::windows_gnu::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8 base.frame_pointer = FramePointer::Always; // Required for backtraces
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, base};
1 +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::windows_gnullvm::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8 base.frame_pointer = FramePointer::Always; // Required for backtraces
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{LinkerFlavor, Lld, SanitizerSet, Target, base};
1 +use crate::spec::{LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::windows_msvc::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8 base.supported_sanitizers = SanitizerSet::ADDRESS;
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base};
1 +use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::freebsd::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8 base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-znotext"]);
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base};
1 +use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::haiku::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8 base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
1 -use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, base};
1 +use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, SanitizerSet, StackProbeType, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::linux_gnu::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
6 +// Dear distribution packager, if you are changing the base CPU model with the goal of removing
7 +// the SSE2 requirement, make sure to also set the `rustc_abi` to `None` above or else the compiler
8 +// will complain that the chosen ABI cannot be realized with the given CPU features.
9 +// Also note that x86 without SSE2 is *not* considered a Tier 1 target by the Rust project, and
10 +// it has some known floating-point correctness issues mostly caused by a lack of people caring
11 +// for LLVM's x87 support (double-rounding, value truncation; see
12 +// https://github.com/rust-lang/rust/issues/114479 for details). This can lead to incorrect
13 +// math (Rust generally promises exact math, so this can break code in unexpected ways) and it
14 +// can lead to memory safety violations if floating-point values are used e.g. to access an
15 +// array. If users run into such issues and report bugs upstream and then it turns out that the
16 +// bugs are caused by distribution patches, that leads to confusion and frustration.
5 17 base.cpu = "pentium4".into();
6 18 base.max_atomic_width = Some(64);
7 19 base.supported_sanitizers = SanitizerSet::ADDRESS;
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
1 -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target, base};
1 +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::linux_musl::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
6 +// If you want to change the base CPU, please see `i686_unknown_linux_gnu.rs`
7 +// for an important comment.
5 8 base.cpu = "pentium4".into();
6 9 base.max_atomic_width = Some(64);
7 10 base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-melf_i386"]);
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
1 +use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, TargetOptions, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::netbsd::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8 base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base};
1 +use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::openbsd::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8 base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-fuse-ld=lld"]);
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, base};
1 +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::windows_uwp_gnu::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8 base.frame_pointer = FramePointer::Always; // Required for backtraces
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{Target, base};
1 +use crate::spec::{RustcAbi, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::windows_uwp_msvc::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
1 -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, base};
1 +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::windows_gnu::opts();
5 5 base.vendor = "win7".into();
6 + base.rustc_abi = Some(RustcAbi::X86Sse2);
6 7 base.cpu = "pentium4".into();
7 8 base.max_atomic_width = Some(64);
8 9 base.frame_pointer = FramePointer::Always; // Required for backtraces
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
1 -use crate::spec::{LinkerFlavor, Lld, SanitizerSet, Target, base};
1 +use crate::spec::{LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::windows_msvc::opts();
5 5 base.vendor = "win7".into();
6 + base.rustc_abi = Some(RustcAbi::X86Sse2);
6 7 base.cpu = "pentium4".into();
7 8 base.max_atomic_width = Some(64);
8 9 base.supported_sanitizers = SanitizerSet::ADDRESS;
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
1 -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base};
1 +use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, StackProbeType, Target, base};
2 2
3 3 pub(crate) fn target() -> Target {
4 4 let mut base = base::vxworks::opts();
5 + base.rustc_abi = Some(RustcAbi::X86Sse2);
5 6 base.cpu = "pentium4".into();
6 7 base.max_atomic_width = Some(64);
7 8 base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
Original file line number Diff line number Diff line change
@@ -790,6 +790,13 @@ impl Target {
790 790 // x87 must be enabled, soft-float must be disabled.
791 791 FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
792 792 }
793 +Some(RustcAbi::X86Sse2) => {
794 +// Extended hardfloat ABI. x87 and SSE2 must be enabled, soft-float must be disabled.
795 +FeatureConstraints {
796 +required: &["x87", "sse2"],
797 +incompatible: &["soft-float"],
798 +}
799 +}
793 800 Some(RustcAbi::X86Softfloat) => {
794 801 // Softfloat ABI, requires corresponding target feature. That feature trumps
795 802 // `x87` and all other FPU features so those do not matter.
@@ -817,6 +824,7 @@ impl Target {
817 824 // LLVM handles the rest.
818 825 FeatureConstraints { required: &["soft-float"], incompatible: &[] }
819 826 }
827 +Some(r) => panic!("invalid Rust ABI for x86_64: {r:?}"),
820 828 }
821 829 }
822 830 "arm" => {
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
1 +warning: target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly
2 + |
3 + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4 + = note: for more information, see issue #116344 https://github.com/rust-lang/rust/issues/116344
5 +
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
1 1 //! Ensure we trigger abi_unsupported_vector_types for target features that are usually enabled
2 2 //! on a target, but disabled in this file via a `-C` flag.
3 -//@ compile-flags: --crate-type=rlib --target=i686-unknown-linux-gnu -C target-feature=-sse,-sse2
3 +//@ compile-flags: --crate-type=rlib --target=i586-unknown-linux-gnu -C target-feature=-sse,-sse2
4 4 //@ build-pass
5 5 //@ ignore-pass (test emits codegen-time warnings)
6 6 //@ needs-llvm-components: x86
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
1 +//@ compile-flags: --target=i686-unknown-linux-gnu --crate-type=lib
2 +//@ needs-llvm-components: x86
3 +//@ compile-flags: -Ctarget-cpu=pentium
4 +// For now this is just a warning.
5 +//@ build-pass
6 +//@error-pattern: must be enabled
7 +
8 +#![feature(no_core, lang_items)]
9 +#![no_core]
10 +
11 +#[lang = "sized"]
12 +pub trait Sized {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1 +warning: target feature `sse2` must be enabled to ensure that the ABI of the current target can be implemented correctly
2 + |
3 + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4 + = note: for more information, see issue #116344 https://github.com/rust-lang/rust/issues/116344
5 +
6 +warning: 1 warning emitted
7 +