================
@@ -96,6 +100,55 @@ 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.
+
+``__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.
+
+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++
+
+  #if __has_builtin(__builtin_ia32_pause)
+     __builtin_ia32_pause();
+  #else
+    abort();
+  #endif
+
+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.
----------------
AaronBallman wrote:

Thank you, this is helping somewhat. But I think a user is still going to ask 
themselves "why does `__has_builtin` return `true` in this case?". The host and 
the offload are separate compilations, so logically, it stands to reason that 
`__has_builtin` would return `true` for the host and `false` for the offload. 
And because of:

> ``__has_builtin`` and ``__has_target_builtin`` behave identically for normal 
> C++ compilations.

They're going to wonder why they wouldn't just replace all uses of 
`__has_builtin` with `__has_target_builtin`, which begs the question of why 
`__has_builtin` isn't just being "fixed".

(I'll be honest, I still don't fully understand the answer to that myself.)

https://github.com/llvm/llvm-project/pull/126324
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to