@@ -906,6 +906,15 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
906906 traceMessage.c_str (), witness->getOriginalFunction ());
907907
908908 assert (witness->isDefinition ());
909+ SILFunction *orig = witness->getOriginalFunction ();
910+
911+ // We can generate empty JVP / VJP for functions available externally. These
912+ // functions have the same linkage as the original ones sans `external`
913+ // flag. Important exception here hidden_external functions as they are
914+ // serializable but corresponding hidden ones would be not and the SIL
915+ // verifier will fail. Patch `serializeFunctions` for this case.
916+ if (orig->getLinkage () == SILLinkage::HiddenExternal)
917+ serializeFunctions = IsNotSerialized;
909918
910919 // If the JVP doesn't exist, need to synthesize it.
911920 if (!witness->getJVP ()) {
@@ -914,9 +923,8 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
914923 // - Functions with unsupported control flow.
915924 if (context.getASTContext ()
916925 .LangOpts .hasFeature (Feature::ForwardModeDifferentiation) &&
917- (diagnoseNoReturn (context, witness->getOriginalFunction (), invoker) ||
918- diagnoseUnsupportedControlFlow (
919- context, witness->getOriginalFunction (), invoker)))
926+ (diagnoseNoReturn (context, orig, invoker) ||
927+ diagnoseUnsupportedControlFlow (context, orig, invoker)))
920928 return true ;
921929
922930 // Create empty JVP.
@@ -933,10 +941,10 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
933941 !witness->getVJP ()) {
934942 // JVP and differential generation do not currently support functions with
935943 // multiple basic blocks.
936- if (witness-> getOriginalFunction () ->size () > 1 ) {
937- context.emitNondifferentiabilityError (
938- witness-> getOriginalFunction ()-> getLocation (). getSourceLoc () ,
939- invoker, diag::autodiff_jvp_control_flow_not_supported);
944+ if (orig ->size () > 1 ) {
945+ context.emitNondifferentiabilityError (orig-> getLocation (). getSourceLoc (),
946+ invoker ,
947+ diag::autodiff_jvp_control_flow_not_supported);
940948 return true ;
941949 }
942950 // Emit JVP function.
@@ -950,7 +958,7 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
950958 " _fatalErrorForwardModeDifferentiationDisabled" );
951959 LLVM_DEBUG (getADDebugStream ()
952960 << " Generated empty JVP for "
953- << witness-> getOriginalFunction () ->getName () << " :\n "
961+ << orig ->getName () << " :\n "
954962 << *jvp);
955963 }
956964 }
@@ -960,9 +968,8 @@ bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness(
960968 // Diagnose:
961969 // - Functions with no return.
962970 // - Functions with unsupported control flow.
963- if (diagnoseNoReturn (context, witness->getOriginalFunction (), invoker) ||
964- diagnoseUnsupportedControlFlow (
965- context, witness->getOriginalFunction (), invoker))
971+ if (diagnoseNoReturn (context, orig, invoker) ||
972+ diagnoseUnsupportedControlFlow (context, orig, invoker))
966973 return true ;
967974
968975 // Create empty VJP.
0 commit comments