Skip to content

Commit 7b0bf9e

Browse files
committed
Auto merge of #95223 - Dylan-DPC:rollup-idpb7ka, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #91608 (Fold aarch64 feature +fp into +neon) - #92955 (add perf side effect docs to `Iterator::cloned()`) - #94713 (Add u16::is_utf16_surrogate) - #95212 (Replace `this.clone()` with `this.create_snapshot_for_diagnostic()`) - #95219 (Modernize `alloc-no-oom-handling` test) - #95222 (interpret/validity: improve clarity) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 2b50739 + 2f24923 commit 7b0bf9e

File tree

16 files changed

+206
-21
lines changed

16 files changed

+206
-21
lines changed

compiler/rustc_codegen_llvm/src/llvm_util.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]
187187
("x86", "avx512vaes") => smallvec!["vaes"],
188188
("x86", "avx512gfni") => smallvec!["gfni"],
189189
("x86", "avx512vpclmulqdq") => smallvec!["vpclmulqdq"],
190-
("aarch64", "fp") => smallvec!["fp-armv8"],
191190
("aarch64", "rcpc2") => smallvec!["rcpc-immo"],
192191
("aarch64", "dpb") => smallvec!["ccpp"],
193192
("aarch64", "dpb2") => smallvec!["ccdp"],
@@ -230,6 +229,8 @@ pub fn check_tied_features(
230229
None
231230
}
232231

232+
// Used to generate cfg variables and apply features
233+
// Must express features in the way Rust understands them
233234
pub fn target_features(sess: &Session) -> Vec<Symbol> {
234235
let target_machine = create_informational_target_machine(sess);
235236
let mut features: Vec<Symbol> =
@@ -239,13 +240,14 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
239240
if sess.is_nightly_build() || gate.is_none() { Some(feature) } else { None }
240241
})
241242
.filter(|feature| {
243+
// check that all features in a given smallvec are enabled
242244
for llvm_feature in to_llvm_features(sess, feature) {
243245
let cstr = SmallCStr::new(llvm_feature);
244-
if unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
245-
return true;
246+
if !unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
247+
return false;
246248
}
247249
}
248-
false
250+
true
249251
})
250252
.map(|feature| Symbol::intern(feature))
251253
.collect();

compiler/rustc_codegen_ssa/src/target_features.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,8 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
4343
];
4444

4545
const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
46-
// FEAT_AdvSimd
46+
// FEAT_AdvSimd & FEAT_FP
4747
("neon", None),
48-
// FEAT_FP
49-
("fp", None),
5048
// FEAT_FP16
5149
("fp16", None),
5250
// FEAT_SVE
@@ -143,7 +141,6 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
143141
];
144142

145143
const AARCH64_TIED_FEATURES: &[&[&str]] = &[
146-
&["fp", "neon"], // Silicon always has both, so avoid needless complications
147144
&["paca", "pacg"], // Together these represent `pauth` in LLVM
148145
];
149146

