@@ -4,10 +4,10 @@ mod simd;
44#[ cfg( feature = "master" ) ]
55use std:: iter;
66
7- #[ cfg( feature = "master" ) ]
8- use gccjit:: Type ;
97use gccjit:: { ComparisonOp , Function , FunctionType , RValue , ToRValue , UnaryOp } ;
108#[ cfg( feature = "master" ) ]
9+ use gccjit:: { FnAttribute , Type } ;
10+ #[ cfg( feature = "master" ) ]
1111use rustc_abi:: ExternAbi ;
1212use rustc_abi:: { BackendRepr , HasDataLayout , WrappingRange } ;
1313use rustc_codegen_ssa:: MemFlags ;
@@ -22,13 +22,18 @@ use rustc_codegen_ssa::traits::{
2222 ArgAbiBuilderMethods , BaseTypeCodegenMethods , BuilderMethods , ConstCodegenMethods ,
2323 IntrinsicCallBuilderMethods , LayoutTypeCodegenMethods ,
2424} ;
25+ use rustc_data_structures:: fx:: FxHashSet ;
2526use rustc_middle:: bug;
2627use rustc_middle:: ty:: layout:: { FnAbiOf , LayoutOf } ;
2728use rustc_middle:: ty:: { self , Instance , Ty } ;
29+ #[ cfg( feature = "master" ) ]
30+ use rustc_session:: config;
2831use rustc_span:: { Span , Symbol , sym} ;
32+ #[ cfg( feature = "master" ) ]
33+ use rustc_target:: callconv:: ArgAttributes ;
2934use rustc_target:: callconv:: { ArgAbi , PassMode } ;
3035
31- use crate :: abi:: { FnAbiGccExt , GccType } ;
36+ use crate :: abi:: { FnAbiGcc , FnAbiGccExt , GccType } ;
3237use crate :: builder:: Builder ;
3338use crate :: common:: { SignType , TypeReflection } ;
3439use crate :: context:: CodegenCx ;
@@ -621,7 +626,82 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
621626 } else {
622627 self . linkage . set ( FunctionType :: Extern ) ;
623628 let fn_abi = self . fn_abi_of_instance ( instance, ty:: List :: empty ( ) ) ;
624- let fn_ty = fn_abi. gcc_type ( self ) ;
629+ assert ! ( !fn_abi. ret. is_indirect( ) ) ;
630+ assert ! ( !fn_abi. c_variadic) ;
631+
632+ let return_type = match fn_abi. ret . mode {
633+ PassMode :: Ignore => self . type_void ( ) ,
634+ PassMode :: Direct ( _) | PassMode :: Pair ( ..) => {
635+ fn_abi. ret . layout . immediate_gcc_type ( self )
636+ }
637+ PassMode :: Cast { .. } | PassMode :: Indirect { .. } => {
638+ unreachable ! ( )
639+ }
640+ } ;
641+
642+ #[ cfg( feature = "master" ) ]
643+ let mut non_null_args = Vec :: new ( ) ;
644+
645+ #[ cfg( feature = "master" ) ]
646+ let mut apply_attrs =
647+ |mut ty : Type < ' gcc > , attrs : & ArgAttributes , arg_index : usize | {
648+ if self . sess ( ) . opts . optimize == config:: OptLevel :: No {
649+ return ty;
650+ }
651+ if attrs. regular . contains ( rustc_target:: callconv:: ArgAttribute :: NoAlias ) {
652+ ty = ty. make_restrict ( )
653+ }
654+ if attrs. regular . contains ( rustc_target:: callconv:: ArgAttribute :: NonNull ) {
655+ non_null_args. push ( arg_index as i32 + 1 ) ;
656+ }
657+ ty
658+ } ;
659+ #[ cfg( not( feature = "master" ) ) ]
660+ let apply_attrs = |ty : Type < ' gcc > , _attrs : & ArgAttributes , _arg_index : usize | ty;
661+
662+ let mut argument_tys = Vec :: with_capacity ( fn_abi. args . len ( ) ) ;
663+ for arg in fn_abi. args . iter ( ) {
664+ match arg. mode {
665+ PassMode :: Ignore => { }
666+ PassMode :: Pair ( a, b) => {
667+ let arg_pos = argument_tys. len ( ) ;
668+ argument_tys. push ( apply_attrs (
669+ arg. layout . scalar_pair_element_gcc_type ( self , 0 ) ,
670+ & a,
671+ arg_pos,
672+ ) ) ;
673+ argument_tys. push ( apply_attrs (
674+ arg. layout . scalar_pair_element_gcc_type ( self , 1 ) ,
675+ & b,
676+ arg_pos + 1 ,
677+ ) ) ;
678+ }
679+ PassMode :: Direct ( attrs) => argument_tys. push ( apply_attrs (
680+ arg. layout . immediate_gcc_type ( self ) ,
681+ & attrs,
682+ argument_tys. len ( ) ,
683+ ) ) ,
684+ PassMode :: Indirect { .. } | PassMode :: Cast { .. } => {
685+ unreachable ! ( )
686+ }
687+ }
688+ }
689+
690+ #[ cfg( feature = "master" ) ]
691+ let fn_attrs = if non_null_args. is_empty ( ) {
692+ Vec :: new ( )
693+ } else {
694+ vec ! [ FnAttribute :: NonNull ( non_null_args) ]
695+ } ;
696+
697+ let fn_ty = FnAbiGcc {
698+ return_type,
699+ arguments_type : argument_tys,
700+ is_c_variadic : false ,
701+ on_stack_param_indices : FxHashSet :: default ( ) ,
702+ #[ cfg( feature = "master" ) ]
703+ fn_attributes : fn_attrs,
704+ } ;
625705
626706 let func = match sym {
627707 "llvm.fma.f16" => {
0 commit comments