Move CTFE handling of nondiverging intrinsics to intrinsics.rs
This commit is contained in:
parent
b7413511dc
commit
104f97e5aa
2 changed files with 29 additions and 19 deletions
|
@ -8,7 +8,7 @@ use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
self,
|
self,
|
||||||
interpret::{ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar},
|
interpret::{ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar},
|
||||||
BinOp,
|
BinOp, NonDivergingIntrinsic,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_middle::ty::layout::LayoutOf as _;
|
use rustc_middle::ty::layout::LayoutOf as _;
|
||||||
|
@ -530,6 +530,32 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn emulate_nondiverging_intrinsic(
|
||||||
|
&mut self,
|
||||||
|
intrinsic: &NonDivergingIntrinsic<'tcx>,
|
||||||
|
) -> InterpResult<'tcx> {
|
||||||
|
match intrinsic {
|
||||||
|
NonDivergingIntrinsic::Assume(op) => {
|
||||||
|
let op = self.eval_operand(op, None)?;
|
||||||
|
let cond = self.read_scalar(&op)?.to_bool()?;
|
||||||
|
if !cond {
|
||||||
|
throw_ub_format!("`assume` called with `false`");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
|
||||||
|
count,
|
||||||
|
src,
|
||||||
|
dst,
|
||||||
|
}) => {
|
||||||
|
let src = self.eval_operand(src, None)?;
|
||||||
|
let dst = self.eval_operand(dst, None)?;
|
||||||
|
let count = self.eval_operand(count, None)?;
|
||||||
|
self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn exact_div(
|
pub fn exact_div(
|
||||||
&mut self,
|
&mut self,
|
||||||
a: &ImmTy<'tcx, M::Provenance>,
|
a: &ImmTy<'tcx, M::Provenance>,
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
//!
|
//!
|
||||||
//! The main entry point is the `step` method.
|
//! The main entry point is the `step` method.
|
||||||
|
|
||||||
|
use rustc_middle::mir;
|
||||||
use rustc_middle::mir::interpret::{InterpResult, Scalar};
|
use rustc_middle::mir::interpret::{InterpResult, Scalar};
|
||||||
use rustc_middle::mir::{self, NonDivergingIntrinsic};
|
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
|
|
||||||
use super::{InterpCx, Machine};
|
use super::{InterpCx, Machine};
|
||||||
|
@ -114,23 +114,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
M::retag(self, *kind, &dest)?;
|
M::retag(self, *kind, &dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Intrinsic(box NonDivergingIntrinsic::Assume(op)) => {
|
Intrinsic(box ref intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
|
||||||
let op = self.eval_operand(op, None)?;
|
|
||||||
let cond = self.read_scalar(&op)?.to_bool()?;
|
|
||||||
if !cond {
|
|
||||||
throw_ub_format!("`assume` called with `false`");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
|
|
||||||
ref count,
|
|
||||||
ref src,
|
|
||||||
ref dst,
|
|
||||||
})) => {
|
|
||||||
let src = self.eval_operand(src, None)?;
|
|
||||||
let dst = self.eval_operand(dst, None)?;
|
|
||||||
let count = self.eval_operand(count, None)?;
|
|
||||||
self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Statements we do not track.
|
// Statements we do not track.
|
||||||
AscribeUserType(..) => {}
|
AscribeUserType(..) => {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue