[clang] [Clang] __has_builtin should return false for aux triple builtins (PR #121839)
Nick Sarnie via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 7 01:22:25 PST 2025
https://github.com/sarnex updated https://github.com/llvm/llvm-project/pull/121839
>From 997373350540448d91f9884b98cbdc0df058a7a3 Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sarnie at intel.com>
Date: Mon, 6 Jan 2025 11:48:07 -0800
Subject: [PATCH 1/2] [Clang] __has_builtin should return false for aux triple
builtins
Signed-off-by: Sarnie, Nick <nick.sarnie at intel.com>
---
clang/include/clang/Basic/Builtins.h | 5 +++++
clang/lib/Basic/Builtins.cpp | 19 +++++++++++++++++++
clang/lib/Lex/PPMacroExpansion.cpp | 20 +++++++++++++++++---
clang/test/Preprocessor/builtin_aux_info.cpp | 12 ++++++++++++
4 files changed, 53 insertions(+), 3 deletions(-)
create mode 100644 clang/test/Preprocessor/builtin_aux_info.cpp
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index 63559d977ce6b6..0939f95b0922c1 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -74,6 +74,7 @@ struct Info {
const char *Features;
HeaderDesc Header;
LanguageID Langs;
+ bool operator==(const Info &Other) const;
};
/// Holds information about both target-independent and
@@ -268,6 +269,10 @@ class Context {
/// for AuxTarget).
unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
+ // Return true if the AuxBuiltin ID represents a target-specific builtin that
+ // is always unsupported on the default target.
+ bool isAuxBuiltinIDAlwaysUnsupportedOnDefaultTarget(unsigned ID) const;
+
/// Returns true if this is a libc/libm function without the '__builtin_'
/// prefix.
static bool isBuiltinFunc(llvm::StringRef Name);
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index 588183788de322..c6e54b89e848cc 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -41,6 +41,14 @@ static constexpr Builtin::Info BuiltinInfo[] = {
#include "clang/Basic/Builtins.inc"
};
+bool Builtin::Info::operator==(const Builtin::Info &Other) const {
+ auto StrCompare = [](StringRef A, StringRef B) { return A == B; };
+ return Name == Other.Name && StrCompare(Type, Other.Type) &&
+ StrCompare(Attributes, Other.Attributes) &&
+ StrCompare(Features, Other.Features) && Header.ID == Other.Header.ID &&
+ Langs == Other.Langs;
+}
+
const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
if (ID < Builtin::FirstTSBuiltin)
return BuiltinInfo[ID];
@@ -183,6 +191,17 @@ unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const {
return Width;
}
+bool Builtin::Context::isAuxBuiltinIDAlwaysUnsupportedOnDefaultTarget(
+ unsigned ID) const {
+ assert(isAuxTargetBuiltinID(ID) && "Expected aux target builtin ID");
+ const auto &Record = getRecord(ID);
+ for (const auto &MainTargetBuiltin : TSRecords)
+ if (Record == MainTargetBuiltin)
+ return false;
+
+ return true;
+}
+
bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx,
bool &HasVAListArg, const char *Fmt) const {
assert(Fmt && "Not passed a format string");
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 347c13da0ad215..13d9a0094a5827 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1804,8 +1804,9 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
diag::err_feature_check_malformed);
if (!II)
return false;
- else if (II->getBuiltinID() != 0) {
- switch (II->getBuiltinID()) {
+ auto BuiltinID = II->getBuiltinID();
+ if (BuiltinID != 0) {
+ switch (BuiltinID) {
case Builtin::BI__builtin_cpu_is:
return getTargetInfo().supportsCpuIs();
case Builtin::BI__builtin_cpu_init:
@@ -1818,8 +1819,21 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
// usual allocation and deallocation functions. Required by libc++
return 201802;
default:
+ // We may get here because of aux builtins which may not be
+ // supported on the default target, for example if we have an X86
+ // specific builtin and the current target is SPIR-V. Sometimes we
+ // rely on __has_builtin returning true when passed a builtin that
+ // is not supported on the default target due to LangOpts but is
+ // supported on the aux target. See
+ // test/Headers/__cpuidex_conflict.c for an example. If the builtin
+ // is an aux builtin and it can never be supported on the default
+ // target, __has_builtin should return false.
+ if (getBuiltinInfo().isAuxBuiltinID(BuiltinID) &&
+ getBuiltinInfo().isAuxBuiltinIDAlwaysUnsupportedOnDefaultTarget(
+ BuiltinID))
+ return false;
return Builtin::evaluateRequiredTargetFeatures(
- getBuiltinInfo().getRequiredFeatures(II->getBuiltinID()),
+ getBuiltinInfo().getRequiredFeatures(BuiltinID),
getTargetInfo().getTargetOpts().FeatureMap);
}
return true;
diff --git a/clang/test/Preprocessor/builtin_aux_info.cpp b/clang/test/Preprocessor/builtin_aux_info.cpp
new file mode 100644
index 00000000000000..041c7edfdcadac
--- /dev/null
+++ b/clang/test/Preprocessor/builtin_aux_info.cpp
@@ -0,0 +1,12 @@
+// REQUIRES: spirv-registered-target
+// REQUIRES: x86-registered-target
+
+// RUN: %clang_cc1 -fopenmp -triple=spirv64 -fopenmp-is-target-device \
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck -implicit-check-not=BAD %s
+
+// CHECK: GOOD
+#if __has_builtin(__builtin_ia32_pause)
+ BAD
+#else
+ GOOD
+#endif
>From 55c6d061fc7dc4a011df92b99f99f064e7704b11 Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sarnie at intel.com>
Date: Tue, 7 Jan 2025 01:22:00 -0800
Subject: [PATCH 2/2] Fix build
Signed-off-by: Sarnie, Nick <nick.sarnie at intel.com>
---
clang/lib/Basic/Builtins.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index c6e54b89e848cc..bd443b3b371e35 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -193,7 +193,7 @@ unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const {
bool Builtin::Context::isAuxBuiltinIDAlwaysUnsupportedOnDefaultTarget(
unsigned ID) const {
- assert(isAuxTargetBuiltinID(ID) && "Expected aux target builtin ID");
+ assert(isAuxBuiltinID(ID) && "Expected aux target builtin ID");
const auto &Record = getRecord(ID);
for (const auto &MainTargetBuiltin : TSRecords)
if (Record == MainTargetBuiltin)
More information about the cfe-commits
mailing list