3
3
//! and miri.
4
4
5
5
use rustc_hir::def_id::DefId;
6
- use rustc_middle::mir::{
7
- self,
8
- interpret::{Allocation, ConstAllocation, GlobalId, InterpResult, PointerArithmetic, Scalar},
9
- BinOp, ConstValue, NonDivergingIntrinsic,
10
- };
11
6
use rustc_middle::ty;
12
7
use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
13
8
use rustc_middle::ty::GenericArgsRef;
14
9
use rustc_middle::ty::{Ty, TyCtxt};
10
+ use rustc_middle::{
11
+ mir::{
12
+ self,
13
+ interpret::{
14
+ Allocation, ConstAllocation, GlobalId, InterpResult, PointerArithmetic, Scalar,
15
+ },
16
+ BinOp, ConstValue, NonDivergingIntrinsic,
17
+ },
18
+ ty::layout::TyAndLayout,
19
+ };
15
20
use rustc_span::symbol::{sym, Symbol};
16
- use rustc_target::abi::{Abi, Primitive, Size} ;
21
+ use rustc_target::abi::Size;
17
22
18
23
use super::{
19
24
util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy,
@@ -22,23 +27,6 @@ use super::{
22
27
23
28
use crate::fluent_generated as fluent;
24
29
25
- fn numeric_intrinsic<Prov>(name: Symbol, bits: u128, kind: Primitive) -> Scalar<Prov> {
26
- let size = match kind {
27
- Primitive::Int(integer, _) => integer.size(),
28
- _ => bug!("invalid `{}` argument: {:?}", name, bits),
29
- };
30
- let extra = 128 - u128::from(size.bits());
31
- let bits_out = match name {
32
- sym::ctpop => u128::from(bits.count_ones()),
33
- sym::ctlz => u128::from(bits.leading_zeros()) - extra,
34
- sym::cttz => u128::from((bits << extra).trailing_zeros()) - extra,
35
- sym::bswap => (bits << extra).swap_bytes(),
36
- sym::bitreverse => (bits << extra).reverse_bits(),
37
- _ => bug!("not a numeric intrinsic: {}", name),
38
- };
39
- Scalar::from_uint(bits_out, size)
40
- }
41
-
42
30
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
43
31
pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
44
32
let path = crate::util::type_name(tcx, ty);
@@ -179,30 +167,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
179
167
| sym::bswap
180
168
| sym::bitreverse => {
181
169
let ty = instance_args.type_at(0);
182
- let layout_of = self.layout_of(ty)?;
170
+ let layout = self.layout_of(ty)?;
183
171
let val = self.read_scalar(&args[0])?;
184
- let bits = val.to_bits(layout_of.size)?;
185
- let kind = match layout_of.abi {
186
- Abi::Scalar(scalar) => scalar.primitive(),
187
- _ => span_bug!(
188
- self.cur_span(),
189
- "{} called on invalid type {:?}",
190
- intrinsic_name,
191
- ty
192
- ),
193
- };
194
- let (nonzero, actual_intrinsic_name) = match intrinsic_name {
195
- sym::cttz_nonzero => (true, sym::cttz),
196
- sym::ctlz_nonzero => (true, sym::ctlz),
197
- other => (false, other),
198
- };
199
- if nonzero && bits == 0 {
200
- throw_ub_custom!(
201
- fluent::const_eval_call_nonzero_intrinsic,
202
- name = intrinsic_name,
203
- );
204
- }
205
- let out_val = numeric_intrinsic(actual_intrinsic_name, bits, kind);
172
+ let out_val = self.numeric_intrinsic(intrinsic_name, val, layout)?;
206
173
self.write_scalar(out_val, dest)?;
207
174
}
208
175
sym::saturating_add | sym::saturating_sub => {
@@ -493,6 +460,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
493
460
}
494
461
}
495
462
463
+ pub fn numeric_intrinsic(
464
+ &self,
465
+ name: Symbol,
466
+ val: Scalar<M::Provenance>,
467
+ layout: TyAndLayout<'tcx>,
468
+ ) -> InterpResult<'tcx, Scalar<M::Provenance>> {
469
+ assert!(layout.ty.is_integral(), "invalid type for numeric intrinsic: {}", layout.ty);
470
+ let bits = val.to_bits(layout.size)?;
471
+ let extra = 128 - u128::from(layout.size.bits());
472
+ let bits_out = match name {
473
+ sym::ctpop => u128::from(bits.count_ones()),
474
+ sym::ctlz_nonzero | sym::cttz_nonzero if bits == 0 => {
475
+ throw_ub_custom!(fluent::const_eval_call_nonzero_intrinsic, name = name,);
476
+ }
477
+ sym::ctlz | sym::ctlz_nonzero => u128::from(bits.leading_zeros()) - extra,
478
+ sym::cttz | sym::cttz_nonzero => u128::from((bits << extra).trailing_zeros()) - extra,
479
+ sym::bswap => (bits << extra).swap_bytes(),
480
+ sym::bitreverse => (bits << extra).reverse_bits(),
481
+ _ => bug!("not a numeric intrinsic: {}", name),
482
+ };
483
+ Ok(Scalar::from_uint(bits_out, layout.size))
484
+ }
485
+
496
486
pub fn exact_div(
497
487
&mut self,
498
488
a: &ImmTy<'tcx, M::Provenance>,
0 commit comments