@@ -28,6 +28,7 @@ use crate::abi::FnAbiLlvmExt;
2828use crate :: builder:: Builder ;
2929use crate :: builder:: autodiff:: { adjust_activity_to_abi, generate_enzyme_call} ;
3030use crate :: context:: CodegenCx ;
31+ use crate :: declare:: declare_raw_fn;
3132use crate :: errors:: AutoDiffWithoutEnable ;
3233use crate :: llvm:: { self , Metadata , Type , Value } ;
3334use crate :: type_of:: LayoutLlvmExt ;
@@ -627,11 +628,41 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
627628 args : & [ OperandRef < ' tcx , Self :: Value > ] ,
628629 is_cleanup : bool ,
629630 ) -> Self :: Value {
630- let fn_ptr = self . get_fn_addr ( instance) ;
631+ let tcx = self . tcx ( ) ;
632+
631633 // FIXME remove usage of fn_abi
632634 let fn_abi = self . fn_abi_of_instance ( instance, ty:: List :: empty ( ) ) ;
633635 assert ! ( !fn_abi. ret. is_indirect( ) ) ;
634- let fn_ty = self . fn_decl_backend_type ( fn_abi) ;
636+ let fn_ty = fn_abi. llvm_type ( self ) ;
637+
638+ let fn_ptr = if let Some ( & llfn) = self . intrinsic_instances . borrow ( ) . get ( & instance) {
639+ llfn
640+ } else {
641+ let sym = tcx. symbol_name ( instance) . name ;
642+
643+ // FIXME use get_intrinsic
644+ let llfn = if let Some ( llfn) = self . get_declared_value ( sym) {
645+ llfn
646+ } else {
647+ // Function addresses in Rust are never significant, allowing functions to
648+ // be merged.
649+ let llfn = declare_raw_fn (
650+ self ,
651+ sym,
652+ fn_abi. llvm_cconv ( self ) ,
653+ llvm:: UnnamedAddr :: Global ,
654+ llvm:: Visibility :: Default ,
655+ fn_ty,
656+ ) ;
657+ fn_abi. apply_attrs_llfn ( self , llfn, Some ( instance) ) ;
658+
659+ llfn
660+ } ;
661+
662+ self . intrinsic_instances . borrow_mut ( ) . insert ( instance, llfn) ;
663+
664+ llfn
665+ } ;
635666
636667 let mut llargs = vec ! [ ] ;
637668
0 commit comments