@@ -4,6 +4,7 @@ use cranelift_codegen::CodegenError;
44use cranelift_codegen:: ir:: UserFuncName ;
55use cranelift_frontend:: { FunctionBuilder , FunctionBuilderContext } ;
66use cranelift_module:: ModuleError ;
7+ use rustc_abi:: { Float , Primitive } ;
78use rustc_ast:: InlineAsmOptions ;
89use rustc_codegen_ssa:: base:: is_call_from_compiler_builtins_to_upstream_monomorphization;
910use rustc_data_structures:: profiling:: SelfProfilerRef ;
@@ -40,6 +41,51 @@ pub(crate) fn codegen_fn<'tcx>(
4041) -> Option < CodegenedFunction > {
4142 debug_assert ! ( !instance. args. has_infer( ) ) ;
4243
44+ let fn_abi = FullyMonomorphizedLayoutCx ( tcx) . fn_abi_of_instance ( instance, ty:: List :: empty ( ) ) ;
45+ let arg_f16_f128 = fn_abi. args . iter ( ) . chain ( Some ( & fn_abi. ret ) ) . any ( |arg| {
46+ let ty = arg. layout . ty ;
47+ if matches ! ( ty. kind( ) , ty:: Float ( ty:: FloatTy :: F16 | ty:: FloatTy :: F128 ) ) {
48+ return true ;
49+ }
50+ match arg. layout . backend_repr {
51+ BackendRepr :: Scalar ( scalar) => match scalar. primitive ( ) {
52+ Primitive :: Float ( float) => match float {
53+ Float :: F16 | Float :: F128 => return true ,
54+ _ => { }
55+ } ,
56+ _ => { }
57+ } ,
58+ BackendRepr :: ScalarPair ( a, b) => {
59+ match a. primitive ( ) {
60+ Primitive :: Float ( float) => match float {
61+ Float :: F16 | Float :: F128 => return true ,
62+ _ => { }
63+ } ,
64+ _ => { }
65+ }
66+ match b. primitive ( ) {
67+ Primitive :: Float ( float) => match float {
68+ Float :: F16 | Float :: F128 => return true ,
69+ _ => { }
70+ } ,
71+ _ => { }
72+ }
73+ }
74+ BackendRepr :: Vector { element, count : _ } => match element. primitive ( ) {
75+ Primitive :: Float ( float) => match float {
76+ Float :: F16 | Float :: F128 => return true ,
77+ _ => { }
78+ } ,
79+ _ => { }
80+ } ,
81+ _ => { }
82+ }
83+ false
84+ } ) ;
85+ if arg_f16_f128 {
86+ return None ;
87+ }
88+
4389 let symbol_name = tcx. symbol_name ( instance) . name . to_string ( ) ;
4490 let _timer = tcx. prof . generic_activity_with_arg ( "codegen fn" , & * symbol_name) ;
4591
@@ -300,6 +346,53 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
300346 fx. bcx . ins ( ) . trap ( TrapCode :: user ( 1 /* unreachable */ ) . unwrap ( ) ) ;
301347 return ;
302348 }
349+ let arg_f16_f128 = fx. mir . local_decls ( ) . indices ( ) . any ( |arg| {
350+ let ty = fx. monomorphize ( fx. mir . local_decls [ arg] . ty ) ;
351+ if matches ! ( ty. kind( ) , ty:: Float ( ty:: FloatTy :: F16 | ty:: FloatTy :: F128 ) ) {
352+ return true ;
353+ }
354+ match fx. layout_of ( ty) . backend_repr {
355+ BackendRepr :: Scalar ( scalar) => match scalar. primitive ( ) {
356+ Primitive :: Float ( float) => match float {
357+ Float :: F16 | Float :: F128 => return true ,
358+ _ => { }
359+ } ,
360+ _ => { }
361+ } ,
362+ BackendRepr :: ScalarPair ( a, b) => {
363+ match a. primitive ( ) {
364+ Primitive :: Float ( float) => match float {
365+ Float :: F16 | Float :: F128 => return true ,
366+ _ => { }
367+ } ,
368+ _ => { }
369+ }
370+ match b. primitive ( ) {
371+ Primitive :: Float ( float) => match float {
372+ Float :: F16 | Float :: F128 => return true ,
373+ _ => { }
374+ } ,
375+ _ => { }
376+ }
377+ }
378+ BackendRepr :: Vector { element, count : _ } => match element. primitive ( ) {
379+ Primitive :: Float ( float) => match float {
380+ Float :: F16 | Float :: F128 => return true ,
381+ _ => { }
382+ } ,
383+ _ => { }
384+ } ,
385+ _ => { }
386+ }
387+ false
388+ } ) ;
389+ if arg_f16_f128 {
390+ fx. bcx . append_block_params_for_function_params ( fx. block_map [ START_BLOCK ] ) ;
391+ fx. bcx . switch_to_block ( fx. block_map [ START_BLOCK ] ) ;
392+ fx. bcx . ins ( ) . trap ( TrapCode :: user ( 1 /* unreachable */ ) . unwrap ( ) ) ;
393+ return ;
394+ }
395+
303396 fx. tcx
304397 . prof
305398 . generic_activity ( "codegen prelude" )
@@ -676,17 +769,85 @@ fn codegen_stmt<'tcx>(
676769 let to_layout = fx. layout_of ( fx. monomorphize ( to_ty) ) ;
677770 match * from_ty. kind ( ) {
678771 ty:: FnDef ( def_id, args) => {
679- let func_ref = fx. get_function_ref (
772+ let fn_abi = FullyMonomorphizedLayoutCx ( fx. tcx ) . fn_abi_of_instance (
680773 Instance :: resolve_for_fn_ptr (
681774 fx. tcx ,
682775 ty:: TypingEnv :: fully_monomorphized ( ) ,
683776 def_id,
684777 args,
685778 )
686779 . unwrap ( ) ,
780+ ty:: List :: empty ( ) ,
687781 ) ;
688- let func_addr = fx. bcx . ins ( ) . func_addr ( fx. pointer_type , func_ref) ;
689- lval. write_cvalue ( fx, CValue :: by_val ( func_addr, to_layout) ) ;
782+ let arg_f16_f128 =
783+ fn_abi. args . iter ( ) . chain ( Some ( & fn_abi. ret ) ) . any ( |arg| {
784+ let ty = arg. layout . ty ;
785+ if matches ! (
786+ ty. kind( ) ,
787+ ty:: Float ( ty:: FloatTy :: F16 | ty:: FloatTy :: F128 )
788+ ) {
789+ return true ;
790+ }
791+ match arg. layout . backend_repr {
792+ BackendRepr :: Scalar ( scalar) => match scalar. primitive ( ) {
793+ Primitive :: Float ( float) => match float {
794+ Float :: F16 | Float :: F128 => return true ,
795+ _ => { }
796+ } ,
797+ _ => { }
798+ } ,
799+ BackendRepr :: ScalarPair ( a, b) => {
800+ match a. primitive ( ) {
801+ Primitive :: Float ( float) => match float {
802+ Float :: F16 | Float :: F128 => return true ,
803+ _ => { }
804+ } ,
805+ _ => { }
806+ }
807+ match b. primitive ( ) {
808+ Primitive :: Float ( float) => match float {
809+ Float :: F16 | Float :: F128 => return true ,
810+ _ => { }
811+ } ,
812+ _ => { }
813+ }
814+ }
815+ BackendRepr :: Vector { element, count : _ } => {
816+ match element. primitive ( ) {
817+ Primitive :: Float ( float) => match float {
818+ Float :: F16 | Float :: F128 => return true ,
819+ _ => { }
820+ } ,
821+ _ => { }
822+ }
823+ }
824+ _ => { }
825+ }
826+ false
827+ } ) ;
828+ if arg_f16_f128 {
829+ let trap_block = fx. bcx . create_block ( ) ;
830+ let true_ = fx. bcx . ins ( ) . iconst ( types:: I8 , 1 ) ;
831+ let next_block = fx. bcx . create_block ( ) ;
832+ fx. bcx . ins ( ) . brif ( true_, trap_block, & [ ] , next_block, & [ ] ) ;
833+ fx. bcx . seal_block ( trap_block) ;
834+ fx. bcx . seal_block ( next_block) ;
835+ fx. bcx . switch_to_block ( trap_block) ;
836+ fx. bcx . ins ( ) . trap ( TrapCode :: user ( 1 ) . unwrap ( ) ) ;
837+ fx. bcx . switch_to_block ( next_block) ;
838+ } else {
839+ let func_ref = fx. get_function_ref (
840+ Instance :: resolve_for_fn_ptr (
841+ fx. tcx ,
842+ ty:: TypingEnv :: fully_monomorphized ( ) ,
843+ def_id,
844+ args,
845+ )
846+ . unwrap ( ) ,
847+ ) ;
848+ let func_addr = fx. bcx . ins ( ) . func_addr ( fx. pointer_type , func_ref) ;
849+ lval. write_cvalue ( fx, CValue :: by_val ( func_addr, to_layout) ) ;
850+ }
690851 }
691852 _ => bug ! ( "Trying to ReifyFnPointer on non FnDef {:?}" , from_ty) ,
692853 }
0 commit comments