Skip to content

Commit 1bc23f1

Browse files
committed
Auto merge of rust-lang#136367 - workingjubilee:rollup-pud5uj0, r=workingjubilee
Rollup of 16 pull requests Successful merges: - rust-lang#133266 (ci: fix explanation why LLVM download is disabled for windows-gnu) - rust-lang#135768 (tests: Port `symbol-mangling-hashed` to rmake.rs) - rust-lang#135836 (bootstrap: only build `crt{begin,end}.o` when compiling to MUSL) - rust-lang#135840 (omit unused args warnings for intrinsics without body) - rust-lang#135900 (Manually walk into WF obligations in `BestObligation` proof tree visitor) - rust-lang#136146 (Explicitly choose x86 softfloat/hardfloat ABI) - rust-lang#136154 (Use +secure-plt for powerpc-unknown-linux-gnu{,spe}) - rust-lang#136163 (Fix off-by-one error causing slice::sort to abort the program) - rust-lang#136266 (fix broken release notes id) - rust-lang#136283 (Update encode_utf16 to mention it is native endian) - rust-lang#136309 (set rustc dylib on manually constructed rustc command) - rust-lang#136314 (Use proper type when applying deref adjustment in const) - rust-lang#136339 (CompileTest: Add Directives to Ignore `arm-unknown-*` Targets) - rust-lang#136348 (miri: make float min/max non-deterministic) - rust-lang#136351 (Add documentation for derive(CoercePointee)) - rust-lang#136358 (`#[optimize(none)]` implies `#[inline(never)]`) Failed merges: - rust-lang#135994 (Rename rustc_middle::Ty::is_unsafe_ptr to is_raw_ptr) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 854f225 + 26a42c1 commit 1bc23f1

File tree

85 files changed

+1405
-793
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+1405
-793
lines changed

RELEASES.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ Version 1.84.1 (2025-01-30)
1616
Version 1.84.0 (2025-01-09)
1717
==========================
1818

19-
<a id="
20-
Language"></a>
19+
<a id="1.84.0-Language"></a>
2120

2221
Language
2322
--------

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
747747
{
748748
let a: F = self.read_scalar(&args[0])?.to_float()?;
749749
let b: F = self.read_scalar(&args[1])?.to_float()?;
750-
let res = self.adjust_nan(a.min(b), &[a, b]);
750+
let res = if a == b {
751+
// They are definitely not NaN (those are never equal), but they could be `+0` and `-0`.
752+
// Let the machine decide which one to return.
753+
M::equal_float_min_max(self, a, b)
754+
} else {
755+
self.adjust_nan(a.min(b), &[a, b])
756+
};
751757
self.write_scalar(res, dest)?;
752758
interp_ok(())
753759
}
@@ -762,7 +768,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
762768
{
763769
let a: F = self.read_scalar(&args[0])?.to_float()?;
764770
let b: F = self.read_scalar(&args[1])?.to_float()?;
765-
let res = self.adjust_nan(a.max(b), &[a, b]);
771+
let res = if a == b {
772+
// They are definitely not NaN (those are never equal), but they could be `+0` and `-0`.
773+
// Let the machine decide which one to return.
774+
M::equal_float_min_max(self, a, b)
775+
} else {
776+
self.adjust_nan(a.max(b), &[a, b])
777+
};
766778
self.write_scalar(res, dest)?;
767779
interp_ok(())
768780
}

compiler/rustc_const_eval/src/interpret/machine.rs

+6
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ pub trait Machine<'tcx>: Sized {
278278
F2::NAN
279279
}
280280

281+
/// Determines the result of `min`/`max` on floats when the arguments are equal.
282+
fn equal_float_min_max<F: Float>(_ecx: &InterpCx<'tcx, Self>, a: F, _b: F) -> F {
283+
// By default, we pick the left argument.
284+
a
285+
}
286+
281287
/// Called before a basic block terminator is executed.
282288
#[inline]
283289
fn before_terminator(_ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
253253
return;
254254
}
255255

256+
let mut expr_ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
257+
256258
for a in &adj {
257259
match a.kind {
258260
Adjust::NeverToAny => {
@@ -266,7 +268,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
266268
None,
267269
expr.span,
268270
overloaded_deref.method_call(self.tcx),
269-
self.tcx.mk_args(&[a.target.into()]),
271+
self.tcx.mk_args(&[expr_ty.into()]),
270272
);
271273
}
272274
Adjust::Deref(None) => {
@@ -283,6 +285,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
283285
// No effects to enforce here.
284286
}
285287
}
288+
289+
expr_ty = a.target;
286290
}
287291

