@@ -9,7 +9,7 @@ use gccjit::Type;
99use gccjit:: { ComparisonOp , Function , FunctionType , RValue , ToRValue , UnaryOp } ;
1010#[ cfg( feature = "master" ) ]
1111use rustc_abi:: ExternAbi ;
12- use rustc_abi:: { BackendRepr , HasDataLayout } ;
12+ use rustc_abi:: { BackendRepr , HasDataLayout , WrappingRange } ;
1313use rustc_codegen_ssa:: MemFlags ;
1414use rustc_codegen_ssa:: base:: wants_msvc_seh;
1515use rustc_codegen_ssa:: common:: IntPredicate ;
@@ -20,7 +20,7 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
2020use rustc_codegen_ssa:: traits:: MiscCodegenMethods ;
2121use rustc_codegen_ssa:: traits:: {
2222 ArgAbiBuilderMethods , BaseTypeCodegenMethods , BuilderMethods , ConstCodegenMethods ,
23- IntrinsicCallBuilderMethods ,
23+ IntrinsicCallBuilderMethods , LayoutTypeCodegenMethods ,
2424} ;
2525use rustc_middle:: bug;
2626#[ cfg( feature = "master" ) ]
@@ -609,6 +609,54 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
609609 Ok ( ( ) )
610610 }
611611
612+ fn codegen_llvm_intrinsic_call (
613+ & mut self ,
614+ instance : ty:: Instance < ' tcx > ,
615+ args : & [ OperandRef < ' tcx , Self :: Value > ] ,
616+ is_cleanup : bool ,
617+ ) -> Self :: Value {
618+ let fn_ptr = self . get_fn_addr ( instance) ;
619+ let fn_ty = fn_ptr. get_type ( ) ;
620+
621+ let mut llargs = vec ! [ ] ;
622+
623+ for arg in args {
624+ match arg. val {
625+ OperandValue :: ZeroSized => { }
626+ OperandValue :: Immediate ( _) => llargs. push ( arg. immediate ( ) ) ,
627+ OperandValue :: Pair ( a, b) => {
628+ llargs. push ( a) ;
629+ llargs. push ( b) ;
630+ }
631+ OperandValue :: Ref ( op_place_val) => {
632+ let mut llval = op_place_val. llval ;
633+ // We can't use `PlaceRef::load` here because the argument
634+ // may have a type we don't treat as immediate, but the ABI
635+ // used for this call is passing it by-value. In that case,
636+ // the load would just produce `OperandValue::Ref` instead
637+ // of the `OperandValue::Immediate` we need for the call.
638+ llval = self . load ( self . backend_type ( arg. layout ) , llval, op_place_val. align ) ;
639+ if let BackendRepr :: Scalar ( scalar) = arg. layout . backend_repr {
640+ if scalar. is_bool ( ) {
641+ self . range_metadata ( llval, WrappingRange { start : 0 , end : 1 } ) ;
642+ }
643+ // We store bools as `i8` so we need to truncate to `i1`.
644+ llval = self . to_immediate_scalar ( llval, scalar) ;
645+ }
646+ llargs. push ( llval) ;
647+ }
648+ }
649+ }
650+
651+ // FIXME directly use the llvm intrinsic adjustment functions here
652+ let llret = self . call ( fn_ty, None , None , fn_ptr, & llargs, None , None ) ;
653+ if is_cleanup {
654+ self . apply_attrs_to_cleanup_callsite ( llret) ;
655+ }
656+
657+ llret
658+ }
659+
612660 fn abort ( & mut self ) {
613661 let func = self . context . get_builtin_function ( "abort" ) ;
614662 let func: RValue < ' gcc > = unsafe { std:: mem:: transmute ( func) } ;
0 commit comments