33//! and miri.
44
55use 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- } ;
116use rustc_middle:: ty;
127use rustc_middle:: ty:: layout:: { LayoutOf as _, ValidityRequirement } ;
138use rustc_middle:: ty:: GenericArgsRef ;
149use 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+ } ;
1520use rustc_span:: symbol:: { sym, Symbol } ;
16- use rustc_target:: abi:: { Abi , Primitive , Size } ;
21+ use rustc_target:: abi:: Size ;
1722
1823use super :: {
1924 util:: ensure_monomorphic_enough, CheckInAllocMsg , ImmTy , InterpCx , Machine , OpTy , PlaceTy ,
@@ -22,23 +27,6 @@ use super::{
2227
2328use crate :: fluent_generated as fluent;
2429
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-
4230/// Directly returns an `Allocation` containing an absolute path representation of the given type.
4331pub ( crate ) fn alloc_type_name < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> ConstAllocation < ' tcx > {
4432 let path = crate :: util:: type_name ( tcx, ty) ;
@@ -179,30 +167,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
179167 | sym:: bswap
180168 | sym:: bitreverse => {
181169 let ty = instance_args. type_at ( 0 ) ;
182- let layout_of = self . layout_of ( ty) ?;
170+ let layout = self . layout_of ( ty) ?;
183171 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) ?;
206173 self . write_scalar ( out_val, dest) ?;
207174 }
208175 sym:: saturating_add | sym:: saturating_sub => {
@@ -493,6 +460,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
493460 }
494461 }
495462
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+
496486 pub fn exact_div (
497487 & mut self ,
498488 a : & ImmTy < ' tcx , M :: Provenance > ,
0 commit comments