[clang] [Clang] __has_builtin should return false for aux triple builtins (PR #121839)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 7 05:57:54 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Nick Sarnie (sarnex)

<details>
<summary>Changes</summary>

Currently, `__has_builtin` will return true when passed a builtin that is only supported on the aux target. I found this when  `__has_builtin` was called with an X86 builtin but the current target was SPIR-V.

If we know for sure the builtin can't be supported on the current target, the function should return false.

We can't simply check if it's an aux builtin, see the test mentioned in the comment.

---
Full diff: https://github.com/llvm/llvm-project/pull/121839.diff


4 Files Affected:

- (modified) clang/include/clang/Basic/Builtins.h (+5) 
- (modified) clang/lib/Basic/Builtins.cpp (+19) 
- (modified) clang/lib/Lex/PPMacroExpansion.cpp (+17-3) 
- (added) clang/test/Preprocessor/builtin_aux_info.cpp (+12) 


``````````diff
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..bd443b3b371e35 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(isAuxBuiltinID(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

``````````

</details>


https://github.com/llvm/llvm-project/pull/121839


More information about the cfe-commits mailing list