https://github.com/sarnex updated 
https://github.com/llvm/llvm-project/pull/126324

>From 46cce74568bca5a3e80e50def4348bc734448362 Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Fri, 7 Feb 2025 14:57:12 -0800
Subject: [PATCH 1/9] [Clang] Add __has_target_builtin macro

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/docs/LanguageExtensions.rst             | 33 +++++++++++++++++++
 clang/include/clang/Lex/Preprocessor.h        |  1 +
 clang/lib/Lex/PPMacroExpansion.cpp            | 17 +++++++---
 .../test/Preprocessor/has_target_builtin.cpp  | 18 ++++++++++
 4 files changed, 64 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Preprocessor/has_target_builtin.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 973cf8f9d091c..057ad564f970b 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -67,6 +67,10 @@ It can be used like this:
   ``__has_builtin`` should not be used to detect support for a builtin macro;
   use ``#ifdef`` instead.
 
+  When using device offloading, a builtin is considered available if it is
+  available on either the host or the device targets.
+  Use ``__has_target_builtin`` to consider only the current target.
+
 ``__has_constexpr_builtin``
 ---------------------------
 
@@ -96,6 +100,35 @@ the ``<cmath>`` header file to conditionally make a 
function constexpr whenever
 the constant evaluation of the corresponding builtin (for example,
 ``std::fmax`` calls ``__builtin_fmax``) is supported in Clang.
 
+``__has_target_builtin``
+------------------------
+
+This function-like macro takes a single identifier argument that is the name of
+a builtin function, a builtin pseudo-function (taking one or more type
+arguments), or a builtin template.
+It evaluates to 1 if the builtin is supported on the current target or 0 if 
not.
+The behavior is different than ``__has_builtin`` when there is an auxiliary 
target,
+such when offloading to a target device.
+It can be used like this:
+
+.. code-block:: c++
+
+  #ifndef __has_target_builtin         // Optional of course.
+    #define __has_target_builtin(x) 0  // Compatibility with non-clang 
compilers.
+  #endif
+
+  ...
+  #if __has_target_builtin(__builtin_trap)
+    __builtin_trap();
+  #else
+    abort();
+  #endif
+  ...
+
+.. note::
+  ``__has_target_builtin`` should not be used to detect support for a builtin 
macro;
+  use ``#ifdef`` instead.
+
 .. _langext-__has_feature-__has_extension:
 
 ``__has_feature`` and ``__has_extension``
diff --git a/clang/include/clang/Lex/Preprocessor.h 
b/clang/include/clang/Lex/Preprocessor.h
index 2bf4d1a166994..240fe28aba93e 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -174,6 +174,7 @@ class Preprocessor {
   IdentifierInfo *Ident__has_extension;            // __has_extension
   IdentifierInfo *Ident__has_builtin;              // __has_builtin
   IdentifierInfo *Ident__has_constexpr_builtin;    // __has_constexpr_builtin
+  IdentifierInfo *Ident__has_target_builtin;       // __has_target_builtin
   IdentifierInfo *Ident__has_attribute;            // __has_attribute
   IdentifierInfo *Ident__has_embed;                // __has_embed
   IdentifierInfo *Ident__has_include;              // __has_include
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp 
b/clang/lib/Lex/PPMacroExpansion.cpp
index 944966a791add..9ec75a08316a1 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -357,6 +357,7 @@ void Preprocessor::RegisterBuiltinMacros() {
   Ident__has_builtin = RegisterBuiltinMacro("__has_builtin");
   Ident__has_constexpr_builtin =
       RegisterBuiltinMacro("__has_constexpr_builtin");
+  Ident__has_target_builtin = RegisterBuiltinMacro("__has_target_builtin");
   Ident__has_attribute = RegisterBuiltinMacro("__has_attribute");
   if (!getLangOpts().CPlusPlus)
     Ident__has_c_attribute = RegisterBuiltinMacro("__has_c_attribute");
@@ -1797,16 +1798,18 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
                                            diag::err_feature_check_malformed);
         return II && HasExtension(*this, II->getName());
       });
