@@ -30,6 +30,7 @@ use crate::abi::FnAbiLlvmExt;
3030use crate :: builder:: Builder ;
3131use crate :: builder:: autodiff:: { adjust_activity_to_abi, generate_enzyme_call} ;
3232use crate :: context:: CodegenCx ;
33+ use crate :: declare:: declare_raw_fn;
3334use crate :: errors:: { AutoDiffWithoutEnable , AutoDiffWithoutLto } ;
3435use crate :: llvm:: { self , Metadata , Type , Value } ;
3536use crate :: type_of:: LayoutLlvmExt ;
@@ -619,11 +620,41 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
619620 args : & [ OperandRef < ' tcx , Self :: Value > ] ,
620621 is_cleanup : bool ,
621622 ) -> Self :: Value {
622- let fn_ptr = self . get_fn_addr ( instance) ;
623+ let tcx = self . tcx ( ) ;
624+
623625 // FIXME remove usage of fn_abi
624626 let fn_abi = self . fn_abi_of_instance ( instance, ty:: List :: empty ( ) ) ;
625627 assert ! ( !fn_abi. ret. is_indirect( ) ) ;
626- let fn_ty = self . fn_decl_backend_type ( fn_abi) ;
628+ let fn_ty = fn_abi. llvm_type ( self ) ;
629+
630+ let fn_ptr = if let Some ( & llfn) = self . intrinsic_instances . borrow ( ) . get ( & instance) {
631+ llfn
632+ } else {
633+ let sym = tcx. symbol_name ( instance) . name ;
634+
635+ // FIXME use get_intrinsic
636+ let llfn = if let Some ( llfn) = self . get_declared_value ( sym) {
637+ llfn
638+ } else {
639+ // Function addresses in Rust are never significant, allowing functions to
640+ // be merged.
641+ let llfn = declare_raw_fn (
642+ self ,
643+ sym,
644+ fn_abi. llvm_cconv ( self ) ,
645+ llvm:: UnnamedAddr :: Global ,
646+ llvm:: Visibility :: Default ,
647+ fn_ty,
648+ ) ;
649+ fn_abi. apply_attrs_llfn ( self , llfn, Some ( instance) ) ;
650+
651+ llfn
652+ } ;
653+
654+ self . intrinsic_instances . borrow_mut ( ) . insert ( instance, llfn) ;
655+
656+ llfn
657+ } ;
627658
628659 let mut llargs = vec ! [ ] ;
629660
0 commit comments