Skip to content

Commit

Permalink
Auto merge of #95223 - Dylan-DPC:rollup-idpb7ka, r=Dylan-DPC
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Mar 23, 2022
2 parents 2b50739 + 2f24923 commit 7b0bf9e
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 21 deletions.
10 changes: 6 additions & 4 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]
("x86", "avx512vaes") => smallvec!["vaes"],
("x86", "avx512gfni") => smallvec!["gfni"],
("x86", "avx512vpclmulqdq") => smallvec!["vpclmulqdq"],
("aarch64", "fp") => smallvec!["fp-armv8"],
("aarch64", "rcpc2") => smallvec!["rcpc-immo"],
("aarch64", "dpb") => smallvec!["ccpp"],
("aarch64", "dpb2") => smallvec!["ccdp"],
Expand Down Expand Up @@ -230,6 +229,8 @@ pub fn check_tied_features(
None
}

// Used to generate cfg variables and apply features
// Must express features in the way Rust understands them
pub fn target_features(sess: &Session) -> Vec<Symbol> {
let target_machine = create_informational_target_machine(sess);
let mut features: Vec<Symbol> =
Expand All @@ -239,13 +240,14 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
if sess.is_nightly_build() || gate.is_none() { Some(feature) } else { None }
})
.filter(|feature| {
// check that all features in a given smallvec are enabled
for llvm_feature in to_llvm_features(sess, feature) {
let cstr = SmallCStr::new(llvm_feature);
if unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
return true;
if !unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
return false;
}
}
false
true
})
.map(|feature| Symbol::intern(feature))
.collect();
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
];

