Skip to content
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

Rollup of 6 pull requests #95223

Merged
merged 16 commits into from
Mar 23, 2022
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: 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")));
}