288292
let autoborrow_mut = adj.iter().any(|adj| {

compiler/rustc_mir_transform/src/inline.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::iter;
44
use std::ops::{Range, RangeFrom};
55

66
use rustc_abi::{ExternAbi, FieldIdx};
7-
use rustc_attr_parsing::InlineAttr;
7+
use rustc_attr_parsing::{InlineAttr, OptimizeAttr};
88
use rustc_hir::def::DefKind;
99
use rustc_hir::def_id::DefId;
1010
use rustc_index::Idx;
@@ -770,6 +770,10 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>(
770770
return Err("never inline attribute");
771771
}
772772

773+
if let OptimizeAttr::DoNotOptimize = callee_attrs.optimize {
774+
return Err("has DoNotOptimize attribute");
775+
}
776+
773777
// Reachability pass defines which functions are eligible for inlining. Generally inlining
774778
// other functions is incorrect because they could reference symbols that aren't exported.
775779
let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();

compiler/rustc_passes/src/liveness.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,14 @@ impl<'tcx> Liveness<'_, 'tcx> {
15221522
}
15231523

15241524
fn warn_about_unused_args(&self, body: &hir::Body<'_>, entry_ln: LiveNode) {
1525+
if let Some(intrinsic) =
1526+
self.ir.tcx.intrinsic(self.ir.tcx.hir().body_owner_def_id(body.id()))
1527+
{
1528+
if intrinsic.must_be_overridden {
1529+
return;
1530+
}
1531+
}
1532+
15251533
for p in body.params {
15261534
self.check_unused_vars_in_pat(
15271535
p.pat,

compiler/rustc_target/src/spec/json.rs

+15
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,19 @@ impl Target {
128128
Some(Ok(()))
129129
})).unwrap_or(Ok(()))
130130
} );
131+
($key_name:ident, RustcAbi) => ( {
132+
let name = (stringify!($key_name)).replace("_", "-");
133+
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
134+
match s.parse::<super::RustcAbi>() {
135+
Ok(rustc_abi) => base.$key_name = Some(rustc_abi),
136+
_ => return Some(Err(format!(
137+
"'{s}' is not a valid value for rustc-abi. \
138+
Use 'x86-softfloat' or leave the field unset."
139+
))),
140+
}
141+
Some(Ok(()))
142+
})).unwrap_or(Ok(()))
143+
} );
131144
($key_name:ident, RelocModel) => ( {
132145
let name = (stringify!($key_name)).replace("_", "-");
133146
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
@@ -612,6 +625,7 @@ impl Target {
612625
key!(llvm_mcount_intrinsic, optional);
613626
key!(llvm_abiname);
614627
key!(llvm_floatabi, FloatAbi)?;
628+
key!(rustc_abi, RustcAbi)?;
615629
key!(relax_elf_relocations, bool);
616630
key!(llvm_args, list);
617631
key!(use_ctors_section, bool);
@@ -788,6 +802,7 @@ impl ToJson for Target {
788802
target_option_val!(llvm_mcount_intrinsic);
789803
target_option_val!(llvm_abiname);
790804
target_option_val!(llvm_floatabi);
805+
target_option_val!(rustc_abi);
791806
target_option_val!(relax_elf_relocations);
792807
target_option_val!(llvm_args);
793808
target_option_val!(use_ctors_section);

compiler/rustc_target/src/spec/mod.rs

+45-4
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,33 @@ impl ToJson for FloatAbi {
11141114
}
11151115
}
11161116

1117+
/// The Rustc-specific variant of the ABI used for this target.
1118+
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
1119+
pub enum RustcAbi {
1120+
/// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI.
1121+
X86Softfloat,
1122+
}
1123+
1124+
impl FromStr for RustcAbi {
1125+
type Err = ();
1126+
1127+
fn from_str(s: &str) -> Result<RustcAbi, ()> {
1128+
Ok(match s {
1129+
"x86-softfloat" => RustcAbi::X86Softfloat,
1130+
_ => return Err(()),
1131+
})
1132+
}
1133+
}
1134+
1135+
impl ToJson for RustcAbi {
1136+
fn to_json(&self) -> Json {
1137+
match *self {
1138+
RustcAbi::X86Softfloat => "x86-softfloat",
1139+
}
1140+
.to_json()
1141+
}
1142+
}
1143+
11171144
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
11181145
pub enum TlsModel {
11191146
GeneralDynamic,
@@ -2505,6 +2532,12 @@ pub struct TargetOptions {
25052532
/// If not provided, LLVM will infer the float ABI from the target triple (`llvm_target`).
25062533
pub llvm_floatabi: Option<FloatAbi>,
25072534

2535+
/// Picks a specific ABI for this target. This is *not* just for "Rust" ABI functions,
2536+
/// it can also affect "C" ABI functions; the point is that this flag is interpreted by
2537+
/// rustc and not forwarded to LLVM.
2538+
/// So far, this is only used on x86.
2539+
pub rustc_abi: Option<RustcAbi>,
2540+
25082541
/// Whether or not RelaxElfRelocation flag will be passed to the linker
25092542
pub relax_elf_relocations: bool,
25102543

@@ -2664,10 +2697,6 @@ impl TargetOptions {
26642697
.collect();
26652698
}
26662699
}
2667-
2668-
pub(crate) fn has_feature(&self, search_feature: &str) -> bool {
2669-
self.features.split(',').any(|f| f.strip_prefix('+').is_some_and(|f| f == search_feature))
2670-
}
26712700
}
26722701

26732702
impl Default for TargetOptions {
@@ -2774,6 +2803,7 @@ impl Default for TargetOptions {
27742803
llvm_mcount_intrinsic: None,
27752804
llvm_abiname: "".into(),
27762805
llvm_floatabi: None,
2806+
rustc_abi: None,
27772807
relax_elf_relocations: false,
27782808
llvm_args: cvs![],
27792809
use_ctors_section: false,
@@ -3240,6 +3270,17 @@ impl Target {
32403270
_ => {}
32413271
}
32423272

3273+
// Check consistency of Rust ABI declaration.
3274+
if let Some(rust_abi) = self.rustc_abi {
3275+
match rust_abi {
3276+
RustcAbi::X86Softfloat => check_matches!(
3277+
&*self.arch,
3278+
"x86" | "x86_64",
3279+
"`x86-softfloat` ABI is only valid for x86 targets"
3280+
),
3281+
}
3282+
}
3283+
32433284
// Check that the given target-features string makes some basic sense.
32443285
if !self.features.is_empty() {
32453286
let mut features_enabled = FxHashSet::default();

compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// The cdecl ABI is used. It differs from the stdcall or fastcall ABI.
66
// "i686-unknown-windows" is used to get the minimal subset of windows-specific features.
77

8-
use crate::spec::{Target, base};
8+
use crate::spec::{RustcAbi, Target, base};
99

1010
pub(crate) fn target() -> Target {
1111
let mut base = base::uefi_msvc::opts();
@@ -22,6 +22,7 @@ pub(crate) fn target() -> Target {
2222
// If you initialize FP units yourself, you can override these flags with custom linker
2323
// arguments, thus giving you access to full MMX/SSE acceleration.
2424
base.features = "-mmx,-sse,+soft-float".into();
25+
base.rustc_abi = Some(RustcAbi::X86Softfloat);
2526

2627
// Use -GNU here, because of the reason below:
2728
// Background and Problem:

compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ pub(crate) fn target() -> Target {
1818
pointer_width: 32,
1919
data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(),
2020
arch: "powerpc".into(),
21-
options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base },
21+
options: TargetOptions {
22+
endian: Endian::Big,
23+
features: "+secure-plt".into(),
24+
mcount: "_mcount".into(),
25+
..base
26+
},
2227
}
2328
}

compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub(crate) fn target() -> Target {
2121
options: TargetOptions {
2222
abi: "spe".into(),
2323
endian: Endian::Big,
24+
features: "+secure-plt".into(),
2425
mcount: "_mcount".into(),
2526
..base
2627
},

compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
// features.
66

77
use crate::spec::{
8-
Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelroLevel, SanitizerSet, StackProbeType,
9-
Target, TargetOptions,
8+
Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelroLevel, RustcAbi, SanitizerSet,
9+
StackProbeType, Target, TargetOptions,
1010
};
1111

1212
pub(crate) fn target() -> Target {
@@ -20,6 +20,7 @@ pub(crate) fn target() -> Target {
2020
relro_level: RelroLevel::Full,
2121
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
2222
linker: Some("rust-lld".into()),
23+
rustc_abi: Some(RustcAbi::X86Softfloat),
2324
features: "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float".into(),
2425
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
2526
disable_redzone: true,

compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
77

88
use crate::abi::call::Conv;
9-
use crate::spec::{Target, base};
9+
use crate::spec::{RustcAbi, Target, base};
1010

1111
pub(crate) fn target() -> Target {
1212
let mut base = base::uefi_msvc::opts();
@@ -26,6 +26,7 @@ pub(crate) fn target() -> Target {
2626
// If you initialize FP units yourself, you can override these flags with custom linker
2727
// arguments, thus giving you access to full MMX/SSE acceleration.
2828
base.features = "-mmx,-sse,+soft-float".into();
29+
base.rustc_abi = Some(RustcAbi::X86Softfloat);
2930

3031
Target {
3132
llvm_target: "x86_64-unknown-windows".into(),

compiler/rustc_target/src/target_features.rs

+36-16
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
55
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
66
use rustc_span::{Symbol, sym};
77

8-
use crate::spec::{FloatAbi, Target};
8+
use crate::spec::{FloatAbi, RustcAbi, Target};
99

1010
/// Features that control behaviour of rustc, rather than the codegen.
1111
/// These exist globally and are not in the target-specific lists below.
@@ -422,7 +422,9 @@ const X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
422422
("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]),
423423
("sm3", Unstable(sym::sha512_sm_x86), &["avx"]),
424424
("sm4", Unstable(sym::sha512_sm_x86), &["avx2"]),
425-
("soft-float", Stability::Forbidden { reason: "unsound because it changes float ABI" }, &[]),
425+
// This cannot actually be toggled, the ABI always fixes it, so it'd make little sense to
426+
// stabilize. It must be in this list for the ABI check to be able to use it.
427+
("soft-float", Stability::Unstable(sym::x87_target_feature), &[]),
426428
("sse", Stable, &[]),
427429
("sse2", Stable, &["sse"]),
428430
("sse3", Stable, &["sse2"]),
@@ -773,23 +775,41 @@ impl Target {
773775
// questions "which ABI is used".
774776
match &*self.arch {
775777
"x86" => {
776-
// We support 2 ABIs, hardfloat (default) and softfloat.
777-
// x86 has no sane ABI indicator so we have to use the target feature.
778-
if self.has_feature("soft-float") {
779-
NOTHING
780-
} else {
781-
// Hardfloat ABI. x87 must be enabled.
782-
FeatureConstraints { required: &["x87"], incompatible: &[] }
778+
// We use our own ABI indicator here; LLVM does not have anything native.
779+
// Every case should require or forbid `soft-float`!
780+
match self.rustc_abi {
781+
None => {
782+
// Default hardfloat ABI.
783+
// x87 must be enabled, soft-float must be disabled.
784+
FeatureConstraints { required: &["x87"], incompatible: &["soft-float"] }
785+
}
786+
Some(RustcAbi::X86Softfloat) => {
787+
// Softfloat ABI, requires corresponding target feature. That feature trumps
788+
// `x87` and all other FPU features so those do not matter.
789+
// Note that this one requirement is the entire implementation of the ABI!
790+
// LLVM handles the rest.
791+
FeatureConstraints { required: &["soft-float"], incompatible: &[] }
792+
}
783793
}
784794
}
785795
"x86_64" => {
786-
// We support 2 ABIs, hardfloat (default) and softfloat.
787-
// x86 has no sane ABI indicator so we have to use the target feature.
788-
if self.has_feature("soft-float") {
789-
NOTHING
790-
} else {
791-
// Hardfloat ABI. x87 and SSE2 must be enabled.
792-
FeatureConstraints { required: &["x87", "sse2"], incompatible: &[] }
796+
// We use our own ABI indicator here; LLVM does not have anything native.
797+
// Every case should require or forbid `soft-float`!
798+
match self.rustc_abi {
799+
None => {
800+
// Default hardfloat ABI. On x86-64, this always includes SSE2.
801+
FeatureConstraints {
802+
required: &["x87", "sse2"],
803+
incompatible: &["soft-float"],
804+
}
805+
}
806+
Some(RustcAbi::X86Softfloat) => {
807+
// Softfloat ABI, requires corresponding target feature. That feature trumps
808+
// `x87` and all other FPU features so those do not matter.
809+
// Note that this one requirement is the entire implementation of the ABI!
810+
// LLVM handles the rest.
811+
FeatureConstraints { required: &["soft-float"], incompatible: &[] }
812+
}
793813
}
794814
}
795815
"arm" => {

0 commit comments

Comments
 (0)