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