Skip to content

Commit a829eba

Browse files
authored
[Triple] Ignore the vendor field for MinGW, wrt LTO/IR compatibility (#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.
1 parent 43f203d commit a829eba

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

llvm/lib/TargetParser/Triple.cpp

+16-5
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,10 @@ bool Triple::isLittleEndian() const {
20242024
}
20252025

20262026
bool Triple::isCompatibleWith(const Triple &Other) const {
2027+
// On MinGW, C code is usually built with a "w64" vendor, while Rust
2028+
// often uses a "pc" vendor.
2029+
bool IgnoreVendor = isWindowsGNUEnvironment();
2030+
20272031
// ARM and Thumb triples are compatible, if subarch, vendor and OS match.
20282032
if ((getArch() == Triple::thumb && Other.getArch() == Triple::arm) ||
20292033
(getArch() == Triple::arm && Other.getArch() == Triple::thumb) ||
@@ -2034,17 +2038,24 @@ bool Triple::isCompatibleWith(const Triple &Other) const {
20342038
getVendor() == Other.getVendor() && getOS() == Other.getOS();
20352039
else
20362040
return getSubArch() == Other.getSubArch() &&
2037-
getVendor() == Other.getVendor() && getOS() == Other.getOS() &&
2041+
(getVendor() == Other.getVendor() || IgnoreVendor) &&
2042+
getOS() == Other.getOS() &&
20382043
getEnvironment() == Other.getEnvironment() &&
20392044
getObjectFormat() == Other.getObjectFormat();
20402045
}
20412046

2042-
// If vendor is apple, ignore the version number.
2047+
// If vendor is apple, ignore the version number (the environment field)
2048+
// and the object format.
20432049
if (getVendor() == Triple::Apple)
20442050
return getArch() == Other.getArch() && getSubArch() == Other.getSubArch() &&
2045-
getVendor() == Other.getVendor() && getOS() == Other.getOS();
2046-
2047-
return *this == Other;
2051+
(getVendor() == Other.getVendor() || IgnoreVendor) &&
2052+
getOS() == Other.getOS();
2053+
2054+
return getArch() == Other.getArch() && getSubArch() == Other.getSubArch() &&
2055+
(getVendor() == Other.getVendor() || IgnoreVendor) &&
2056+
getOS() == Other.getOS() &&
2057+
getEnvironment() == Other.getEnvironment() &&
2058+
getObjectFormat() == Other.getObjectFormat();
20482059
}
20492060

20502061
std::string Triple::merge(const Triple &Other) const {

llvm/unittests/TargetParser/TripleTest.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/TargetParser/Triple.h"
10+
#include "llvm/Support/FormatVariadic.h"
1011
#include "llvm/Support/VersionTuple.h"
1112
#include "gtest/gtest.h"
1213

@@ -2737,4 +2738,41 @@ TEST(TripleTest, DXILNormaizeWithVersion) {
27372738
EXPECT_EQ("dxilv1.0-pc-shadermodel5.0-compute",
27382739
Triple::normalize("dxil-shadermodel5.0-pc-compute"));
27392740
}
2741+
2742+
TEST(TripleTest, isCompatibleWith) {
2743+
struct {
2744+
const char *A;
2745+
const char *B;
2746+
bool Result;
2747+
} Cases[] = {
2748+
{"armv7-linux-gnueabihf", "thumbv7-linux-gnueabihf", true},
2749+
{"armv4-none-unknown-eabi", "thumbv6-unknown-linux-gnueabihf", false},
2750+
{"x86_64-apple-macosx10.9.0", "x86_64-apple-macosx10.10.0", true},
2751+
{"x86_64-apple-macosx10.9.0", "i386-apple-macosx10.9.0", false},
2752+
{"x86_64-apple-macosx10.9.0", "x86_64h-apple-macosx10.9.0", true},
2753+
{"x86_64-unknown-linux-gnu", "x86_64-unknown-linux-gnu", true},
2754+
{"x86_64-unknown-linux-gnu", "i386-unknown-linux-gnu", false},
2755+
{"x86_64-unknown-linux-gnu", "x86_64h-unknown-linux-gnu", true},
2756+
{"x86_64-pc-windows-gnu", "x86_64-pc-windows-msvc", false},
2757+
{"x86_64-pc-windows-msvc", "x86_64-pc-windows-msvc-elf", false},
2758+
{"i686-w64-windows-gnu", "i386-w64-windows-gnu", true},
2759+
{"x86_64-w64-windows-gnu", "x86_64-pc-windows-gnu", true},
2760+
{"armv7-w64-windows-gnu", "thumbv7-pc-windows-gnu", true},
2761+
};
2762+
2763+
auto DoTest = [](const char *A, const char *B,
2764+
bool Result) -> testing::AssertionResult {
2765+
if (Triple(A).isCompatibleWith(Triple(B)) != Result) {
2766+
return testing::AssertionFailure()
2767+
<< llvm::formatv("Triple {0} and {1} were expected to be {2}", A,
2768+
B, Result ? "compatible" : "incompatible");
2769+
}
2770+
return testing::AssertionSuccess();
2771+
};
2772+
for (const auto &C : Cases) {
2773+
EXPECT_TRUE(DoTest(C.A, C.B, C.Result));
2774+
// Test that the comparison is commutative.
2775+
EXPECT_TRUE(DoTest(C.B, C.A, C.Result));
2776+
}
2777+
}
27402778
} // end anonymous namespace

0 commit comments

Comments
 (0)