-  } else if (II == Ident__has_builtin) {
+  } else if (II == Ident__has_builtin || II == Ident__has_target_builtin) {
+    bool IsHasTargetBuiltin = II == Ident__has_target_builtin;
     EvaluateFeatureLikeBuiltinMacro(
         OS, Tok, II, *this, false,
-        [this](Token &Tok, bool &HasLexedNextToken) -> int {
+        [this, IsHasTargetBuiltin](Token &Tok, bool &HasLexedNextToken) -> int 
{
           IdentifierInfo *II = ExpectFeatureIdentifierInfo(
               Tok, *this, 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:
@@ -1819,8 +1822,12 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
               // usual allocation and deallocation functions. Required by 
libc++
               return 201802;
             default:
+              // __has_target_builtin should return false for aux builtins.
+              if (IsHasTargetBuiltin &&
+                  getBuiltinInfo().isAuxBuiltinID(BuiltinID))
+                return false;
               return Builtin::evaluateRequiredTargetFeatures(
-                  getBuiltinInfo().getRequiredFeatures(II->getBuiltinID()),
+                  getBuiltinInfo().getRequiredFeatures(BuiltinID),
                   getTargetInfo().getTargetOpts().FeatureMap);
             }
             return true;
diff --git a/clang/test/Preprocessor/has_target_builtin.cpp 
b/clang/test/Preprocessor/has_target_builtin.cpp
new file mode 100644
index 0000000000000..64b2d7e1b35d9
--- /dev/null
+++ b/clang/test/Preprocessor/has_target_builtin.cpp
@@ -0,0 +1,18 @@
+// 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
+
+// RUN: %clang_cc1 -fopenmp -triple=nvptx64 -fopenmp-is-target-device \
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=BAD %s
+
+// RUN: %clang_cc1 -fopenmp -triple=amdgcn-amd-amdhsa 
-fopenmp-is-target-device \
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=BAD %s
+
+// RUN: %clang_cc1 -fopenmp -triple=aarch64 -fopenmp-is-target-device \
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=BAD %s
+
+// CHECK: GOOD
+#if __has_target_builtin(__builtin_ia32_pause)
+  BAD
+#else
+  GOOD
+#endif

>From 2a2a18b3d1c0220cd55b922bea4fe0694a9a668f Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Mon, 10 Feb 2025 11:45:40 -0800
Subject: [PATCH 2/9] add release note, only define for offloading targets,
 update test

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/docs/LanguageExtensions.rst              |  5 ++++-
 clang/docs/ReleaseNotes.rst                    |  6 ++++++
 clang/lib/Lex/PPMacroExpansion.cpp             |  7 ++++++-
 clang/test/Preprocessor/has_target_builtin.cpp | 17 +++++++++++++----
 4 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 057ad564f970b..f284c2bfcd892 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -69,7 +69,8 @@ It can be used like this:
 
   When using device offloading, a builtin is considered available if it is
   available on either the host or the device targets.
-  Use ``__has_target_builtin`` to consider only the current target.
+  Use ``__has_target_builtin`` to consider only the current target for an
+  offloading target.
 
 ``__has_constexpr_builtin``
 ---------------------------
@@ -129,6 +130,8 @@ It can be used like this:
   ``__has_target_builtin`` should not be used to detect support for a builtin 
macro;
   use ``#ifdef`` instead.
 
+  ``__has_target_built`` is only defined for offloading targets.
+
 .. _langext-__has_feature-__has_extension:
 
 ``__has_feature`` and ``__has_extension``
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 50d3bbbc97e91..468c34266f2da 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -104,6 +104,12 @@ Non-comprehensive list of changes in this release
 New Compiler Flags
 ------------------
 
+New Compiler Builtins
+---------------------
+
+- The new ``__has_target_builtin`` macro can be used to check if a builtin is 
available
+  on the current offloading target.
+
 Deprecated Compiler Flags
 -------------------------
 
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp 
b/clang/lib/Lex/PPMacroExpansion.cpp
index 9ec75a08316a1..48b4c6acb96e1 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -357,7 +357,12 @@ void Preprocessor::RegisterBuiltinMacros() {
   Ident__has_builtin = RegisterBuiltinMacro("__has_builtin");
   Ident__has_constexpr_builtin =
       RegisterBuiltinMacro("__has_constexpr_builtin");
-  Ident__has_target_builtin = RegisterBuiltinMacro("__has_target_builtin");
+  if (getLangOpts().OpenMPIsTargetDevice || getLangOpts().CUDAIsDevice ||
+      getLangOpts().SYCLIsDevice)
+    Ident__has_target_builtin = RegisterBuiltinMacro("__has_target_builtin");
+  else
+    Ident__has_target_builtin = nullptr;
+
   Ident__has_attribute = RegisterBuiltinMacro("__has_attribute");
   if (!getLangOpts().CPlusPlus)
     Ident__has_c_attribute = RegisterBuiltinMacro("__has_c_attribute");
diff --git a/clang/test/Preprocessor/has_target_builtin.cpp 
b/clang/test/Preprocessor/has_target_builtin.cpp
index 64b2d7e1b35d9..e7f28a049af3b 100644
--- a/clang/test/Preprocessor/has_target_builtin.cpp
+++ b/clang/test/Preprocessor/has_target_builtin.cpp
@@ -1,18 +1,27 @@
 // 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
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not="{{BAD|DOESNT}}" %s
 
 // RUN: %clang_cc1 -fopenmp -triple=nvptx64 -fopenmp-is-target-device \
-// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=BAD %s
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not="{{BAD|DOESNT}}" %s
 
 // RUN: %clang_cc1 -fopenmp -triple=amdgcn-amd-amdhsa 
-fopenmp-is-target-device \
-// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=BAD %s
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not="{{BAD|DOESNT}}" %s
 
 // RUN: %clang_cc1 -fopenmp -triple=aarch64 -fopenmp-is-target-device \
-// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=BAD %s
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not="{{BAD|DOESNT}}" %s
+
+// RUN: %clang_cc1 -triple=aarch64 -E %s | FileCheck 
-check-prefix=CHECK-NOTOFFLOAD -implicit-check-not="{{GOOD|HAS|BAD}}" %s
 
 // CHECK: GOOD
+
+// CHECK-NOTOFFLOAD: DOESNT
+#ifdef __has_target_builtin
+  HAS
 #if __has_target_builtin(__builtin_ia32_pause)
   BAD
 #else
   GOOD
 #endif
+#else
+  DOESNT
+#endif

>From 644ea85450825e73b3c71c6e80333c90354805ea Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Mon, 10 Feb 2025 12:16:18 -0800
Subject: [PATCH 3/9] doc feedback

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/docs/LanguageExtensions.rst | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index f284c2bfcd892..34c87f9e7697f 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -109,18 +109,19 @@ a builtin function, a builtin pseudo-function (taking one 
or more type
 arguments), or a builtin template.
 It evaluates to 1 if the builtin is supported on the current target or 0 if 
not.
 The behavior is different than ``__has_builtin`` when there is an auxiliary 
target,
-such when offloading to a target device.
+such as when offloading to a target device.
 It can be used like this:
 
 .. code-block:: c++
-
-  #ifndef __has_target_builtin         // Optional of course.
-    #define __has_target_builtin(x) 0  // Compatibility with non-clang 
compilers.
-  #endif
-
-  ...
+  #ifdef __CUDA__
   #if __has_target_builtin(__builtin_trap)
     __builtin_trap();
+  #else
+      abort();
+  #endif
+  #else // !CUDA
+  #if __has_builtin(__builtin_trap)
+  __builtin_trap();
   #else
     abort();
   #endif
@@ -130,7 +131,7 @@ It can be used like this:
   ``__has_target_builtin`` should not be used to detect support for a builtin 
macro;
   use ``#ifdef`` instead.
 
-  ``__has_target_built`` is only defined for offloading targets.
+  ``__has_target_builtin`` is only defined for offloading targets.
 
 .. _langext-__has_feature-__has_extension:
 

>From 887de75686aaa64e0c5f81541ad9e9f9b6e00b37 Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Mon, 10 Feb 2025 12:40:26 -0800
Subject: [PATCH 4/9] improve comparison doc

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/docs/LanguageExtensions.rst | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 34c87f9e7697f..541a1ca0192d2 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -108,8 +108,17 @@ This function-like macro takes a single identifier 
argument that is the name of
 a builtin function, a builtin pseudo-function (taking one or more type
 arguments), or a builtin template.
 It evaluates to 1 if the builtin is supported on the current target or 0 if 
not.
-The behavior is different than ``__has_builtin`` when there is an auxiliary 
target,
-such as when offloading to a target device.
+
+``__has_builtin`` and ``__has_target_builtin`` behave identically for normal 
C++ compilations.
+
+For heterogeneous compilations that see source code intended for more than one 
target:
+
+``__has_builtin`` returns true if the builtin is known to the compiler
+(i.e. it's available via one of the targets), but makes no promises whether 
it's available on the current target.
+The compiler can parse it, but not necessarily generate code for it.
+
+``__has_target_builtin`` returns true if the builtin can actually be generated 
for the current target.
+
 It can be used like this:
 
 .. code-block:: c++

>From 7781516792588feeb54f114f5fbc91312f9ff924 Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Mon, 10 Feb 2025 12:43:25 -0800
Subject: [PATCH 5/9] space

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/docs/LanguageExtensions.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 541a1ca0192d2..aa6bf488f34e9 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -122,6 +122,7 @@ The compiler can parse it, but not necessarily generate 
code for it.
 It can be used like this:
 
 .. code-block:: c++
+
   #ifdef __CUDA__
   #if __has_target_builtin(__builtin_trap)
     __builtin_trap();

>From 5d84bc5f5b10b14b333d831774f65ce02316c958 Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Mon, 10 Feb 2025 12:45:18 -0800
Subject: [PATCH 6/9] spacing again

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/docs/LanguageExtensions.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index aa6bf488f34e9..7c0592d576f15 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -127,11 +127,11 @@ It can be used like this:
   #if __has_target_builtin(__builtin_trap)
     __builtin_trap();
   #else
-      abort();
+    abort();
   #endif
   #else // !CUDA
   #if __has_builtin(__builtin_trap)
-  __builtin_trap();
+    __builtin_trap();
   #else
     abort();
   #endif

>From 7e2dc73ba39bba27d39973de47af2f641c9cf42d Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Mon, 10 Feb 2025 14:00:40 -0800
Subject: [PATCH 7/9] missed endif

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/docs/LanguageExtensions.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 7c0592d576f15..8c642c818ee65 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -135,6 +135,7 @@ It can be used like this:
   #else
     abort();
   #endif
+  #endif
   ...
 
 .. note::

>From 2668404f9a46155a897030aca29e117f4319f9a5 Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Tue, 11 Feb 2025 07:02:49 -0800
Subject: [PATCH 8/9] make macro defined on all targets, address aarons
 feedback

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/docs/LanguageExtensions.rst             |  5 +---
 clang/docs/ReleaseNotes.rst                   |  2 +-
 clang/lib/Lex/PPMacroExpansion.cpp            |  9 ++-----
 .../test/Preprocessor/has_target_builtin.cpp  | 25 ++++++++-----------
 4 files changed, 15 insertions(+), 26 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 8c642c818ee65..96e7df210db48 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -69,8 +69,7 @@ It can be used like this:
 
   When using device offloading, a builtin is considered available if it is
   available on either the host or the device targets.
-  Use ``__has_target_builtin`` to consider only the current target for an
-  offloading target.
+  Use ``__has_target_builtin`` to consider only the current target.
 
 ``__has_constexpr_builtin``
 ---------------------------
@@ -142,8 +141,6 @@ It can be used like this:
   ``__has_target_builtin`` should not be used to detect support for a builtin 
macro;
   use ``#ifdef`` instead.
 
-  ``__has_target_builtin`` is only defined for offloading targets.
-
 .. _langext-__has_feature-__has_extension:
 
 ``__has_feature`` and ``__has_extension``
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 468c34266f2da..d588c3727997e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -108,7 +108,7 @@ New Compiler Builtins
 ---------------------
 
 - The new ``__has_target_builtin`` macro can be used to check if a builtin is 
available
-  on the current offloading target.
+  on the current target.
 
 Deprecated Compiler Flags
 -------------------------
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp 
b/clang/lib/Lex/PPMacroExpansion.cpp
index 48b4c6acb96e1..8be4d06c4887d 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -357,12 +357,7 @@ void Preprocessor::RegisterBuiltinMacros() {
   Ident__has_builtin = RegisterBuiltinMacro("__has_builtin");
   Ident__has_constexpr_builtin =
       RegisterBuiltinMacro("__has_constexpr_builtin");
-  if (getLangOpts().OpenMPIsTargetDevice || getLangOpts().CUDAIsDevice ||
-      getLangOpts().SYCLIsDevice)
-    Ident__has_target_builtin = RegisterBuiltinMacro("__has_target_builtin");
-  else
-    Ident__has_target_builtin = nullptr;
-
+  Ident__has_target_builtin = RegisterBuiltinMacro("__has_target_builtin");
   Ident__has_attribute = RegisterBuiltinMacro("__has_attribute");
   if (!getLangOpts().CPlusPlus)
     Ident__has_c_attribute = RegisterBuiltinMacro("__has_c_attribute");
@@ -1812,7 +1807,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
               Tok, *this, diag::err_feature_check_malformed);
           if (!II)
             return false;
-          auto BuiltinID = II->getBuiltinID();
+          unsigned BuiltinID = II->getBuiltinID();
           if (BuiltinID != 0) {
             switch (BuiltinID) {
             case Builtin::BI__builtin_cpu_is:
diff --git a/clang/test/Preprocessor/has_target_builtin.cpp 
b/clang/test/Preprocessor/has_target_builtin.cpp
index e7f28a049af3b..f11f7ae0e28c0 100644
--- a/clang/test/Preprocessor/has_target_builtin.cpp
+++ b/clang/test/Preprocessor/has_target_builtin.cpp
@@ -1,27 +1,24 @@
 // RUN: %clang_cc1 -fopenmp -triple=spirv64 -fopenmp-is-target-device \
-// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not="{{BAD|DOESNT}}" %s
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=HAS %s
 
 // RUN: %clang_cc1 -fopenmp -triple=nvptx64 -fopenmp-is-target-device \
-// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not="{{BAD|DOESNT}}" %s
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=HAS %s
 
 // RUN: %clang_cc1 -fopenmp -triple=amdgcn-amd-amdhsa 
-fopenmp-is-target-device \
-// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not="{{BAD|DOESNT}}" %s
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=HAS %s
 
 // RUN: %clang_cc1 -fopenmp -triple=aarch64 -fopenmp-is-target-device \
-// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not="{{BAD|DOESNT}}" %s
+// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck 
-implicit-check-not=HAS %s
 
-// RUN: %clang_cc1 -triple=aarch64 -E %s | FileCheck 
-check-prefix=CHECK-NOTOFFLOAD -implicit-check-not="{{GOOD|HAS|BAD}}" %s
+// RUN: %clang_cc1 -triple=aarch64 -E %s | FileCheck -implicit-check-not=HAS %s
 
-// CHECK: GOOD
+// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -E %s | \
+// RUN: FileCheck -check-prefix=CHECK-NO-OFFLOAD-HAS-BUILTIN 
-implicit-check-not=DOESNT %s
 
-// CHECK-NOTOFFLOAD: DOESNT
-#ifdef __has_target_builtin
-  HAS
+// CHECK: DOESNT
+// CHECK-NO-OFFLOAD-HAS-BUILTIN: HAS
 #if __has_target_builtin(__builtin_ia32_pause)
-  BAD
+ HAS
 #else
-  GOOD
-#endif
-#else
-  DOESNT
+ DOESNT
 #endif

>From 71433893b44a6d8eae019522c84b7f717c4c575a Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Wed, 12 Feb 2025 11:19:15 -0800
Subject: [PATCH 9/9] improve example

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/docs/LanguageExtensions.rst | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 96e7df210db48..be767af694519 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -118,24 +118,32 @@ The compiler can parse it, but not necessarily generate 
code for it.
 
 ``__has_target_builtin`` returns true if the builtin can actually be generated 
for the current target.
 
-It can be used like this:
+As a motivating example, let's try to guard a builtin call using 
``__has_builtin`` in a heterogeneous compilation,
+such as OpenMP Offloading, with the host being x86-64 and the offloading 
device being AMDGPU.
 
 .. code-block:: c++
 
-  #ifdef __CUDA__
-  #if __has_target_builtin(__builtin_trap)
-    __builtin_trap();
+  #if __has_builtin(__builtin_ia32_pause)
+     __builtin_ia32_pause();
   #else
     abort();
   #endif
-  #else // !CUDA
-  #if __has_builtin(__builtin_trap)
-    __builtin_trap();
+
+Compilation of this code results in a compiler error because 
``__builtin_ia32_pause`` is known to the compiler because
+it is a builtin supported by the host x86-64 compilation so ``__has_builtin`` 
returns true. However, code cannot
+be generated for ``__builtin_ia32_pause`` during the offload AMDGPU 
compilation as it is not supported on that target.
+
+To guard uses of builtins in heterogeneous compilations such as this,
+``__has_target_builtin`` can be used as per the below example to verify code 
can be generated
+for the referenced builtin on the current target being compiled.
+
+.. code-block:: c++
+
+  #if __has_target_builtin(__builtin_ia32_pause)
+     __builtin_ia32_pause();
   #else
     abort();
   #endif
-  #endif
-  ...
 
 .. note::
   ``__has_target_builtin`` should not be used to detect support for a builtin 
macro;

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to