Frontend: Fix -target-variant subarch normalization.

In https://github.com/swiftlang/swift/pull/77156, normalization was introduced
for -target-variant triples. That PR also caused -target-variant arguments to
be inherited from the main compilation options whenever building dependency
modules from their interfaces, which is incorrect. The -target-variant option
must only be specified when compiling a "zippered" module, but the dependencies
of zippered modules are not necessarily zippered themselves and
indiscriminantly propagating the option can cause miscompilation.

The new, more targeted approach to normalizing arm64e triples simply uses the
arch and subarch of the -target argument of the main compile to decide whether
the subarch of both the -target and -target-variant arguments of a dependency
need adjustment.

Resolves rdar://135322077 and rdar://141640919.
This commit is contained in:
Allan Shortlidge
2024-12-20 16:10:16 -08:00
parent 0b6ab9a866
commit 3f0eb8ce2c
10 changed files with 203 additions and 42 deletions

View File

@@ -1390,14 +1390,6 @@ void swift::serialization::diagnoseSerializedASTLoadFailureTransitive(
}
}
static bool tripleNeedsSubarchitectureAdjustment(const llvm::Triple &lhs, const llvm::Triple &rhs) {
return (lhs.getSubArch() != rhs.getSubArch() &&
lhs.getArch() == rhs.getArch() &&
lhs.getVendor() == rhs.getVendor() &&
lhs.getOS() == rhs.getOS() &&
lhs.getEnvironment() == rhs.getEnvironment());
}
static std::optional<StringRef> getFlagsFromInterfaceFile(StringRef &file,
StringRef prefix) {
StringRef line, buffer = file;
@@ -1419,8 +1411,7 @@ static std::optional<StringRef> getFlagsFromInterfaceFile(StringRef &file,
bool swift::extractCompilerFlagsFromInterface(
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
SmallVectorImpl<const char *> &SubArgs,
std::optional<llvm::Triple> PreferredTarget,
std::optional<llvm::Triple> PreferredTargetVariant) {
std::optional<llvm::Triple> PreferredTarget) {
auto FlagMatch = getFlagsFromInterfaceFile(buffer, SWIFT_MODULE_FLAGS_KEY);
if (!FlagMatch)
return true;
@@ -1430,19 +1421,19 @@ bool swift::extractCompilerFlagsFromInterface(
// only in subarchitecture from the compatible target triple, then
// we have loaded a Swift interface from a different-but-compatible
// architecture slice. Use the compatible subarchitecture.
for (unsigned I = 1; I < SubArgs.size(); ++I) {
if (strcmp(SubArgs[I - 1], "-target") == 0) {
llvm::Triple target(SubArgs[I]);
if (PreferredTarget &&
tripleNeedsSubarchitectureAdjustment(target, *PreferredTarget))
target.setArch(PreferredTarget->getArch(), PreferredTarget->getSubArch());
SubArgs[I] = ArgSaver.save(target.str()).data();
} else if (strcmp(SubArgs[I - 1], "-target-variant") == 0) {
llvm::Triple targetVariant(SubArgs[I]);
if (PreferredTargetVariant &&
tripleNeedsSubarchitectureAdjustment(targetVariant, *PreferredTargetVariant))
targetVariant.setArch(PreferredTargetVariant->getArch(), PreferredTargetVariant->getSubArch());
SubArgs[I] = ArgSaver.save(targetVariant.str()).data();
if (PreferredTarget) {
for (unsigned I = 1; I < SubArgs.size(); ++I) {
if (strcmp(SubArgs[I - 1], "-target") != 0 &&
strcmp(SubArgs[I - 1], "-target-variant") != 0)
continue;
llvm::Triple triple(SubArgs[I]);
if (triple.getArch() != PreferredTarget->getArch())
continue;
if (triple.getSubArch() == PreferredTarget->getSubArch())
continue;
triple.setArch(PreferredTarget->getArch(), PreferredTarget->getSubArch());
SubArgs[I] = ArgSaver.save(triple.str()).data();
}
}