Skip to content

Commit

Permalink
[Triple] Ignore the vendor field for MinGW, wrt LTO/IR compatibility (l…
Browse files Browse the repository at this point in the history
…lvm#122801)

For MinGW environments, the regular C/C++ toolchains usually use "w64"
for the vendor field in triples, while Rust toolchains usually use "pc"
in the vendor field.

The differences in the vendor field have no bearing on whether the IR is
compatible on this platform. (This probably goes for most other OSes as
well, but limiting the scope of the change to the specific case.)

Add a unit test for the isCompatibleWith, including some existing test
cases found in existing tests.
  • Loading branch information
mstorsjo authored and paulhuggett committed Jan 16, 2025
1 parent 46b282a commit 96cddda
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 5 deletions.
21 changes: 16 additions & 5 deletions llvm/lib/TargetParser/Triple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2024,6 +2024,10 @@ bool Triple::isLittleEndian() const {
}

bool Triple::isCompatibleWith(const Triple &Other) const {
// On MinGW, C code is usually built with a "w64" vendor, while Rust
// often uses a "pc" vendor.
bool IgnoreVendor = isWindowsGNUEnvironment();

// ARM and Thumb triples are compatible, if subarch, vendor and OS match.
if ((getArch() == Triple::thumb && Other.getArch() == Triple::arm) ||
(getArch() == Triple::arm && Other.getArch() == Triple::thumb) ||
Expand All @@ -2034,17 +2038,24 @@ bool Triple::isCompatibleWith(const Triple &Other) const {
getVendor() == Other.getVendor() && getOS() == Other.getOS();
else
return getSubArch() == Other.getSubArch() &&
getVendor() == Other.getVendor() && getOS() == Other.getOS() &&
(getVendor() == Other.getVendor() || IgnoreVendor) &&
getOS() == Other.getOS() &&
getEnvironment() == Other.getEnvironment() &&
getObjectFormat() == Other.getObjectFormat();
}

// If vendor is apple, ignore the version number.
// If vendor is apple, ignore the version number (the environment field)
// and the object format.
if (getVendor() == Triple::Apple)
return getArch() == Other.getArch() && getSubArch() == Other.getSubArch() &&
getVendor() == Other.getVendor() && getOS() == Other.getOS();

return *this == Other;
(getVendor() == Other.getVendor() || IgnoreVendor) &&
getOS() == Other.getOS();

return getArch() == Other.getArch() && getSubArch() == Other.getSubArch() &&
(getVendor() == Other.getVendor() || IgnoreVendor) &&
getOS() == Other.getOS() &&
getEnvironment() == Other.getEnvironment() &&
getObjectFormat() == Other.getObjectFormat();
}

std::string Triple::merge(const Triple &Other) const {
Expand Down
38 changes: 38 additions & 0 deletions llvm/unittests/TargetParser/TripleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/TargetParser/Triple.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/VersionTuple.h"
#include "gtest/gtest.h"

Expand Down Expand Up @@ -2737,4 +2738,41 @@ TEST(TripleTest, DXILNormaizeWithVersion) {
EXPECT_EQ("dxilv1.0-pc-shadermodel5.0-compute",
Triple::normalize("dxil-shadermodel5.0-pc-compute"));
}

TEST(TripleTest, isCompatibleWith) {
struct {
const char *A;
const char *B;
bool Result;
} Cases[] = {
{"armv7-linux-gnueabihf", "thumbv7-linux-gnueabihf", true},
{"armv4-none-unknown-eabi", "thumbv6-unknown-linux-gnueabihf", false},
{"x86_64-apple-macosx10.9.0", "x86_64-apple-macosx10.10.0", true},
{"x86_64-apple-macosx10.9.0", "i386-apple-macosx10.9.0", false},
{"x86_64-apple-macosx10.9.0", "x86_64h-apple-macosx10.9.0", true},
{"x86_64-unknown-linux-gnu", "x86_64-unknown-linux-gnu", true},
{"x86_64-unknown-linux-gnu", "i386-unknown-linux-gnu", false},
{"x86_64-unknown-linux-gnu", "x86_64h-unknown-linux-gnu", true},
{"x86_64-pc-windows-gnu", "x86_64-pc-windows-msvc", false},
{"x86_64-pc-windows-msvc", "x86_64-pc-windows-msvc-elf", false},
{"i686-w64-windows-gnu", "i386-w64-windows-gnu", true},
{"x86_64-w64-windows-gnu", "x86_64-pc-windows-gnu", true},
{"armv7-w64-windows-gnu", "thumbv7-pc-windows-gnu", true},
};

auto DoTest = [](const char *A, const char *B,
bool Result) -> testing::AssertionResult {
if (Triple(A).isCompatibleWith(Triple(B)) != Result) {
return testing::AssertionFailure()
<< llvm::formatv("Triple {0} and {1} were expected to be {2}", A,
B, Result ? "compatible" : "incompatible");
}
return testing::AssertionSuccess();
};
for (const auto &C : Cases) {
EXPECT_TRUE(DoTest(C.A, C.B, C.Result));
// Test that the comparison is commutative.
EXPECT_TRUE(DoTest(C.B, C.A, C.Result));
}
}
} // end anonymous namespace

0 comments on commit 96cddda

Please sign in to comment.