@@ -141,6 +141,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
141141 this. write_pointer ( Pointer :: new ( ptr. provenance , masked_addr) , dest) ?;
142142 }
143143
144+ // The default implementation always returns `false`, but we want
145+ // to return either `true` or `false` at random.
146+ "is_comptile_time_known" => {
147+ let rand = 0 ;
148+ _ = getrandom:: getrandom ( & mut [ rand] ) ;
149+
150+ this. write_scalar (
151+ Scalar :: from_bool ( if ( rand % 1 ) == 1 { true } else { false } ) ,
152+ dest,
153+ ) ?;
154+ }
155+
144156 // Floating-point operations
145157 "fabsf32" => {
146158 let [ f] = check_arg_count ( args) ?;
@@ -417,4 +429,59 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
417429
418430 Ok ( ( ) )
419431 }
432+ <<<<<<< HEAD
433+ =======
434+
435+ fn float_to_int_unchecked < F > (
436+ & self ,
437+ f : F ,
438+ dest_ty : Ty < ' tcx > ,
439+ ) -> InterpResult < ' tcx , Scalar < Provenance > >
440+ where
441+ F : Float + Into < Scalar < Provenance > > ,
442+ {
443+ let this = self . eval_context_ref ( ) ;
444+
445+ // Step 1: cut off the fractional part of `f`. The result of this is
446+ // guaranteed to be precisely representable in IEEE floats.
447+ let f = f. round_to_integral ( Round :: TowardZero ) . value ;
448+
449+ // Step 2: Cast the truncated float to the target integer type and see if we lose any information in this step.
450+ Ok ( match dest_ty. kind( ) {
451+ // Unsigned
452+ ty : : Uint ( t) => {
453+ let size = Integer : : from_uint_ty( this, * t) . size( ) ;
454+ let res = f. to_u128( size. bits_usize( ) ) ;
455+ if res. status. is_empty( ) {
456+ // No status flags means there was no further rounding or other loss of precision.
457+ Scalar :: from_uint( res. value, size)
458+ } else {
459+ // `f` was not representable in this integer type.
460+ throw_ub_format ! (
461+ "`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{dest_ty:?}`" ,
462+ ) ;
463+ }
464+ }
465+ // Signed
466+ ty:: Int ( t) => {
467+ let size = Integer :: from_int_ty( this, * t) . size( ) ;
468+ let res = f. to_i128( size. bits_usize( ) ) ;
469+ if res. status. is_empty( ) {
470+ // No status flags means there was no further rounding or other loss of precision.
471+ Scalar :: from_int( res. value, size)
472+ } else {
473+ // `f` was not representable in this integer type.
474+ throw_ub_format ! (
475+ "`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{dest_ty:?}`" ,
476+ ) ;
477+ }
478+ }
479+ // Nothing else
480+ _ => span_bug ! (
481+ this. cur_span( ) ,
482+ "`float_to_int_unchecked` called with non-int output type {dest_ty:?}"
483+ ) ,
484+ } )
485+ }
486+ >>>>>>> acbf90a9489 ( Make MIRI choose the path randomly and rename the intrinsic )
420487}
0 commit comments