@@ -4801,12 +4801,8 @@ a functional mechanism for programatically querying:
48014801
48024802.. code-block :: c
48034803
4804- // When used as the predicate for a control structure
4805- bool __builtin_amdgcn_processor_is(const char*);
4806- bool __builtin_amdgcn_is_invocable(builtin_name);
4807- // Otherwise
4808- void __builtin_amdgcn_processor_is(const char*);
4809- void __builtin_amdgcn_is_invocable(void);
4804+ __amdgpu_feature_predicate_t __builtin_amdgcn_processor_is(const char*);
4805+ __amdgpu_feature_predicate_t __builtin_amdgcn_is_invocable(builtin_name);
48104806
48114807 **Example of use **:
48124808
@@ -4825,7 +4821,7 @@ a functional mechanism for programatically querying:
48254821 while (__builtin_amdgcn_processor_is ("gfx1101")) *p += x;
48264822
48274823 do {
4828- * p -= x ;
4824+ break ;
48294825 } while (__builtin_amdgcn_processor_is ("gfx1010"));
48304826
48314827 for (; __builtin_amdgcn_processor_is ("gfx1201"); ++*p) break;
@@ -4836,7 +4832,7 @@ a functional mechanism for programatically querying:
48364832 __builtin_amdgcn_s_ttracedata_imm (1);
48374833
48384834 do {
4839- * p -= x ;
4835+ break ;
48404836 } while (
48414837 __builtin_amdgcn_is_invocable (__builtin_amdgcn_global_load_tr_b64_i32));
48424838
@@ -4845,55 +4841,57 @@ a functional mechanism for programatically querying:
48454841
48464842**Description **:
48474843
4848- When used as the predicate value of the following control structures:
4844+ The builtins return a value of type ``__amdgpu_feature_predicate_t ``, which is a
4845+ target specific type that behaves as if its C++ definition was the following:
48494846
48504847.. code-block :: c++
48514848
4852- if (...)
4853- while (...)
4854- do { } while (...)
4855- for (...)
4849+ struct __amdgpu_feature_predicate_t {
4850+ __amdgpu_feature_predicate_t () = delete;
4851+ __amdgpu_feature_predicate_t (const __amdgpu_feature_predicate_t&) = delete;
4852+ __amdgpu_feature_predicate_t (__amdgpu_feature_predicate_t&&) = delete;
4853+
4854+ explicit
4855+ operator bool () const noexcept;
4856+ };
4857+
4858+ The builtins can be used in C as well, wherein the
4859+ ``__amdgpu_feature_predicate_t `` type behaves as an opaque, forward declared
4860+ type with conditional automated conversion to ``_Bool `` when used as the
4861+ predicate argument to a control structure:
4862+
4863+ .. code-block :: c
4864+
4865+ struct __amdgpu_feature_predicate_t ret(); // Error
4866+ void arg(struct __amdgpu_feature_predicate_t); // Error
4867+ void local() {
4868+ struct __amdgpu_feature_predicate_t x; // Error
4869+ struct __amdgpu_feature_predicate_t y =
4870+ __builtin_amdgcn_processor_is("gfx900"); // Error
4871+ }
4872+ void valid_use() {
4873+ _Bool x = (_Bool)__builtin_amdgcn_processor_is("gfx900"); // OK
4874+ if (__builtin_amdgcn_processor_is("gfx900")) // Implicit cast to _Bool
4875+ return;
4876+ for (; __builtin_amdgcn_processor_is("gfx900");) // Implicit cast to _Bool
4877+ break;
4878+ while (__builtin_amdgcn_processor_is("gfx900")) // Implicit cast to _Bool
4879+ break;
4880+ do {
4881+ break;
4882+ } while (__builtin_amdgcn_processor_is("gfx900")); // Implicit cast to _Bool
4883+
4884+ __builtin_amdgcn_processor_is("gfx900") ? x : !x;
4885+ }
48564886
4857- be it directly, or as arguments to logical operators such as ``!, ||, && ``, the
4858- builtins return a boolean value that:
4887+ The boolean interpretation of the predicate values returned by the builtins:
48594888
48604889* indicates whether the current target matches the argument; the argument MUST
48614890 be a string literal and a valid AMDGPU target
48624891* indicates whether the builtin function passed as the argument can be invoked
48634892 by the current target; the argument MUST be either a generic or AMDGPU
48644893 specific builtin name
48654894
4866- Outside of these contexts, the builtins have a ``void `` returning signature
4867- which prevents their misuse.
4868-
4869- **Example of invalid use **:
4870-
4871- .. code-block :: c++
4872-
4873- void kernel (int* p, int x, bool (*pfn)(bool), const char * str) {
4874- if (__builtin_amdgcn_processor_is ("not_an_amdgcn_gfx_id")) return;
4875- else if (__builtin_amdgcn_processor_is (str)) __builtin_trap ();
4876-
4877- bool a = __builtin_amdgcn_processor_is ("gfx906");
4878- const bool b = !__builtin_amdgcn_processor_is ("gfx906");
4879- const bool c = !__builtin_amdgcn_processor_is ("gfx906");
4880- bool d = __builtin_amdgcn_is_invocable (__builtin_amdgcn_s_sleep_var);
4881- bool e = !__builtin_amdgcn_is_invocable (__builtin_amdgcn_s_sleep_var);
4882- const auto f =
4883- !__builtin_amdgcn_is_invocable (__builtin_amdgcn_s_wait_event_export_ready)
4884- || __builtin_amdgcn_is_invocable (__builtin_amdgcn_s_sleep_var);
4885- const auto g =
4886- !__builtin_amdgcn_is_invocable (__builtin_amdgcn_s_wait_event_export_ready)
4887- || !__builtin_amdgcn_is_invocable (__builtin_amdgcn_s_sleep_var);
4888- __builtin_amdgcn_processor_is ("gfx1201")
4889- ? __builtin_amdgcn_s_sleep_var (x) : __builtin_amdgcn_s_sleep (42);
4890- if (pfn (__builtin_amdgcn_processor_is ("gfx1200")))
4891- __builtin_amdgcn_s_sleep_var (x);
4892-
4893- if (__builtin_amdgcn_is_invocable ("__builtin_amdgcn_s_sleep_var")) return;
4894- else if (__builtin_amdgcn_is_invocable (x)) __builtin_trap ();
4895- }
4896-
48974895When invoked while compiling for a concrete target, the builtins are evaluated
48984896early by Clang, and never produce any CodeGen effects / have no observable
48994897side-effects in IR. Conversely, when compiling for AMDGCN flavoured SPIR-v,
0 commit comments