Skip to content

Commit c653a7d

Browse files
committed
Operator ?? is hidden_external and therefore might be serialized.
empty JVPs / VJPs has the same linkage as the original function sans external flag and also inherit serialization flag. This works for all cases but not for hidden_external ones. Drop serializable flag for such case
1 parent c8fb9cf commit c653a7d

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

lib/SILOptimizer/Mandatory/Differentiation.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)