From 971e37ff7e80cf2dbf4f95162d5957913803f30d Mon Sep 17 00:00:00 2001 From: Nicholas Thompson Date: Tue, 23 Jan 2024 12:02:31 -0500 Subject: [PATCH] Further Implement `is_val_statically_known` --- .../src/intrinsics/mod.rs | 6 ++++ compiler/rustc_codegen_gcc/src/context.rs | 7 +++-- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 6 ++++ library/core/src/intrinsics.rs | 30 ++++++++++++++----- tests/codegen/is_val_statically_known.rs | 4 +-- 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 15249402a63..f328ad93d26 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -439,6 +439,12 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, a); } + sym::is_val_statically_known => { + intrinsic_args!(fx, args => (_a); intrinsic); + + let res = fx.bcx.ins().iconst(types::I8, 0); + ret.write_cvalue(fx, CValue::by_val(res, ret.layout())); + } sym::breakpoint => { intrinsic_args!(fx, args => (); intrinsic); diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 053f759329f..5760d96165d 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -196,15 +196,16 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let mut functions = FxHashMap::default(); let builtins = [ - "__builtin_unreachable", "abort", "__builtin_expect", "__builtin_add_overflow", "__builtin_mul_overflow", - "__builtin_saddll_overflow", /*"__builtin_sadd_overflow",*/ "__builtin_smulll_overflow", /*"__builtin_smul_overflow",*/ + "__builtin_unreachable", "abort", "__builtin_expect", /*"__builtin_expect_with_probability",*/ + "__builtin_constant_p", "__builtin_add_overflow", "__builtin_mul_overflow", "__builtin_saddll_overflow", + /*"__builtin_sadd_overflow",*/ "__builtin_smulll_overflow", /*"__builtin_smul_overflow",*/ "__builtin_ssubll_overflow", /*"__builtin_ssub_overflow",*/ "__builtin_sub_overflow", "__builtin_uaddll_overflow", "__builtin_uadd_overflow", "__builtin_umulll_overflow", "__builtin_umul_overflow", "__builtin_usubll_overflow", "__builtin_usub_overflow", "sqrtf", "sqrt", "__builtin_powif", "__builtin_powi", "sinf", "sin", "cosf", "cos", "powf", "pow", "expf", "exp", "exp2f", "exp2", "logf", "log", "log10f", "log10", "log2f", "log2", "fmaf", "fma", "fabsf", "fabs", "fminf", "fmin", "fmaxf", "fmax", "copysignf", "copysign", "floorf", "floor", "ceilf", "ceil", "truncf", "trunc", "rintf", "rint", "nearbyintf", "nearbyint", "roundf", "round", - "__builtin_expect_with_probability", + ]; for builtin in builtins.iter() { diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 85b891fce3e..eac8cb43779 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -123,6 +123,12 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { sym::unlikely => { self.expect(args[0].immediate(), false) } + sym::is_val_statically_known => { + let a = args[0].immediate(); + let builtin = self.context.get_builtin_function("__builtin_constant_p"); + let res = self.context.new_call(None, builtin, &[a]); + self.icmp(IntPredicate::IntEQ, res, self.const_i32(0)) + } kw::Try => { try_intrinsic( self, diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index b49cdcf2f36..5b652f99911 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2525,15 +2525,30 @@ extern "rust-intrinsic" { /// or `false`, and the caller has to ensure sound behavior for both cases. /// In other words, the following code has *Undefined Behavior*: /// - /// ```rust - /// if !is_val_statically_known(0) { unreachable_unchecked(); } + /// ``` + /// #![feature(is_val_statically_known)] + /// #![feature(core_intrinsics)] + /// # #![allow(internal_features)] + /// use std::hint::unreachable_unchecked; + /// use std::intrinsics::is_val_statically_known; + /// + /// unsafe { + /// if !is_val_statically_known(0) { unreachable_unchecked(); } + /// } /// ``` /// /// This also means that the following code's behavior is unspecified; it /// may panic, or it may not: /// - /// ```rust,no_run - /// assert_eq!(is_val_statically_known(0), black_box(is_val_statically_known(0))) + /// ```no_run + /// #![feature(is_val_statically_known)] + /// #![feature(core_intrinsics)] + /// # #![allow(internal_features)] + /// use std::intrinsics::is_val_statically_known; + /// + /// unsafe { + /// assert_eq!(is_val_statically_known(0), is_val_statically_known(0)); + /// } /// ``` /// /// Unsafe code may not rely on `is_val_statically_known` returning any @@ -2547,15 +2562,14 @@ extern "rust-intrinsic" { #[rustc_const_unstable(feature = "is_val_statically_known", issue = "none")] #[rustc_nounwind] #[cfg(not(bootstrap))] - pub fn is_val_statically_known(arg: T) -> bool; + pub fn is_val_statically_known(arg: T) -> bool; } // FIXME: Seems using `unstable` here completely ignores `rustc_allow_const_fn_unstable` // and thus compiling stage0 core doesn't work. -#[rustc_const_stable(feature = "is_val_statically_known", since = "never")] +#[rustc_const_stable(feature = "is_val_statically_known", since = "0.0.0")] #[cfg(bootstrap)] -pub const unsafe fn is_val_statically_known(t: T) -> bool { - mem::forget(t); +pub const unsafe fn is_val_statically_known(_arg: T) -> bool { false } diff --git a/tests/codegen/is_val_statically_known.rs b/tests/codegen/is_val_statically_known.rs index 4dcab744235..44187d4f667 100644 --- a/tests/codegen/is_val_statically_known.rs +++ b/tests/codegen/is_val_statically_known.rs @@ -1,6 +1,4 @@ -// #[cfg(bootstrap)] -// ignore-stage1 -// compile-flags: --crate-type=lib -Zmerge-functions=disabled +// compile-flags: --crate-type=lib -Zmerge-functions=disabled -O #![feature(core_intrinsics)]