mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #151533 - JonathanBrouwer:rollup-P3oXrte, r=JonathanBrouwer
Rollup of 5 pull requests Successful merges: - rust-lang/rust#149639 (inline constant localized typeck constraint computation) - rust-lang/rust#150780 (Add -Z large-data-threshold) - rust-lang/rust#151520 (Rename `HandleCycleError` to `CycleErrorHandling`) - rust-lang/rust#151525 (update enzyme, includes an extra patch to fix MacOS builds in CI) - rust-lang/rust#151527 (Clean up or resolve cfg-related instances of `FIXME(f16_f128)`) r? @ghost
This commit is contained in:
@@ -45,7 +45,6 @@ pub(super) fn convert_typeck_constraints<'tcx>(
|
||||
{
|
||||
localize_statement_constraint(
|
||||
tcx,
|
||||
body,
|
||||
stmt,
|
||||
&outlives_constraint,
|
||||
point,
|
||||
@@ -74,7 +73,6 @@ pub(super) fn convert_typeck_constraints<'tcx>(
|
||||
/// needed CFG `from`-`to` intra-block nodes.
|
||||
fn localize_statement_constraint<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
stmt: &Statement<'tcx>,
|
||||
outlives_constraint: &OutlivesConstraint<'tcx>,
|
||||
current_point: PointIndex,
|
||||
@@ -114,28 +112,22 @@ fn localize_statement_constraint<'tcx>(
|
||||
},
|
||||
"there should be no common regions between the LHS and RHS of an assignment"
|
||||
);
|
||||
|
||||
let lhs_ty = body.local_decls[lhs.local].ty;
|
||||
let successor_point = current_point;
|
||||
compute_constraint_direction(
|
||||
tcx,
|
||||
outlives_constraint,
|
||||
&lhs_ty,
|
||||
current_point,
|
||||
successor_point,
|
||||
universal_regions,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
// For the other cases, we localize an outlives constraint to where it arises.
|
||||
LocalizedOutlivesConstraint {
|
||||
source: outlives_constraint.sup,
|
||||
from: current_point,
|
||||
target: outlives_constraint.sub,
|
||||
to: current_point,
|
||||
}
|
||||
// Assignments should be the only statement that can both generate constraints that
|
||||
// apply on entry (specific to the RHS place) *and* others that only apply on exit (the
|
||||
// subset of RHS regions that actually flow into the LHS): i.e., where midpoints would
|
||||
// be used to ensure the former happen before the latter, within the same MIR Location.
|
||||
}
|
||||
}
|
||||
|
||||
// We generally localize an outlives constraint to where it arises.
|
||||
LocalizedOutlivesConstraint {
|
||||
source: outlives_constraint.sup,
|
||||
from: current_point,
|
||||
target: outlives_constraint.sub,
|
||||
to: current_point,
|
||||
}
|
||||
}
|
||||
|
||||
/// For a given outlives constraint arising from a MIR terminator, localize the constraint with the
|
||||
@@ -150,14 +142,12 @@ fn localize_terminator_constraint<'tcx>(
|
||||
universal_regions: &UniversalRegions<'tcx>,
|
||||
) -> LocalizedOutlivesConstraint {
|
||||
// FIXME: check if other terminators need the same handling as `Call`s, in particular
|
||||
// Assert/Yield/Drop. A handful of tests are failing with Drop related issues, as well as some
|
||||
// coroutine tests, and that may be why.
|
||||
// Assert/Yield/Drop.
|
||||
match &terminator.kind {
|
||||
// FIXME: also handle diverging calls.
|
||||
TerminatorKind::Call { destination, target: Some(target), .. } => {
|
||||
// Calls are similar to assignments, and thus follow the same pattern. If there is a
|
||||
// target for the call we also relate what flows into the destination here to entry to
|
||||
// that successor.
|
||||
// If there is a target for the call we also relate what flows into the destination here
|
||||
// to entry to that successor.
|
||||
let destination_ty = destination.ty(&body.local_decls, tcx);
|
||||
let successor_location = Location { block: *target, statement_index: 0 };
|
||||
let successor_point = liveness.point_from_location(successor_location);
|
||||
|
||||
@@ -39,6 +39,7 @@ pub(crate) fn new(
|
||||
debug_info_compression: llvm::CompressionKind,
|
||||
use_emulated_tls: bool,
|
||||
use_wasm_eh: bool,
|
||||
large_data_threshold: u64,
|
||||
) -> Result<Self, LlvmError<'static>> {
|
||||
// SAFETY: llvm::LLVMRustCreateTargetMachine copies pointed to data
|
||||
let tm_ptr = unsafe {
|
||||
@@ -65,6 +66,7 @@ pub(crate) fn new(
|
||||
debug_info_compression,
|
||||
use_emulated_tls,
|
||||
use_wasm_eh,
|
||||
large_data_threshold,
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
@@ -275,6 +275,8 @@ pub(crate) fn target_machine_factory(
|
||||
|
||||
let use_wasm_eh = wants_wasm_eh(sess);
|
||||
|
||||
let large_data_threshold = sess.opts.unstable_opts.large_data_threshold.unwrap_or(0);
|
||||
|
||||
let prof = SelfProfilerRef::clone(&sess.prof);
|
||||
Arc::new(move |config: TargetMachineFactoryConfig| {
|
||||
// Self-profile timer for invoking a factory to create a target machine.
|
||||
@@ -316,6 +318,7 @@ pub(crate) fn target_machine_factory(
|
||||
debuginfo_compression,
|
||||
use_emulated_tls,
|
||||
use_wasm_eh,
|
||||
large_data_threshold,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -665,8 +665,8 @@ fn msvc_basic_name(self) -> &'static str {
|
||||
|
||||
impl MsvcBasicName for ty::FloatTy {
|
||||
fn msvc_basic_name(self) -> &'static str {
|
||||
// FIXME(f16_f128): `f16` and `f128` have no MSVC representation. We could improve the
|
||||
// debuginfo. See: <https://github.com/rust-lang/rust/issues/121837>
|
||||
// FIXME(f128): `f128` has no MSVC representation. We could improve the debuginfo.
|
||||
// See: <https://github.com/rust-lang/rust/issues/121837>
|
||||
match self {
|
||||
ty::FloatTy::F16 => {
|
||||
bug!("`f16` should have been handled in `build_basic_type_di_node`")
|
||||
|
||||
@@ -2347,6 +2347,7 @@ pub(crate) fn LLVMRustCreateTargetMachine(
|
||||
DebugInfoCompression: CompressionKind,
|
||||
UseEmulatedTls: bool,
|
||||
UseWasmEH: bool,
|
||||
LargeDataThreshold: u64,
|
||||
) -> *mut TargetMachine;
|
||||
|
||||
pub(crate) fn LLVMRustAddLibraryInfo<'a>(
|
||||
|
||||
@@ -305,7 +305,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||
bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray,
|
||||
const char *SplitDwarfFile, const char *OutputObjFile,
|
||||
LLVMRustCompressionKind DebugInfoCompression, bool UseEmulatedTls,
|
||||
bool UseWasmEH) {
|
||||
bool UseWasmEH, uint64_t LargeDataThreshold) {
|
||||
|
||||
auto OptLevel = fromRust(RustOptLevel);
|
||||
auto RM = fromRust(RustReloc);
|
||||
@@ -381,6 +381,11 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||
TargetMachine *TM = TheTarget->createTargetMachine(
|
||||
Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
|
||||
#endif
|
||||
|
||||
if (LargeDataThreshold != 0) {
|
||||
TM->setLargeDataThreshold(LargeDataThreshold);
|
||||
}
|
||||
|
||||
return wrap(TM);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::hir_id::OwnerId;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_query_system::HandleCycleError;
|
||||
use rustc_query_system::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
|
||||
pub(crate) use rustc_query_system::query::QueryJobId;
|
||||
use rustc_query_system::query::*;
|
||||
use rustc_query_system::query::{CycleError, CycleErrorHandling, HashResult, QueryCache};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
pub use sealed::IntoQueryParam;
|
||||
|
||||
@@ -23,7 +22,8 @@ pub struct DynamicQuery<'tcx, C: QueryCache> {
|
||||
pub name: &'static str,
|
||||
pub eval_always: bool,
|
||||
pub dep_kind: DepKind,
|
||||
pub handle_cycle_error: HandleCycleError,
|
||||
/// How this query deals with query cycle errors.
|
||||
pub cycle_error_handling: CycleErrorHandling,
|
||||
// Offset of this query's state field in the QueryStates struct
|
||||
pub query_state: usize,
|
||||
// Offset of this query's cache field in the QueryCaches struct
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
queries,
|
||||
};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_query_system::Value;
|
||||
use rustc_query_system::dep_graph::SerializedDepNodeIndex;
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_query_system::query::{
|
||||
CycleError, HashResult, QueryCache, QueryConfig, QueryMap, QueryMode, QueryState,
|
||||
get_query_incr, get_query_non_incr,
|
||||
CycleError, CycleErrorHandling, HashResult, QueryCache, QueryConfig, QueryMap, QueryMode,
|
||||
QueryState, get_query_incr, get_query_non_incr,
|
||||
};
|
||||
use rustc_query_system::{HandleCycleError, Value};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
|
||||
use crate::plumbing::{__rust_begin_short_backtrace, encode_all_query_results, try_mark_green};
|
||||
@@ -181,8 +181,8 @@ fn dep_kind(self) -> DepKind {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn handle_cycle_error(self) -> HandleCycleError {
|
||||
self.dynamic.handle_cycle_error
|
||||
fn cycle_error_handling(self) -> CycleErrorHandling {
|
||||
self.dynamic.cycle_error_handling
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
||||
@@ -199,21 +199,21 @@ pub fn query_key_hash_verify_all<'tcx>(tcx: TyCtxt<'tcx>) {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! handle_cycle_error {
|
||||
macro_rules! cycle_error_handling {
|
||||
([]) => {{
|
||||
rustc_query_system::HandleCycleError::Error
|
||||
rustc_query_system::query::CycleErrorHandling::Error
|
||||
}};
|
||||
([(cycle_fatal) $($rest:tt)*]) => {{
|
||||
rustc_query_system::HandleCycleError::Fatal
|
||||
rustc_query_system::query::CycleErrorHandling::Fatal
|
||||
}};
|
||||
([(cycle_stash) $($rest:tt)*]) => {{
|
||||
rustc_query_system::HandleCycleError::Stash
|
||||
rustc_query_system::query::CycleErrorHandling::Stash
|
||||
}};
|
||||
([(cycle_delay_bug) $($rest:tt)*]) => {{
|
||||
rustc_query_system::HandleCycleError::DelayBug
|
||||
rustc_query_system::query::CycleErrorHandling::DelayBug
|
||||
}};
|
||||
([$other:tt $($modifiers:tt)*]) => {
|
||||
handle_cycle_error!([$($modifiers)*])
|
||||
cycle_error_handling!([$($modifiers)*])
|
||||
};
|
||||
}
|
||||
|
||||
@@ -618,7 +618,7 @@ pub(crate) fn dynamic_query<'tcx>()
|
||||
name: stringify!($name),
|
||||
eval_always: is_eval_always!([$($modifiers)*]),
|
||||
dep_kind: dep_graph::dep_kinds::$name,
|
||||
handle_cycle_error: handle_cycle_error!([$($modifiers)*]),
|
||||
cycle_error_handling: cycle_error_handling!([$($modifiers)*]),
|
||||
query_state: std::mem::offset_of!(QueryStates<'tcx>, $name),
|
||||
query_cache: std::mem::offset_of!(QueryCaches<'tcx>, $name),
|
||||
cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key),
|
||||
|
||||
@@ -11,14 +11,6 @@ pub(crate) struct CycleStack {
|
||||
pub desc: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum HandleCycleError {
|
||||
Error,
|
||||
Fatal,
|
||||
DelayBug,
|
||||
Stash,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum StackCount {
|
||||
#[note(query_system_cycle_stack_single)]
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
pub mod query;
|
||||
mod values;
|
||||
|
||||
pub use error::{HandleCycleError, QueryOverflow, QueryOverflowNote};
|
||||
pub use error::{QueryOverflow, QueryOverflowNote};
|
||||
pub use values::Value;
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
@@ -7,10 +7,9 @@
|
||||
use rustc_span::ErrorGuaranteed;
|
||||
|
||||
use crate::dep_graph::{DepKind, DepNode, DepNodeParams, SerializedDepNodeIndex};
|
||||
use crate::error::HandleCycleError;
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::query::caches::QueryCache;
|
||||
use crate::query::{CycleError, DepNodeIndex, QueryContext, QueryState};
|
||||
use crate::query::{CycleError, CycleErrorHandling, DepNodeIndex, QueryContext, QueryState};
|
||||
|
||||
pub type HashResult<V> = Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>;
|
||||
|
||||
@@ -67,7 +66,7 @@ fn value_from_cycle_error(
|
||||
fn feedable(self) -> bool;
|
||||
|
||||
fn dep_kind(self) -> DepKind;
|
||||
fn handle_cycle_error(self) -> HandleCycleError;
|
||||
fn cycle_error_handling(self) -> CycleErrorHandling;
|
||||
fn hash_result(self) -> HashResult<Self::Value>;
|
||||
|
||||
// Just here for convenience and checking that the key matches the kind, don't override this.
|
||||
|
||||
@@ -20,6 +20,18 @@
|
||||
mod job;
|
||||
mod plumbing;
|
||||
|
||||
/// How a particular query deals with query cycle errors.
|
||||
///
|
||||
/// Inspected by the code that actually handles cycle errors, to decide what
|
||||
/// approach to use.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum CycleErrorHandling {
|
||||
Error,
|
||||
Fatal,
|
||||
DelayBug,
|
||||
Stash,
|
||||
}
|
||||
|
||||
/// Description of a frame in the query stack.
|
||||
///
|
||||
/// This is mostly used in case of cycles for error reporting.
|
||||
|
||||
@@ -19,12 +19,13 @@
|
||||
use tracing::instrument;
|
||||
|
||||
use super::QueryConfig;
|
||||
use crate::HandleCycleError;
|
||||
use crate::dep_graph::{DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeParams};
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::query::caches::QueryCache;
|
||||
use crate::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, report_cycle};
|
||||
use crate::query::{QueryContext, QueryMap, QueryStackFrame, SerializedDepNodeIndex};
|
||||
use crate::query::{
|
||||
CycleErrorHandling, QueryContext, QueryMap, QueryStackFrame, SerializedDepNodeIndex,
|
||||
};
|
||||
|
||||
#[inline]
|
||||
fn equivalent_key<K: Eq, V>(k: &K) -> impl Fn(&(K, V)) -> bool + '_ {
|
||||
@@ -142,22 +143,21 @@ fn handle_cycle_error<Q, Qcx>(
|
||||
Q: QueryConfig<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
use HandleCycleError::*;
|
||||
match query.handle_cycle_error() {
|
||||
Error => {
|
||||
match query.cycle_error_handling() {
|
||||
CycleErrorHandling::Error => {
|
||||
let guar = error.emit();
|
||||
query.value_from_cycle_error(*qcx.dep_context(), cycle_error, guar)
|
||||
}
|
||||
Fatal => {
|
||||
CycleErrorHandling::Fatal => {
|
||||
error.emit();
|
||||
qcx.dep_context().sess().dcx().abort_if_errors();
|
||||
unreachable!()
|
||||
}
|
||||
DelayBug => {
|
||||
CycleErrorHandling::DelayBug => {
|
||||
let guar = error.delay_as_bug();
|
||||
query.value_from_cycle_error(*qcx.dep_context(), cycle_error, guar)
|
||||
}
|
||||
Stash => {
|
||||
CycleErrorHandling::Stash => {
|
||||
let guar = if let Some(root) = cycle_error.cycle.first()
|
||||
&& let Some(span) = root.query.span
|
||||
{
|
||||
|
||||
@@ -2426,6 +2426,9 @@ pub(crate) fn parse_align(slot: &mut Option<Align>, v: Option<&str>) -> bool {
|
||||
`=skip-entry`
|
||||
`=skip-exit`
|
||||
Multiple options can be combined with commas."),
|
||||
large_data_threshold: Option<u64> = (None, parse_opt_number, [TRACKED],
|
||||
"set the threshold for objects to be stored in a \"large data\" section \
|
||||
(only effective with -Ccode-model=medium, default: 65536)"),
|
||||
layout_seed: Option<u64> = (None, parse_opt_number, [TRACKED],
|
||||
"seed layout randomization"),
|
||||
link_directives: bool = (true, parse_bool, [TRACKED],
|
||||
|
||||
@@ -47,7 +47,7 @@ pub fn supported_types(
|
||||
types! { _: I8, I16, I32, F16, F32; }
|
||||
}
|
||||
}
|
||||
// FIXME(f16_f128): Add `q: F128;` once LLVM support the `Q` extension.
|
||||
// FIXME(f128): Add `q: F128;` once LLVM support the `Q` extension.
|
||||
Self::freg => types! { f: F16, F32; d: F64; },
|
||||
Self::vreg => &[],
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ fn from(small: $Small) -> Self {
|
||||
// * 53 bits in f64
|
||||
// * 113 bits in f128
|
||||
// Lossy float conversions are not implemented at this time.
|
||||
// FIXME(f16_f128): The `f16`/`f128` impls `#[stable]` attributes should be changed to reference
|
||||
// FIXME(f16,f128): The `f16`/`f128` impls `#[stable]` attributes should be changed to reference
|
||||
// `f16`/`f128` when they are stabilised (trait impls have to have a `#[stable]` attribute, but none
|
||||
// of the `f16`/`f128` impls can be used on stable as the `f16` and `f128` types are unstable).
|
||||
|
||||
@@ -168,7 +168,7 @@ fn from(small: $Small) -> Self {
|
||||
impl_from!(i16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(i32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(i32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
// FIXME(f16_f128): This impl would allow using `f128` on stable before it is stabilised.
|
||||
// FIXME(f128): This impl would allow using `f128` on stable before it is stabilised.
|
||||
// impl_from!(i64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
|
||||
// unsigned integer -> float
|
||||
@@ -181,11 +181,11 @@ fn from(small: $Small) -> Self {
|
||||
impl_from!(u16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(u32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
// FIXME(f16_f128): This impl would allow using `f128` on stable before it is stabilised.
|
||||
// FIXME(f128): This impl would allow using `f128` on stable before it is stabilised.
|
||||
// impl_from!(u64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
|
||||
// float -> float
|
||||
// FIXME(f16_f128): adding additional `From<{float}>` impls to `f32` breaks inference. See
|
||||
// FIXME(f16,f128): adding additional `From<{float}>` impls to `f32` breaks inference. See
|
||||
// <https://github.com/rust-lang/rust/issues/123831>
|
||||
impl_from!(f16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
|
||||
@@ -236,7 +236,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
floating! { f16 }
|
||||
|
||||
// FIXME(f16_f128): A fallback is used when the backend+target does not support f16 well, in order
|
||||
// FIXME(f16): A fallback is used when the backend+target does not support f16 well, in order
|
||||
// to avoid ICEs.
|
||||
|
||||
#[cfg(not(target_has_reliable_f16))]
|
||||
|
||||
@@ -179,7 +179,7 @@ fn from_str(src: &str) -> Result<Self, ParseFloatError> {
|
||||
from_str_float_impl!(f32);
|
||||
from_str_float_impl!(f64);
|
||||
|
||||
// FIXME(f16_f128): A fallback is used when the backend+target does not support f16 well, in order
|
||||
// FIXME(f16): A fallback is used when the backend+target does not support f16 well, in order
|
||||
// to avoid ICEs.
|
||||
|
||||
#[cfg(not(target_has_reliable_f16))]
|
||||
|
||||
@@ -137,10 +137,8 @@ pub mod consts {
|
||||
pub const LN_10: f128 = 2.30258509299404568401799145468436420760110148862877297603333_f128;
|
||||
}
|
||||
|
||||
#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), allow(internal_features))))]
|
||||
impl f128 {
|
||||
// FIXME(f16_f128): almost all methods in this `impl` are missing examples and a const
|
||||
// implementation. Add these once we can run code on all platforms and have f16/f128 in CTFE.
|
||||
|
||||
/// The radix or base of the internal representation of `f128`.
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
pub const RADIX: u32 = 2;
|
||||
@@ -277,8 +275,7 @@ impl f128 {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `unordtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let nan = f128::NAN;
|
||||
/// let f = 7.0_f128;
|
||||
@@ -300,8 +297,7 @@ pub const fn is_nan(self) -> bool {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let f = 7.0f128;
|
||||
/// let inf = f128::INFINITY;
|
||||
@@ -326,8 +322,7 @@ pub const fn is_infinite(self) -> bool {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `lttf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let f = 7.0f128;
|
||||
/// let inf: f128 = f128::INFINITY;
|
||||
@@ -355,8 +350,7 @@ pub const fn is_finite(self) -> bool {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let min = f128::MIN_POSITIVE; // 3.362103143e-4932f128
|
||||
/// let max = f128::MAX;
|
||||
@@ -386,8 +380,7 @@ pub const fn is_subnormal(self) -> bool {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let min = f128::MIN_POSITIVE; // 3.362103143e-4932f128
|
||||
/// let max = f128::MAX;
|
||||
@@ -419,8 +412,7 @@ pub const fn is_normal(self) -> bool {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// use std::num::FpCategory;
|
||||
///
|
||||
@@ -514,8 +506,7 @@ pub const fn is_sign_negative(self) -> bool {
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// // f128::EPSILON is the difference between 1.0 and the next number up.
|
||||
/// assert_eq!(1.0f128.next_up(), 1.0 + f128::EPSILON);
|
||||
@@ -569,8 +560,7 @@ pub const fn next_up(self) -> Self {
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let x = 1.0f128;
|
||||
/// // Clamp value into range [0, 1).
|
||||
@@ -613,8 +603,7 @@ pub const fn next_down(self) -> Self {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let x = 2.0_f128;
|
||||
/// let abs_difference = (x.recip() - (1.0 / x)).abs();
|
||||
@@ -640,8 +629,7 @@ pub const fn recip(self) -> Self {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let angle = std::f128::consts::PI;
|
||||
///
|
||||
@@ -671,8 +659,7 @@ pub const fn to_degrees(self) -> Self {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let angle = 180.0f128;
|
||||
///
|
||||
@@ -706,8 +693,7 @@ pub const fn to_radians(self) -> f128 {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // Using aarch64 because `reliable_f128_math` is needed
|
||||
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128_math)] {
|
||||
///
|
||||
/// let x = 1.0f128;
|
||||
/// let y = 2.0f128;
|
||||
@@ -738,8 +724,7 @@ pub const fn max(self, other: f128) -> f128 {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // Using aarch64 because `reliable_f128_math` is needed
|
||||
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128_math)] {
|
||||
///
|
||||
/// let x = 1.0f128;
|
||||
/// let y = 2.0f128;
|
||||
@@ -771,8 +756,7 @@ pub const fn min(self, other: f128) -> f128 {
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// #![feature(float_minimum_maximum)]
|
||||
/// # // Using aarch64 because `reliable_f128_math` is needed
|
||||
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128_math)] {
|
||||
///
|
||||
/// let x = 1.0f128;
|
||||
/// let y = 2.0f128;
|
||||
@@ -804,8 +788,7 @@ pub const fn maximum(self, other: f128) -> f128 {
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// #![feature(float_minimum_maximum)]
|
||||
/// # // Using aarch64 because `reliable_f128_math` is needed
|
||||
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128_math)] {
|
||||
///
|
||||
/// let x = 1.0f128;
|
||||
/// let y = 2.0f128;
|
||||
@@ -831,8 +814,7 @@ pub const fn minimum(self, other: f128) -> f128 {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // Using aarch64 because `reliable_f128_math` is needed
|
||||
/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// assert_eq!(1f128.midpoint(4.0), 2.5);
|
||||
/// assert_eq!((-5.5f128).midpoint(8.0), 1.25);
|
||||
@@ -862,8 +844,7 @@ pub const fn midpoint(self, other: f128) -> f128 {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `float*itf` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let value = 4.6_f128;
|
||||
/// let rounded = unsafe { value.to_int_unchecked::<u16>() };
|
||||
@@ -906,10 +887,11 @@ pub unsafe fn to_int_unchecked<Int>(self) -> Int
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// # // FIXME(f16_f128): enable this once const casting works
|
||||
/// # // assert_ne!((1f128).to_bits(), 1f128 as u128); // to_bits() is not casting!
|
||||
/// assert_ne!((1f128).to_bits(), 1f128 as u128); // to_bits() is not casting!
|
||||
/// assert_eq!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
@@ -952,8 +934,7 @@ pub const fn to_bits(self) -> u128 {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let v = f128::from_bits(0x40029000000000000000000000000000);
|
||||
/// assert_eq!(v, 12.5);
|
||||
@@ -1064,8 +1045,7 @@ pub const fn from_bits(v: u128) -> Self {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let value = f128::from_be_bytes(
|
||||
/// [0x40, 0x02, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -1090,8 +1070,7 @@ pub const fn from_bits(v: u128) -> Self {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let value = f128::from_le_bytes(
|
||||
/// [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -1123,8 +1102,7 @@ pub const fn from_bits(v: u128) -> Self {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `eqtf2` is available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let value = f128::from_ne_bytes(if cfg!(target_endian = "big") {
|
||||
/// [0x40, 0x02, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -1257,8 +1235,7 @@ pub const fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # // FIXME(f16_f128): remove when `{eq,gt,unord}tf` are available
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// assert!((-3.0f128).clamp(-2.0, 1.0) == -2.0);
|
||||
/// assert!((0.0f128).clamp(-2.0, 1.0) == 0.0);
|
||||
@@ -1333,7 +1310,7 @@ pub fn clamp_magnitude(self, limit: f128) -> f128 {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let x = 3.5_f128;
|
||||
/// let y = -3.5_f128;
|
||||
@@ -1349,9 +1326,7 @@ pub fn clamp_magnitude(self, limit: f128) -> f128 {
|
||||
#[rustc_const_unstable(feature = "f128", issue = "116909")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn abs(self) -> Self {
|
||||
// FIXME(f16_f128): replace with `intrinsics::fabsf128` when available
|
||||
// We don't do this now because LLVM has lowering bugs for f128 math.
|
||||
Self::from_bits(self.to_bits() & !(1 << 127))
|
||||
intrinsics::fabsf128(self)
|
||||
}
|
||||
|
||||
/// Returns a number that represents the sign of `self`.
|
||||
@@ -1364,7 +1339,7 @@ pub const fn abs(self) -> Self {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let f = 3.5_f128;
|
||||
///
|
||||
@@ -1400,7 +1375,7 @@ pub const fn signum(self) -> f128 {
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(f128)]
|
||||
/// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
/// # #[cfg(target_has_reliable_f128)] {
|
||||
///
|
||||
/// let f = 3.5_f128;
|
||||
///
|
||||
@@ -1477,8 +1452,6 @@ pub const fn algebraic_rem(self, rhs: f128) -> f128 {
|
||||
}
|
||||
|
||||
// Functions in this module fall into `core_float_math`
|
||||
// FIXME(f16_f128): all doctests must be gated to platforms that have `long double` === `_Float128`
|
||||
// due to https://github.com/llvm/llvm-project/issues/44744. aarch64 linux matches this.
|
||||
// #[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[cfg(not(test))]
|
||||
#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))]
|
||||
|
||||
@@ -134,9 +134,6 @@ pub mod consts {
|
||||
|
||||
#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), allow(internal_features))))]
|
||||
impl f16 {
|
||||
// FIXME(f16_f128): almost all methods in this `impl` are missing examples and a const
|
||||
// implementation. Add these once we can run code on all platforms and have f16/f128 in CTFE.
|
||||
|
||||
/// The radix or base of the internal representation of `f16`.
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
pub const RADIX: u32 = 2;
|
||||
@@ -887,8 +884,7 @@ pub unsafe fn to_int_unchecked<Int>(self) -> Int
|
||||
/// #![feature(f16)]
|
||||
/// # #[cfg(target_has_reliable_f16)] {
|
||||
///
|
||||
/// # // FIXME(f16_f128): enable this once const casting works
|
||||
/// # // assert_ne!((1f16).to_bits(), 1f16 as u128); // to_bits() is not casting!
|
||||
/// assert_ne!((1f16).to_bits(), 1f16 as u16); // to_bits() is not casting!
|
||||
/// assert_eq!((12.5f16).to_bits(), 0x4a40);
|
||||
/// # }
|
||||
/// ```
|
||||
|
||||
@@ -391,7 +391,7 @@ const fn flt (x: $fty) -> $fty { x }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(f16_f128): merge into `num` once the required `fmodl`/`fmodf128` function is available on
|
||||
// FIXME(f128): merge into `num` once the required `fmodl`/`fmodf128` function is available on
|
||||
// all platforms.
|
||||
float_test! {
|
||||
name: num_rem,
|
||||
@@ -1357,15 +1357,11 @@ const fn q_nan() -> Float {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(f16): Tests involving sNaN are disabled because without optimizations, `total_cmp` is
|
||||
// getting incorrectly lowered to code that includes a `extend`/`trunc` round trip, which quiets
|
||||
// sNaNs. See: https://github.com/llvm/llvm-project/issues/104915
|
||||
|
||||
float_test! {
|
||||
name: total_cmp_s_nan,
|
||||
attrs: {
|
||||
const: #[cfg(false)],
|
||||
f16: #[cfg(miri)],
|
||||
f16: #[cfg(any(miri, target_has_reliable_f16_math))],
|
||||
f128: #[cfg(any(miri, target_has_reliable_f128_math))],
|
||||
},
|
||||
test<Float> {
|
||||
@@ -1636,7 +1632,7 @@ fn s_nan() -> Float {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(f16_f128): Uncomment and adapt these tests once the From<{u64,i64}> impls are added.
|
||||
// FIXME(f128): Uncomment and adapt these tests once the From<{u64,i64}> impls are added.
|
||||
// float_test! {
|
||||
// name: from_u64_i64,
|
||||
// attrs: {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
const FPATHS_F64: &[FPath<f64>] =
|
||||
&[((0, 0, false, false), Some(0.0)), ((0, 0, false, false), Some(0.0))];
|
||||
|
||||
// FIXME(f16_f128): enable on all targets once possible.
|
||||
#[test]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
fn check_fast_path_f16() {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use crate::num::{ldexp_f32, ldexp_f64};
|
||||
|
||||
// FIXME(f16_f128): enable on all targets once possible.
|
||||
#[test]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
fn test_f16_integer_decode() {
|
||||
@@ -54,7 +53,6 @@ fn test_f64_integer_decode() {
|
||||
|
||||
/* Sanity checks of computed magic numbers */
|
||||
|
||||
// FIXME(f16_f128): enable on all targets once possible.
|
||||
#[test]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
fn test_f16_consts() {
|
||||
|
||||
@@ -17,7 +17,6 @@ fn compute_float64(q: i64, w: u64) -> (i32, u64) {
|
||||
(fp.p_biased, fp.m)
|
||||
}
|
||||
|
||||
// FIXME(f16_f128): enable on all targets once possible.
|
||||
#[test]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
fn compute_float_f16_rounding() {
|
||||
|
||||
@@ -92,8 +92,6 @@ fn fast_path_correct() {
|
||||
test_literal!(1.448997445238699);
|
||||
}
|
||||
|
||||
// FIXME(f16_f128): remove gates once tests work on all targets
|
||||
|
||||
#[test]
|
||||
fn lonely_dot() {
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
|
||||
@@ -287,7 +287,7 @@ pub fn f16_exact_sanity_test<F>(mut f: F)
|
||||
check_exact!(f(f16::MIN_POSITIVE) => b"6103515625 ", -4);
|
||||
check_exact!(f(minf16) => b"59604644775390625", -7);
|
||||
|
||||
// FIXME(f16_f128): these should gain the check_exact_one tests like `f32` and `f64` have,
|
||||
// FIXME(f16): these should gain the check_exact_one tests like `f32` and `f64` have,
|
||||
// but these values are not easy to generate. The algorithm from the Paxon paper [1] needs
|
||||
// to be adapted to binary16.
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
|
||||
#![cfg(target_has_reliable_f128)]
|
||||
|
||||
use std::f128::consts;
|
||||
@@ -35,7 +34,7 @@ macro_rules! assert_f128_biteq {
|
||||
|
||||
#[test]
|
||||
fn test_num_f128() {
|
||||
// FIXME(f16_f128): replace with a `test_num` call once the required `fmodl`/`fmodf128`
|
||||
// FIXME(f128): replace with a `test_num` call once the required `fmodl`/`fmodf128`
|
||||
// function is available on all platforms.
|
||||
let ten = 10f128;
|
||||
let two = 2f128;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
|
||||
#![cfg(target_has_reliable_f16)]
|
||||
|
||||
use std::f16::consts;
|
||||
@@ -258,8 +257,6 @@ fn test_ln_gamma() {
|
||||
|
||||
#[test]
|
||||
fn test_real_consts() {
|
||||
// FIXME(f16_f128): add math tests when available
|
||||
|
||||
let pi: f16 = consts::PI;
|
||||
let frac_pi_2: f16 = consts::FRAC_PI_2;
|
||||
let frac_pi_3: f16 = consts::FRAC_PI_3;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# `large-data-threshold`
|
||||
|
||||
-----------------------
|
||||
|
||||
This flag controls the threshold for static data to be placed in large data
|
||||
sections when using the `medium` code model on x86-64.
|
||||
|
||||
When using `-Ccode-model=medium`, static data smaller than this threshold will
|
||||
use RIP-relative addressing (32-bit offsets), while larger data will use
|
||||
absolute 64-bit addressing. This allows the compiler to generate more efficient
|
||||
code for smaller data while still supporting data larger than 2GB.
|
||||
|
||||
The default threshold is 65536 bytes (64KB) if not specified.
|
||||
|
||||
## Example
|
||||
|
||||
```sh
|
||||
rustc -Ccode-model=medium -Zlarge-data-threshold=1024 main.rs
|
||||
```
|
||||
|
||||
This sets the threshold to 1KB, meaning only data smaller than 1024 bytes will
|
||||
use RIP-relative addressing.
|
||||
|
||||
## Platform Support
|
||||
|
||||
This flag is only effective on x86-64 targets when using `-Ccode-model=medium`.
|
||||
On other architectures or with other code models, this flag has no effect.
|
||||
+1
-1
Submodule src/tools/enzyme updated: 09f4820b78...eb72baf793
@@ -0,0 +1,73 @@
|
||||
// Test for -Z large_data_threshold=...
|
||||
// This test verifies that with the medium code model, data above the threshold
|
||||
// is placed in large data sections (.ldata, .lbss, .lrodata).
|
||||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: -Ccode-model=medium -Zlarge-data-threshold=4
|
||||
//@ compile-flags: --target=x86_64-unknown-linux-gnu
|
||||
//@ needs-llvm-components: x86
|
||||
|
||||
#![feature(no_core, lang_items)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[lang = "pointee_sized"]
|
||||
pub trait PointeeSized {}
|
||||
|
||||
#[lang = "meta_sized"]
|
||||
pub trait MetaSized: PointeeSized {}
|
||||
|
||||
#[lang = "sized"]
|
||||
pub trait Sized: MetaSized {}
|
||||
|
||||
#[lang = "drop_in_place"]
|
||||
fn drop_in_place<T>(_: *mut T) {}
|
||||
|
||||
#[used]
|
||||
#[no_mangle]
|
||||
// U is below the threshold, should be in .data
|
||||
static mut U: u16 = 123;
|
||||
|
||||
#[used]
|
||||
#[no_mangle]
|
||||
// V is below the threshold, should be in .bss
|
||||
static mut V: u16 = 0;
|
||||
|
||||
#[used]
|
||||
#[no_mangle]
|
||||
// W is at the threshold, should be in .data
|
||||
static mut W: u32 = 123;
|
||||
|
||||
#[used]
|
||||
#[no_mangle]
|
||||
// X is at the threshold, should be in .bss
|
||||
static mut X: u32 = 0;
|
||||
|
||||
#[used]
|
||||
#[no_mangle]
|
||||
// Y is over the threshold, should be in .ldata
|
||||
static mut Y: u64 = 123;
|
||||
|
||||
#[used]
|
||||
#[no_mangle]
|
||||
// Z is over the threshold, should be in .lbss
|
||||
static mut Z: u64 = 0;
|
||||
|
||||
// CHECK: .section .data.U,
|
||||
// CHECK-NOT: .section
|
||||
// CHECK: U:
|
||||
// CHECK: .section .bss.V,
|
||||
// CHECK-NOT: .section
|
||||
// CHECK: V:
|
||||
// CHECK: .section .data.W,
|
||||
// CHECK-NOT: .section
|
||||
// CHECK: W:
|
||||
// CHECK: .section .bss.X,
|
||||
// CHECK-NOT: .section
|
||||
// CHECK: X:
|
||||
// CHECK: .section .ldata.Y,
|
||||
// CHECK-NOT: .section
|
||||
// CHECK: Y:
|
||||
// CHECK: .section .lbss.Z,
|
||||
// CHECK-NOT: .section
|
||||
// CHECK: Z:
|
||||
@@ -1,9 +1,11 @@
|
||||
//@ run-pass
|
||||
//@ compile-flags: --check-cfg=cfg(target_has_reliable_f16,target_has_reliable_f128)
|
||||
|
||||
// Test half-open range patterns against their expression equivalents
|
||||
// via `.contains(...)` and make sure the dynamic semantics match.
|
||||
|
||||
#![allow(unreachable_patterns)]
|
||||
#![feature(cfg_target_has_reliable_f16_f128)]
|
||||
#![feature(f128)]
|
||||
#![feature(f16)]
|
||||
|
||||
@@ -42,8 +44,7 @@ fn range_to_inclusive() {
|
||||
assert!(!yes!('b', ..='a'));
|
||||
|
||||
// f16; `..=X`
|
||||
// FIXME(f16_f128): remove gate when ABI issues are resolved
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
{
|
||||
assert!(yes!(f16::NEG_INFINITY, ..=f16::NEG_INFINITY));
|
||||
assert!(yes!(f16::NEG_INFINITY, ..=1.0f16));
|
||||
@@ -64,8 +65,7 @@ fn range_to_inclusive() {
|
||||
assert!(!yes!(1.6f64, ..=-1.5f64));
|
||||
|
||||
// f128; `..=X`
|
||||
// FIXME(f16_f128): remove gate when ABI issues are resolved
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f128)]
|
||||
{
|
||||
assert!(yes!(f128::NEG_INFINITY, ..=f128::NEG_INFINITY));
|
||||
assert!(yes!(f128::NEG_INFINITY, ..=1.0f128));
|
||||
@@ -106,8 +106,7 @@ fn range_to() {
|
||||
assert!(!yes!('b', ..'a'));
|
||||
|
||||
// f16; `..X`
|
||||
// FIXME(f16_f128): remove gate when ABI issues are resolved
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
{
|
||||
assert!(yes!(f16::NEG_INFINITY, ..1.0f16));
|
||||
assert!(!yes!(1.5f16, ..1.5f16));
|
||||
@@ -131,8 +130,7 @@ fn range_to() {
|
||||
assert!(!yes!(1.6f64, ..1.5f64));
|
||||
|
||||
// f128; `..X`
|
||||
// FIXME(f16_f128): remove gate when ABI issues are resolved
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f128)]
|
||||
{
|
||||
assert!(yes!(f128::NEG_INFINITY, ..1.0f128));
|
||||
assert!(!yes!(1.5f128, ..1.5f128));
|
||||
@@ -174,8 +172,7 @@ fn range_from() {
|
||||
assert!(yes!(core::char::MAX, core::char::MAX..));
|
||||
|
||||
// f16; `X..`
|
||||
// FIXME(f16_f128): remove gate when ABI issues are resolved
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
{
|
||||
assert!(yes!(f16::NEG_INFINITY, f16::NEG_INFINITY..));
|
||||
assert!(yes!(f16::INFINITY, f16::NEG_INFINITY..));
|
||||
@@ -208,8 +205,7 @@ fn range_from() {
|
||||
assert!(yes!(f64::INFINITY, f64::INFINITY..));
|
||||
|
||||
// f128; `X..`
|
||||
// FIXME(f16_f128): remove gate when ABI issues are resolved
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f128)]
|
||||
{
|
||||
assert!(yes!(f128::NEG_INFINITY, f128::NEG_INFINITY..));
|
||||
assert!(yes!(f128::INFINITY, f128::NEG_INFINITY..));
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//@ run-pass
|
||||
//@ compile-flags: --check-cfg=cfg(target_has_reliable_f16,target_has_reliable_f128)
|
||||
// Makes sure we use `==` (not bitwise) semantics for float comparison.
|
||||
|
||||
#![feature(cfg_target_has_reliable_f16_f128)]
|
||||
#![feature(f128)]
|
||||
#![feature(f16)]
|
||||
|
||||
// FIXME(f16_f128): remove gates when ABI issues are resolved
|
||||
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
fn check_f16() {
|
||||
const F1: f16 = 0.0;
|
||||
const F2: f16 = -0.0;
|
||||
@@ -34,7 +34,7 @@ fn check_f64() {
|
||||
assert!(matches!(F2, F1));
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f128)]
|
||||
fn check_f128() {
|
||||
const F1: f128 = 0.0;
|
||||
const F2: f128 = -0.0;
|
||||
@@ -45,10 +45,10 @@ fn check_f128() {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f16)]
|
||||
check_f16();
|
||||
check_f32();
|
||||
check_f64();
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[cfg(target_has_reliable_f128)]
|
||||
check_f128();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user