compiler/rustc_const_eval/src/interpret/validity.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
432432
if let Some(ref mut ref_tracking) = self.ref_tracking {
433433
// Proceed recursively even for ZST, no reason to skip them!
434434
// `!` is a ZST and we want to validate it.
435-
// Skip validation entirely for some external statics
436435
if let Ok((alloc_id, _offset, _ptr)) = self.ecx.memory.ptr_try_get_alloc(place.ptr) {
437-
// not a ZST
436+
// Special handling for pointers to statics (irrespective of their type).
438437
let alloc_kind = self.ecx.tcx.get_global_alloc(alloc_id);
439438
if let Some(GlobalAlloc::Static(did)) = alloc_kind {
440439
assert!(!self.ecx.tcx.is_thread_local_static(did));
@@ -469,7 +468,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
469468
// We need to clone the path anyway, make sure it gets created
470469
// with enough space for the additional `Deref`.
471470
let mut new_path = Vec::with_capacity(path.len() + 1);
472-
new_path.clone_from(path);
471+
new_path.extend(path);
473472
new_path.push(PathElem::Deref);
474473
new_path
475474
});

compiler/rustc_parse/src/parser/generics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ impl<'a> Parser<'a> {
118118
Some(this.parse_ty_param(attrs)?)
119119
} else if this.token.can_begin_type() {
120120
// Trying to write an associated type bound? (#26271)
121-
let snapshot = this.clone();
121+
let snapshot = this.create_snapshot_for_diagnostic();
122122
match this.parse_ty_where_predicate() {
123123
Ok(where_predicate) => {
124124
this.struct_span_err(
@@ -133,7 +133,7 @@ impl<'a> Parser<'a> {
133133
Err(err) => {
134134
err.cancel();
135135
// FIXME - maybe we should overwrite 'self' outside of `collect_tokens`?
136-
*this = snapshot;
136+
this.restore_snapshot(snapshot);
137137
return Ok((None, TrailingToken::None));
138138
}
139139
}

compiler/rustc_target/src/asm/aarch64.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl AArch64InlineAsmRegClass {
6464
match self {
6565
Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
6666
Self::vreg | Self::vreg_low16 => types! {
67-
fp: I8, I16, I32, I64, F32, F64,
67+
neon: I8, I16, I32, I64, F32, F64,
6868
VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2), VecF64(1),
6969
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
7070
},

library/core/src/char/decode.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
9191
None => self.iter.next()?,
9292
};
9393

94-
if u < 0xD800 || 0xDFFF < u {
94+
if !u.is_utf16_surrogate() {
9595
// SAFETY: not a surrogate
9696
Some(Ok(unsafe { from_u32_unchecked(u as u32) }))
9797
} else if u >= 0xDC00 {
@@ -125,7 +125,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
125125
// buf is empty, no additional elements from it.
126126
None => (0, 0),
127127
// `u` is a non surrogate, so it's always an additional character.
128-
Some(u) if u < 0xD800 || 0xDFFF < u => (1, 1),
128+
Some(u) if !u.is_utf16_surrogate() => (1, 1),
129129
// `u` is a leading surrogate (it can never be a trailing surrogate and
130130
// it's a surrogate due to the previous branch) and `self.iter` is empty.
131131
//

library/core/src/iter/traits/iterator.rs

+16
Original file line numberDiff line numberDiff line change
@@ -3189,6 +3189,10 @@ pub trait Iterator {
31893189
/// This is useful when you have an iterator over `&T`, but you need an
31903190
/// iterator over `T`.
31913191
///
3192+
/// There is no guarantee whatsoever about the `clone` method actually
3193+
/// being called *or* optimized away. So code should not depend on
3194+
/// either.
3195+
///
31923196
/// [`clone`]: Clone::clone
31933197
///
31943198
/// # Examples
@@ -3206,6 +3210,18 @@ pub trait Iterator {
32063210
/// assert_eq!(v_cloned, vec![1, 2, 3]);
32073211
/// assert_eq!(v_map, vec![1, 2, 3]);
32083212
/// ```
3213+
///
3214+
/// To get the best performance, try to clone late:
3215+
///
3216+
/// ```
3217+
/// let a = [vec![0_u8, 1, 2], vec![3, 4], vec![23]];
3218+
/// // don't do this:
3219+
/// let slower: Vec<_> = a.iter().cloned().filter(|s| s.len() == 1).collect();
3220+
/// assert_eq!(&[vec![23]], &slower[..]);
3221+
/// // instead call `cloned` late
3222+
/// let faster: Vec<_> = a.iter().filter(|s| s.len() == 1).cloned().collect();
3223+
/// assert_eq!(&[vec![23]], &faster[..]);
3224+
/// ```
32093225
#[stable(feature = "rust1", since = "1.0.0")]
32103226
fn cloned<'a, T: 'a>(self) -> Cloned<Self>
32113227
where

library/core/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
#![warn(missing_docs)]
9494
#![allow(explicit_outlives_requirements)]
9595
//
96-
// Library features for const fns:
96+
// Library features:
9797
#![feature(const_align_offset)]
9898
#![feature(const_align_of_val)]
9999
#![feature(const_alloc_layout)]
@@ -146,6 +146,8 @@
146146
#![feature(ptr_metadata)]
147147
#![feature(slice_ptr_get)]
148148
#![feature(str_internals)]
149+
#![feature(utf16_extra)]
150+
#![feature(utf16_extra_const)]
149151
#![feature(variant_count)]
150152
#![feature(const_array_from_ref)]
151153
#![feature(const_slice_from_ref)]

library/core/src/num/mod.rs

+25
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,31 @@ impl u16 {
820820
uint_impl! { u16, u16, i16, NonZeroU16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
821821
"[0x34, 0x12]", "[0x12, 0x34]", "", "" }
822822
widening_impl! { u16, u32, 16, unsigned }
823+
824+
/// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`].
825+
///
826+
/// # Examples
827+
///
828+
/// ```
829+
/// #![feature(utf16_extra)]
830+
///
831+
/// let low_non_surrogate = 0xA000u16;
832+
/// let low_surrogate = 0xD800u16;
833+
/// let high_surrogate = 0xDC00u16;
834+
/// let high_non_surrogate = 0xE000u16;
835+
///
836+
/// assert!(!low_non_surrogate.is_utf16_surrogate());
837+
/// assert!(low_surrogate.is_utf16_surrogate());
838+
/// assert!(high_surrogate.is_utf16_surrogate());
839+
/// assert!(!high_non_surrogate.is_utf16_surrogate());
840+
/// ```
841+
#[must_use]
842+
#[unstable(feature = "utf16_extra", issue = "94919")]
843+
#[rustc_const_unstable(feature = "utf16_extra_const", issue = "94919")]
844+
#[inline]
845+
pub const fn is_utf16_surrogate(self) -> bool {
846+
matches!(self, 0xD800..=0xDFFF)
847+
}
823848
}
824849

825850
#[lang = "u32"]

library/std/tests/run-time-detect.rs

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ fn aarch64_linux() {
2929
println!("neon: {}", is_aarch64_feature_detected!("neon"));
3030
println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
3131
println!("pmull: {}", is_aarch64_feature_detected!("pmull"));
32-
println!("fp: {}", is_aarch64_feature_detected!("fp"));
3332
println!("fp16: {}", is_aarch64_feature_detected!("fp16"));
3433
println!("sve: {}", is_aarch64_feature_detected!("sve"));
3534
println!("crc: {}", is_aarch64_feature_detected!("crc"));
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
-include ../tools.mk
22

33
all:
4-
$(RUSTC) --edition=2018 --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg feature=\"external_crate\" --cfg no_global_oom_handling
4+
$(RUSTC) --edition=2021 --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg no_global_oom_handling

src/test/run-make-fulldeps/simd-ffi/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ define MK_TARGETS
4141
# now.
4242
$(1): simd.rs
4343
$$(RUSTC) --target=$(1) --emit=llvm-ir,asm simd.rs \
44-
-C target-feature='+fp,+neon,+sse2' -C extra-filename=-$(1)
44+
-C target-feature='+neon,+sse2' -C extra-filename=-$(1)
4545
endef
4646

4747
$(foreach targetxxx,$(TARGETS),$(eval $(call MK_TARGETS,$(targetxxx))))

src/test/ui/asm/aarch64/bad-reg.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// only-aarch64
2-
// compile-flags: -C target-feature=+fp
2+
// compile-flags: -C target-feature=+neon
33

44
#![feature(asm_const, asm_sym)]
55

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// only-aarch64
2+
// run-pass
3+
#![allow(dead_code)]
4+
use std::arch::*;
5+
use std::arch::aarch64::*;
6+
7+
// Smoke test to verify aarch64 code that enables NEON compiles.
8+
fn main() {
9+
let _zero = if is_aarch64_feature_detected!("neon") {
10+
unsafe {
11+
let zeros = zero_vector();
12+
vgetq_lane_u8::<1>(zeros)
13+
}
14+
} else {
15+
0
16+
};
17+
}
18+
19+
20+
#[target_feature(enable = "neon")]
21+
unsafe fn zero_vector() -> uint8x16_t {
22+
vmovq_n_u8(0)
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// revisions: aarch64-neon aarch64-sve2
2+
// [aarch64-neon] compile-flags: -Ctarget-feature=+neon --target=aarch64-unknown-linux-gnu
3+
// [aarch64-neon] needs-llvm-components: aarch64
4+
// [aarch64-sve2] compile-flags: -Ctarget-feature=-neon,+sve2 --target=aarch64-unknown-linux-gnu
5+
// [aarch64-sve2] needs-llvm-components: aarch64
6+
// build-pass
7+
#![no_core]
8+
#![crate_type = "rlib"]
9+
#![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api)]
10+
#![stable(feature = "test", since = "1.0.0")]
11+
12+
// Tests vetting "feature hierarchies" in the cases where we impose them.
13+
14+
// Supporting minimal rust core code
15+
#[lang = "sized"]
16+
trait Sized {}
17+
#[lang = "copy"]
18+
trait Copy {}
19+
impl Copy for bool {}
20+
21+
extern "rust-intrinsic" {
22+
#[rustc_const_stable(feature = "test", since = "1.0.0")]
23+
fn unreachable() -> !;
24+
}
25+
26+
#[rustc_builtin_macro]
27+
macro_rules! cfg {
28+
($($cfg:tt)*) => {};
29+
}
30+
31+
// Test code
32+
const fn do_or_die(cond: bool) {
33+
if cond {
34+
} else {
35+
unsafe { unreachable() }
36+
}
37+
}
38+
39+
macro_rules! assert {
40+
($x:expr $(,)?) => {
41+
const _: () = do_or_die($x);
42+
};
43+
}
44+
45+
46+
#[cfg(aarch64_neon)]
47+
fn check_neon_not_sve2() {
48+
// This checks that a normal aarch64 target doesn't suddenly jump up the feature hierarchy.
49+
assert!(cfg!(target_feature = "neon"));
50+
assert!(cfg!(not(target_feature = "sve2")));
51+
}
52+
53+
#[cfg(aarch64_sve2)]
54+
fn check_sve2_includes_neon() {
55+
// This checks that aarch64's sve2 includes neon
56+
assert!(cfg!(target_feature = "neon"));
57+
assert!(cfg!(target_feature = "sve2"));
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// revisions: aarch64 x86-64
2+
// [aarch64] compile-flags: -Ctarget-feature=+neon,+fp16,+fhm --target=aarch64-unknown-linux-gnu
3+
// [aarch64] needs-llvm-components: aarch64
4+
// [x86-64] compile-flags: -Ctarget-feature=+sse4.2,+rdrand --target=x86_64-unknown-linux-gnu
5+
// [x86-64] needs-llvm-components: x86
6+
// build-pass
7+
#![no_core]
8+
#![crate_type = "rlib"]
9+
#![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api)]
10+
#![stable(feature = "test", since = "1.0.0")]
11+
12+
// Supporting minimal rust core code
13+
#[lang = "sized"]
14+
trait Sized {}
15+
#[lang = "copy"]
16+
trait Copy {}
17+
impl Copy for bool {}
18+
19+
extern "rust-intrinsic" {
20+
#[rustc_const_stable(feature = "test", since = "1.0.0")]
21+
fn unreachable() -> !;
22+
}
23+
24+
#[rustc_builtin_macro]
25+
macro_rules! cfg {
26+
($($cfg:tt)*) => {};
27+
}
28+
29+
// Test code
30+
const fn do_or_die(cond: bool) {
31+
if cond {
32+
} else {
33+
unsafe { unreachable() }
34+
}
35+
}
36+
37+
macro_rules! assert {
38+
($x:expr $(,)?) => {
39+
const _: () = do_or_die($x);
40+
};
41+
}
42+
43+
44+
#[cfg(target_arch = "aarch64")]
45+
fn check_aarch64() {
46+
// This checks that the rustc feature name is used, not the LLVM feature.
47+
assert!(cfg!(target_feature = "neon"));
48+
assert!(cfg!(not(target_feature = "fp-armv8")));
49+
assert!(cfg!(target_feature = "fhm"));
50+
assert!(cfg!(not(target_feature = "fp16fml")));
51+
assert!(cfg!(target_feature = "fp16"));
52+
assert!(cfg!(not(target_feature = "fullfp16")));
53+
}
54+
55+
#[cfg(target_arch = "x86_64")]
56+
fn check_x86_64() {
57+
// This checks that the rustc feature name is used, not the LLVM feature.
58+
assert!(cfg!(target_feature = "rdrand"));
59+
assert!(cfg!(not(target_feature = "rdrnd")));
60+
61+
// Likewise: We enable LLVM's crc32 feature with SSE4.2, but Rust says it's just SSE4.2
62+
assert!(cfg!(target_feature = "sse4.2"));
63+
assert!(cfg!(not(target_feature = "crc32")));
64+
}

0 commit comments

Comments
 (0)