const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
// FEAT_AdvSimd
// FEAT_AdvSimd & FEAT_FP
("neon", None),
// FEAT_FP
("fp", None),
// FEAT_FP16
("fp16", None),
// FEAT_SVE
Expand Down Expand Up @@ -143,7 +141,6 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
];

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

Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
if let Some(ref mut ref_tracking) = self.ref_tracking {
// Proceed recursively even for ZST, no reason to skip them!
// `!` is a ZST and we want to validate it.
// Skip validation entirely for some external statics
if let Ok((alloc_id, _offset, _ptr)) = self.ecx.memory.ptr_try_get_alloc(place.ptr) {
// not a ZST
// Special handling for pointers to statics (irrespective of their type).
let alloc_kind = self.ecx.tcx.get_global_alloc(alloc_id);
if let Some(GlobalAlloc::Static(did)) = alloc_kind {
assert!(!self.ecx.tcx.is_thread_local_static(did));
Expand Down Expand Up @@ -469,7 +468,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// We need to clone the path anyway, make sure it gets created
// with enough space for the additional `Deref`.
let mut new_path = Vec::with_capacity(path.len() + 1);
new_path.clone_from(path);
new_path.extend(path);
new_path.push(PathElem::Deref);
new_path
});
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl<'a> Parser<'a> {
Some(this.parse_ty_param(attrs)?)
} else if this.token.can_begin_type() {
// Trying to write an associated type bound? (#26271)
let snapshot = this.clone();
let snapshot = this.create_snapshot_for_diagnostic();
match this.parse_ty_where_predicate() {
Ok(where_predicate) => {
this.struct_span_err(
Expand All @@ -133,7 +133,7 @@ impl<'a> Parser<'a> {
Err(err) => {
err.cancel();
// FIXME - maybe we should overwrite 'self' outside of `collect_tokens`?
*this = snapshot;
this.restore_snapshot(snapshot);
return Ok((None, TrailingToken::None));
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/asm/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl AArch64InlineAsmRegClass {
match self {
Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
Self::vreg | Self::vreg_low16 => types! {
fp: I8, I16, I32, I64, F32, F64,
neon: I8, I16, I32, I64, F32, F64,
VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2), VecF64(1),
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
},
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/char/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
None => self.iter.next()?,
};

if u < 0xD800 || 0xDFFF < u {
if !u.is_utf16_surrogate() {
// SAFETY: not a surrogate
Some(Ok(unsafe { from_u32_unchecked(u as u32) }))
} else if u >= 0xDC00 {
Expand Down Expand Up @@ -125,7 +125,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
// buf is empty, no additional elements from it.
None => (0, 0),
// `u` is a non surrogate, so it's always an additional character.
Some(u) if u < 0xD800 || 0xDFFF < u => (1, 1),
Some(u) if !u.is_utf16_surrogate() => (1, 1),
// `u` is a leading surrogate (it can never be a trailing surrogate and
// it's a surrogate due to the previous branch) and `self.iter` is empty.
//
Expand Down
16 changes: 16 additions & 0 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3189,6 +3189,10 @@ pub trait Iterator {
/// This is useful when you have an iterator over `&T`, but you need an
/// iterator over `T`.
///
/// There is no guarantee whatsoever about the `clone` method actually
/// being called *or* optimized away. So code should not depend on
/// either.
///
/// [`clone`]: Clone::clone
///
/// # Examples
Expand All @@ -3206,6 +3210,18 @@ pub trait Iterator {
/// assert_eq!(v_cloned, vec![1, 2, 3]);
/// assert_eq!(v_map, vec![1, 2, 3]);
/// ```
///
/// To get the best performance, try to clone late:
///
/// ```
/// let a = [vec![0_u8, 1, 2], vec![3, 4], vec![23]];
/// // don't do this:
/// let slower: Vec<_> = a.iter().cloned().filter(|s| s.len() == 1).collect();
/// assert_eq!(&[vec![23]], &slower[..]);
/// // instead call `cloned` late
/// let faster: Vec<_> = a.iter().filter(|s| s.len() == 1).cloned().collect();
/// assert_eq!(&[vec![23]], &faster[..]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn cloned<'a, T: 'a>(self) -> Cloned<Self>
where
Expand Down
4 changes: 3 additions & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
#![warn(missing_docs)]
#![allow(explicit_outlives_requirements)]
//
// Library features for const fns:
// Library features:
#![feature(const_align_offset)]
#![feature(const_align_of_val)]
#![feature(const_alloc_layout)]
Expand Down Expand Up @@ -146,6 +146,8 @@
#![feature(ptr_metadata)]
#![feature(slice_ptr_get)]
#![feature(str_internals)]
#![feature(utf16_extra)]
#![feature(utf16_extra_const)]
#![feature(variant_count)]
#![feature(const_array_from_ref)]
#![feature(const_slice_from_ref)]
Expand Down
25 changes: 25 additions & 0 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,31 @@ impl u16 {
uint_impl! { u16, u16, i16, NonZeroU16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
"[0x34, 0x12]", "[0x12, 0x34]", "", "" }
widening_impl! { u16, u32, 16, unsigned }

/// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`].
///
/// # Examples
///
/// ```
/// #![feature(utf16_extra)]
///
/// let low_non_surrogate = 0xA000u16;
/// let low_surrogate = 0xD800u16;
/// let high_surrogate = 0xDC00u16;
/// let high_non_surrogate = 0xE000u16;
///
/// assert!(!low_non_surrogate.is_utf16_surrogate());
/// assert!(low_surrogate.is_utf16_surrogate());
/// assert!(high_surrogate.is_utf16_surrogate());
/// assert!(!high_non_surrogate.is_utf16_surrogate());
/// ```
#[must_use]
#[unstable(feature = "utf16_extra", issue = "94919")]
#[rustc_const_unstable(feature = "utf16_extra_const", issue = "94919")]
#[inline]
pub const fn is_utf16_surrogate(self) -> bool {
matches!(self, 0xD800..=0xDFFF)
}
}

#[lang = "u32"]
Expand Down
1 change: 0 additions & 1 deletion library/std/tests/run-time-detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ fn aarch64_linux() {
println!("neon: {}", is_aarch64_feature_detected!("neon"));
println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
println!("pmull: {}", is_aarch64_feature_detected!("pmull"));
println!("fp: {}", is_aarch64_feature_detected!("fp"));
println!("fp16: {}", is_aarch64_feature_detected!("fp16"));
println!("sve: {}", is_aarch64_feature_detected!("sve"));
println!("crc: {}", is_aarch64_feature_detected!("crc"));
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-include ../tools.mk

all:
$(RUSTC) --edition=2018 --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg feature=\"external_crate\" --cfg no_global_oom_handling
$(RUSTC) --edition=2021 --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg no_global_oom_handling
2 changes: 1 addition & 1 deletion src/test/run-make-fulldeps/simd-ffi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ define MK_TARGETS
# now.
$(1): simd.rs
$$(RUSTC) --target=$(1) --emit=llvm-ir,asm simd.rs \
-C target-feature='+fp,+neon,+sse2' -C extra-filename=-$(1)
-C target-feature='+neon,+sse2' -C extra-filename=-$(1)
endef

$(foreach targetxxx,$(TARGETS),$(eval $(call MK_TARGETS,$(targetxxx))))
2 changes: 1 addition & 1 deletion src/test/ui/asm/aarch64/bad-reg.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// only-aarch64
// compile-flags: -C target-feature=+fp
// compile-flags: -C target-feature=+neon

#![feature(asm_const, asm_sym)]

Expand Down
23 changes: 23 additions & 0 deletions src/test/ui/target-feature/aarch64-neon-works.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// only-aarch64
// run-pass
#![allow(dead_code)]
use std::arch::*;
use std::arch::aarch64::*;

// Smoke test to verify aarch64 code that enables NEON compiles.
fn main() {
let _zero = if is_aarch64_feature_detected!("neon") {
unsafe {
let zeros = zero_vector();
vgetq_lane_u8::<1>(zeros)
}
} else {
0
};
}


#[target_feature(enable = "neon")]
unsafe fn zero_vector() -> uint8x16_t {
vmovq_n_u8(0)
}
58 changes: 58 additions & 0 deletions src/test/ui/target-feature/feature-hierarchy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// revisions: aarch64-neon aarch64-sve2
// [aarch64-neon] compile-flags: -Ctarget-feature=+neon --target=aarch64-unknown-linux-gnu
// [aarch64-neon] needs-llvm-components: aarch64
// [aarch64-sve2] compile-flags: -Ctarget-feature=-neon,+sve2 --target=aarch64-unknown-linux-gnu
// [aarch64-sve2] needs-llvm-components: aarch64
// build-pass
#![no_core]
#![crate_type = "rlib"]
#![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api)]
#![stable(feature = "test", since = "1.0.0")]

// Tests vetting "feature hierarchies" in the cases where we impose them.

// Supporting minimal rust core code
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
impl Copy for bool {}

extern "rust-intrinsic" {
#[rustc_const_stable(feature = "test", since = "1.0.0")]
fn unreachable() -> !;
}

#[rustc_builtin_macro]
macro_rules! cfg {
($($cfg:tt)*) => {};
}

// Test code
const fn do_or_die(cond: bool) {
if cond {
} else {
unsafe { unreachable() }
}
}

macro_rules! assert {
($x:expr $(,)?) => {
const _: () = do_or_die($x);
};
}


#[cfg(aarch64_neon)]
fn check_neon_not_sve2() {
// This checks that a normal aarch64 target doesn't suddenly jump up the feature hierarchy.
assert!(cfg!(target_feature = "neon"));
assert!(cfg!(not(target_feature = "sve2")));
}

#[cfg(aarch64_sve2)]
fn check_sve2_includes_neon() {
// This checks that aarch64's sve2 includes neon
assert!(cfg!(target_feature = "neon"));
assert!(cfg!(target_feature = "sve2"));
}
64 changes: 64 additions & 0 deletions src/test/ui/target-feature/no-llvm-leaks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// revisions: aarch64 x86-64
// [aarch64] compile-flags: -Ctarget-feature=+neon,+fp16,+fhm --target=aarch64-unknown-linux-gnu
// [aarch64] needs-llvm-components: aarch64
// [x86-64] compile-flags: -Ctarget-feature=+sse4.2,+rdrand --target=x86_64-unknown-linux-gnu
// [x86-64] needs-llvm-components: x86
// build-pass
#![no_core]
#![crate_type = "rlib"]
#![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api)]
#![stable(feature = "test", since = "1.0.0")]

// Supporting minimal rust core code
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
impl Copy for bool {}

extern "rust-intrinsic" {
#[rustc_const_stable(feature = "test", since = "1.0.0")]
fn unreachable() -> !;
}

#[rustc_builtin_macro]
macro_rules! cfg {
($($cfg:tt)*) => {};
}

// Test code
const fn do_or_die(cond: bool) {
if cond {
} else {
unsafe { unreachable() }
}
}

macro_rules! assert {
($x:expr $(,)?) => {
const _: () = do_or_die($x);
};
}


#[cfg(target_arch = "aarch64")]
fn check_aarch64() {
// This checks that the rustc feature name is used, not the LLVM feature.
assert!(cfg!(target_feature = "neon"));
assert!(cfg!(not(target_feature = "fp-armv8")));
assert!(cfg!(target_feature = "fhm"));
assert!(cfg!(not(target_feature = "fp16fml")));
assert!(cfg!(target_feature = "fp16"));
assert!(cfg!(not(target_feature = "fullfp16")));
}

#[cfg(target_arch = "x86_64")]
fn check_x86_64() {
// This checks that the rustc feature name is used, not the LLVM feature.
assert!(cfg!(target_feature = "rdrand"));
assert!(cfg!(not(target_feature = "rdrnd")));

// Likewise: We enable LLVM's crc32 feature with SSE4.2, but Rust says it's just SSE4.2
assert!(cfg!(target_feature = "sse4.2"));
assert!(cfg!(not(target_feature = "crc32")));
}

0 comments on commit 7b0bf9e

Please sign in to comment.