Rollup merge of #76973 - lzutao:unstably-const-assume, r=oli-obk
Unstably allow assume intrinsic in const contexts Not sure much about this usage because there are concerns about [blocking optimization][1] and [slowing down LLVM][2] when using `assme` intrinsic in inline functions. But since Oli suggested in https://github.com/rust-lang/rust/issues/76960#issuecomment-695772221, here we are. [1]: https://github.com/rust-lang/rust/pull/54995#issuecomment-429302709 [2]: https://github.com/rust-lang/rust/issues/49572#issuecomment-589615423
This commit is contained in:
commit
1b8c939a8d
@ -5,9 +5,9 @@ use rustc_span::Span;
|
||||
use rustc_target::abi::call::FnAbi;
|
||||
|
||||
pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
|
||||
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
|
||||
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
|
||||
/// add them to librustc_codegen_llvm/context.rs
|
||||
/// Remember to add all intrinsics here, in `compiler/rustc_typeck/src/check/mod.rs`,
|
||||
/// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics,
|
||||
/// add them to `compiler/rustc_codegen_llvm/src/context.rs`.
|
||||
fn codegen_intrinsic_call(
|
||||
&mut self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
|
@ -12,8 +12,8 @@ extern "rust-intrinsic" {
|
||||
```
|
||||
|
||||
Please check you didn't make a mistake in the function's name. All intrinsic
|
||||
functions are defined in `librustc_codegen_llvm/intrinsic.rs` and in
|
||||
`libcore/intrinsics.rs` in the Rust source code. Example:
|
||||
functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
|
||||
`library/core/src/intrinsics.rs` in the Rust source code. Example:
|
||||
|
||||
```
|
||||
#![feature(intrinsics)]
|
||||
|
@ -17,8 +17,8 @@ fn main() {
|
||||
```
|
||||
|
||||
Please check you didn't make a mistake in the function's name. All intrinsic
|
||||
functions are defined in `librustc_codegen_llvm/intrinsic.rs` and in
|
||||
`libcore/intrinsics.rs` in the Rust source code. Example:
|
||||
functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
|
||||
`library/core/src/intrinsics.rs` in the Rust source code. Example:
|
||||
|
||||
```
|
||||
#![feature(intrinsics)]
|
||||
|
@ -435,6 +435,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// These just return their argument
|
||||
self.copy_op(args[0], dest)?;
|
||||
}
|
||||
sym::assume => {
|
||||
let cond = self.read_scalar(args[0])?.check_init()?.to_bool()?;
|
||||
if !cond {
|
||||
throw_ub_format!("`assume` intrinsic called with `false`");
|
||||
}
|
||||
}
|
||||
_ => return Ok(false),
|
||||
}
|
||||
|
||||
|
@ -390,9 +390,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
ty::InstanceDef::Virtual(_, idx) => {
|
||||
let mut args = args.to_vec();
|
||||
// We have to implement all "object safe receivers". Currently we
|
||||
// support built-in pointers (&, &mut, Box) as well as unsized-self. We do
|
||||
// support built-in pointers `(&, &mut, Box)` as well as unsized-self. We do
|
||||
// not yet support custom self types.
|
||||
// Also see librustc_codegen_llvm/abi.rs and librustc_codegen_llvm/mir/block.rs.
|
||||
// Also see `compiler/rustc_codegen_llvm/src/abi.rs` and `compiler/rustc_codegen_ssa/src/mir/block.rs`.
|
||||
let receiver_place = match args[0].layout.ty.builtin_deref(true) {
|
||||
Some(_) => {
|
||||
// Built-in pointer.
|
||||
|
@ -106,8 +106,8 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
|
||||
}
|
||||
}
|
||||
|
||||
/// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs,
|
||||
/// and in libcore/intrinsics.rs
|
||||
/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
|
||||
/// and in `library/core/src/intrinsics.rs`.
|
||||
pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
||||
let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
|
||||
let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id();
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Compiler intrinsics.
|
||||
//!
|
||||
//! The corresponding definitions are in `librustc_codegen_llvm/intrinsic.rs`.
|
||||
//! The corresponding const implementations are in `librustc_mir/interpret/intrinsics.rs`
|
||||
//! The corresponding definitions are in `compiler/rustc_codegen_llvm/src/intrinsic.rs`.
|
||||
//! The corresponding const implementations are in `compiler/rustc_mir/src/interpret/intrinsics.rs`
|
||||
//!
|
||||
//! # Const intrinsics
|
||||
//!
|
||||
@ -10,7 +10,7 @@
|
||||
//!
|
||||
//! In order to make an intrinsic usable at compile-time, one needs to copy the implementation
|
||||
//! from https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs to
|
||||
//! `librustc_mir/interpret/intrinsics.rs` and add a
|
||||
//! `compiler/rustc_mir/src/interpret/intrinsics.rs` and add a
|
||||
//! `#[rustc_const_unstable(feature = "foo", issue = "01234")]` to the intrinsic.
|
||||
//!
|
||||
//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
|
||||
@ -733,6 +733,7 @@ extern "rust-intrinsic" {
|
||||
/// own, or if it does not enable any significant optimizations.
|
||||
///
|
||||
/// This intrinsic does not have a stable counterpart.
|
||||
#[rustc_const_unstable(feature = "const_assume", issue = "76972")]
|
||||
pub fn assume(b: bool);
|
||||
|
||||
/// Hints to the compiler that branch condition is likely to be true.
|
||||
|
@ -1,4 +1,5 @@
|
||||
use core::any::TypeId;
|
||||
use core::intrinsics::assume;
|
||||
|
||||
#[test]
|
||||
fn test_typeid_sized_types() {
|
||||
@ -20,3 +21,17 @@ fn test_typeid_unsized_types() {
|
||||
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
|
||||
assert!(TypeId::of::<X>() != TypeId::of::<Y>());
|
||||
}
|
||||
|
||||
// Check that `const_assume` feature allow `assume` intrinsic
|
||||
// to be used in const contexts.
|
||||
#[test]
|
||||
fn test_assume_can_be_in_const_contexts() {
|
||||
const unsafe fn foo(x: usize, y: usize) -> usize {
|
||||
// SAFETY: the entire function is not safe,
|
||||
// but it is just an example not used elsewhere.
|
||||
unsafe { assume(y != 0) };
|
||||
x / y
|
||||
}
|
||||
let rs = unsafe { foo(42, 97) };
|
||||
assert_eq!(rs, 0);
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
#![feature(bound_cloned)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cell_update)]
|
||||
#![feature(const_assume)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(core_private_bignum)]
|
||||
#![feature(core_private_diy_float)]
|
||||
#![feature(debug_non_exhaustive)]
|
||||
|
@ -175,7 +175,7 @@ pub struct _TypeDescriptor {
|
||||
// to be able to catch Rust panics by simply declaring a `struct rust_panic`.
|
||||
//
|
||||
// When modifying, make sure that the type name string exactly matches
|
||||
// the one used in src/librustc_codegen_llvm/intrinsic.rs.
|
||||
// the one used in `compiler/rustc_codegen_llvm/src/intrinsic.rs`.
|
||||
const TYPE_NAME: [u8; 11] = *b"rust_panic\0";
|
||||
|
||||
static mut THROW_INFO: _ThrowInfo = _ThrowInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user