https://gcc.gnu.org/g:4e05c2ca43252e52a265d38c89b0f01abaeea6bd

commit r17-643-g4e05c2ca43252e52a265d38c89b0f01abaeea6bd
Author: Christoph Müllner <[email protected]>
Date:   Mon May 18 13:42:33 2026 +0200

    RISC-V: Add intrinsic detection macros
    
    RISC-V C API pull request #183 specifies macros that let users
    detect compiler support for intrinsic APIs independent of -march:
    https://github.com/riscv-non-isa/riscv-c-api-doc/pull/183
    
    Define __riscv_intrinsic_<extension> macros in the corresponding
    RISC-V intrinsic headers.  The macros describe compiler support for
    an intrinsic API and do not depend on whether the related ISA
    extension is enabled by -march.
    
    Derive scalar composite macros from their component macros so they
    are only defined when all component intrinsic headers have been
    included.
    
    gcc/
            * config/riscv/andes_vector.h: Define intrinsic detection macros.
            * config/riscv/riscv_bitmanip.h: Likewise.
            * config/riscv/riscv_crypto.h: Likewise.
            * config/riscv/riscv_vector.h: Likewise.
            * config/riscv/sifive_vector.h: Likewise.
            * doc/extend.texi: Document RISC-V intrinsic detection macros.
    
    gcc/testsuite/
            * gcc.target/riscv/intrinsic-detection-bitmanip.c: New test.
            * gcc.target/riscv/intrinsic-detection-crypto.c: New test.
            * gcc.target/riscv/intrinsic-detection-scalar-reverse.c: New test.
            * gcc.target/riscv/intrinsic-detection-scalar.c: New test.
            * gcc.target/riscv/rvv/base/intrinsic-detection.c: New test.
    
    Signed-off-by: Christoph Müllner <[email protected]>

Diff:
---
 gcc/config/riscv/andes_vector.h                    |  5 ++
 gcc/config/riscv/riscv_bitmanip.h                  | 27 ++++++-
 gcc/config/riscv/riscv_crypto.h                    | 25 ++++++
 gcc/config/riscv/riscv_vector.h                    | 48 ++++++++++++
 gcc/config/riscv/sifive_vector.h                   |  5 ++
 gcc/doc/extend.texi                                | 10 +++
 .../riscv/intrinsic-detection-bitmanip.c           | 30 +++++++
 .../gcc.target/riscv/intrinsic-detection-crypto.c  | 30 +++++++
 .../riscv/intrinsic-detection-scalar-reverse.c     | 13 ++++
 .../gcc.target/riscv/intrinsic-detection-scalar.c  | 44 +++++++++++
 .../riscv/rvv/base/intrinsic-detection.c           | 91 ++++++++++++++++++++++
 11 files changed, 327 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/andes_vector.h b/gcc/config/riscv/andes_vector.h
index 712ca77c27ca..94355aec2716 100644
--- a/gcc/config/riscv/andes_vector.h
+++ b/gcc/config/riscv/andes_vector.h
@@ -25,6 +25,11 @@
 #ifndef __ANDES_VECTOR_H
 #define __ANDES_VECTOR_H
 
+#define __riscv_intrinsic_xandesvbfhcvt 1
+#define __riscv_intrinsic_xandesvdot 1
+#define __riscv_intrinsic_xandesvpackfph 1
+#define __riscv_intrinsic_xandesvsintload 1
+
 /* TODO: This should have a separate pragma to include only the Andes
         vector intrinsics.  For now, we are including riscv_vector.h.  */
 #include <riscv_vector.h>
diff --git a/gcc/config/riscv/riscv_bitmanip.h 
b/gcc/config/riscv/riscv_bitmanip.h
index ea0eb4fd6af6..3cc9b7034d54 100644
--- a/gcc/config/riscv/riscv_bitmanip.h
+++ b/gcc/config/riscv/riscv_bitmanip.h
@@ -27,6 +27,31 @@
 
 #include <stdint.h>
 
+#define __riscv_intrinsic_zbb 1
+#define __riscv_intrinsic_zbc 1
+#define __riscv_intrinsic_zbkb 1
+#define __riscv_intrinsic_zbkc 1
+#define __riscv_intrinsic_zbkx 1
+
+#if !defined (__riscv_intrinsic_zkn) \
+    && defined (__riscv_intrinsic_zbkb) \
+    && defined (__riscv_intrinsic_zbkc) \
+    && defined (__riscv_intrinsic_zbkx) \
+    && defined (__riscv_intrinsic_zknd) \
+    && defined (__riscv_intrinsic_zkne) \
+    && defined (__riscv_intrinsic_zknh)
+#define __riscv_intrinsic_zkn 1
+#endif
+
+#if !defined (__riscv_intrinsic_zks) \
+    && defined (__riscv_intrinsic_zbkb) \
+    && defined (__riscv_intrinsic_zbkc) \
+    && defined (__riscv_intrinsic_zbkx) \
+    && defined (__riscv_intrinsic_zksed) \
+    && defined (__riscv_intrinsic_zksh)
+#define __riscv_intrinsic_zks 1
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -294,4 +319,4 @@ __riscv_xperm8_64 (uint64_t rs1, uint64_t rs2)
 #if defined (__cplusplus)
 }
 #endif // __cplusplus
-#endif // __RISCV_BITMANIP_H
\ No newline at end of file
+#endif // __RISCV_BITMANIP_H
diff --git a/gcc/config/riscv/riscv_crypto.h b/gcc/config/riscv/riscv_crypto.h
index 2f3f431ce295..23141286ff36 100644
--- a/gcc/config/riscv/riscv_crypto.h
+++ b/gcc/config/riscv/riscv_crypto.h
@@ -27,6 +27,31 @@
 
 #include <stdint.h>
 
+#define __riscv_intrinsic_zknd 1
+#define __riscv_intrinsic_zkne 1
+#define __riscv_intrinsic_zknh 1
+#define __riscv_intrinsic_zksed 1
+#define __riscv_intrinsic_zksh 1
+
+#if !defined (__riscv_intrinsic_zkn) \
+    && defined (__riscv_intrinsic_zbkb) \
+    && defined (__riscv_intrinsic_zbkc) \
+    && defined (__riscv_intrinsic_zbkx) \
+    && defined (__riscv_intrinsic_zknd) \
+    && defined (__riscv_intrinsic_zkne) \
+    && defined (__riscv_intrinsic_zknh)
+#define __riscv_intrinsic_zkn 1
+#endif
+
+#if !defined (__riscv_intrinsic_zks) \
+    && defined (__riscv_intrinsic_zbkb) \
+    && defined (__riscv_intrinsic_zbkc) \
+    && defined (__riscv_intrinsic_zbkx) \
+    && defined (__riscv_intrinsic_zksed) \
+    && defined (__riscv_intrinsic_zksh)
+#define __riscv_intrinsic_zks 1
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/gcc/config/riscv/riscv_vector.h b/gcc/config/riscv/riscv_vector.h
index 4128c75de86f..bda75833ef2e 100644
--- a/gcc/config/riscv/riscv_vector.h
+++ b/gcc/config/riscv/riscv_vector.h
@@ -28,6 +28,54 @@
 #include <stdint.h>
 #include <stddef.h>
 
+#define __riscv_intrinsic_v 1
+#define __riscv_intrinsic_zve32f 1
+#define __riscv_intrinsic_zve32x 1
+#define __riscv_intrinsic_zve64d 1
+#define __riscv_intrinsic_zve64f 1
+#define __riscv_intrinsic_zve64x 1
+#define __riscv_intrinsic_zvbb 1
+#define __riscv_intrinsic_zvbc 1
+#define __riscv_intrinsic_zvfbfmin 1
+#define __riscv_intrinsic_zvfbfwma 1
+#define __riscv_intrinsic_zvfh 1
+#define __riscv_intrinsic_zvfhmin 1
+#define __riscv_intrinsic_zvkb 1
+#define __riscv_intrinsic_zvkg 1
+#define __riscv_intrinsic_zvkned 1
+#define __riscv_intrinsic_zvknha 1
+#define __riscv_intrinsic_zvknhb 1
+#define __riscv_intrinsic_zvksed 1
+#define __riscv_intrinsic_zvksh 1
+
+#if defined (__riscv_intrinsic_zvkned) \
+    && defined (__riscv_intrinsic_zvknhb) \
+    && defined (__riscv_intrinsic_zvkb)
+#define __riscv_intrinsic_zvkn 1
+#endif
+
+#if defined (__riscv_intrinsic_zvkn) && defined (__riscv_intrinsic_zvbc)
+#define __riscv_intrinsic_zvknc 1
+#endif
+
+#if defined (__riscv_intrinsic_zvkn) && defined (__riscv_intrinsic_zvkg)
+#define __riscv_intrinsic_zvkng 1
+#endif
+
+#if defined (__riscv_intrinsic_zvksed) \
+    && defined (__riscv_intrinsic_zvksh) \
+    && defined (__riscv_intrinsic_zvkb)
+#define __riscv_intrinsic_zvks 1
+#endif
+
+#if defined (__riscv_intrinsic_zvks) && defined (__riscv_intrinsic_zvbc)
+#define __riscv_intrinsic_zvksc 1
+#endif
+
+#if defined (__riscv_intrinsic_zvks) && defined (__riscv_intrinsic_zvkg)
+#define __riscv_intrinsic_zvksg 1
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/gcc/config/riscv/sifive_vector.h b/gcc/config/riscv/sifive_vector.h
index cb4182415433..841e7c8a64a9 100644
--- a/gcc/config/riscv/sifive_vector.h
+++ b/gcc/config/riscv/sifive_vector.h
@@ -25,6 +25,11 @@
 #ifndef __SIFIVE_VECTOR_H
 #define __SIFIVE_VECTOR_H
 
+#define __riscv_intrinsic_xsfvcp 1
+#define __riscv_intrinsic_xsfvfnrclipxfqf 1
+#define __riscv_intrinsic_xsfvqmaccdod 1
+#define __riscv_intrinsic_xsfvqmaccqoq 1
+
 /* TODO: This should have a separate pragma to include only the SiFive
          vector intrinsics. For now, we are including riscv_vector.h. */
 #include <riscv_vector.h>
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index be04402e0939..e14d033267dd 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -27193,6 +27193,16 @@ of @var{bitval} is taken into account.
 These built-in functions are available for the RISC-V family of
 processors.
 
+RISC-V intrinsic headers define macros of the form
+@code{__riscv_intrinsic_@var{extension}} with the value @code{1} when
+GCC supports intrinsics for @var{extension}.  These macros indicate
+compiler support for the intrinsic API and are independent of whether the
+corresponding ISA extension is enabled for the current compilation unit.
+Include @file{riscv_bitmanip.h} for scalar bit-manipulation intrinsics,
+@file{riscv_crypto.h} for scalar cryptography intrinsics,
+@file{riscv_vector.h} for vector intrinsics, and vendor intrinsic
+headers for vendor intrinsic extensions.
+
 @defbuiltin{{void *} __builtin_thread_pointer (void)}
 Returns the value that is currently set in the @samp{tp} register.
 @enddefbuiltin
diff --git a/gcc/testsuite/gcc.target/riscv/intrinsic-detection-bitmanip.c 
b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-bitmanip.c
new file mode 100644
index 000000000000..826163977dea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-bitmanip.c
@@ -0,0 +1,30 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_bitmanip.h>
+
+#if defined (__riscv_zbb) || defined (__riscv_zbc) \
+    || defined (__riscv_zbkb) || defined (__riscv_zbkc) \
+    || defined (__riscv_zbkx)
+#error "unexpected scalar bitmanip ISA extension macro"
+#endif
+
+#if !defined (__riscv_intrinsic_zbb) \
+    || !defined (__riscv_intrinsic_zbc) \
+    || !defined (__riscv_intrinsic_zbkb) \
+    || !defined (__riscv_intrinsic_zbkc) \
+    || !defined (__riscv_intrinsic_zbkx)
+#error "missing scalar bitmanip intrinsic detection macro"
+#endif
+
+#if defined (__riscv_intrinsic_zkn) || defined (__riscv_intrinsic_zks)
+#error "unexpected scalar crypto composite intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_zbb != 1 \
+    || __riscv_intrinsic_zbc != 1 \
+    || __riscv_intrinsic_zbkb != 1 \
+    || __riscv_intrinsic_zbkc != 1 \
+    || __riscv_intrinsic_zbkx != 1
+#error "bad scalar bitmanip intrinsic detection macro value"
+#endif
diff --git a/gcc/testsuite/gcc.target/riscv/intrinsic-detection-crypto.c 
b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-crypto.c
new file mode 100644
index 000000000000..726f0d6327dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-crypto.c
@@ -0,0 +1,30 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_crypto.h>
+
+#if defined (__riscv_zkne) || defined (__riscv_zknd) \
+    || defined (__riscv_zknh) || defined (__riscv_zksed) \
+    || defined (__riscv_zksh)
+#error "unexpected scalar crypto ISA extension macro"
+#endif
+
+#if !defined (__riscv_intrinsic_zknd) \
+    || !defined (__riscv_intrinsic_zkne) \
+    || !defined (__riscv_intrinsic_zknh) \
+    || !defined (__riscv_intrinsic_zksed) \
+    || !defined (__riscv_intrinsic_zksh)
+#error "missing scalar crypto intrinsic detection macro"
+#endif
+
+#if defined (__riscv_intrinsic_zkn) || defined (__riscv_intrinsic_zks)
+#error "unexpected scalar crypto composite intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_zknd != 1 \
+    || __riscv_intrinsic_zkne != 1 \
+    || __riscv_intrinsic_zknh != 1 \
+    || __riscv_intrinsic_zksed != 1 \
+    || __riscv_intrinsic_zksh != 1
+#error "bad scalar crypto intrinsic detection macro value"
+#endif
diff --git 
a/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar-reverse.c 
b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar-reverse.c
new file mode 100644
index 000000000000..5bc6bbd6e236
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar-reverse.c
@@ -0,0 +1,13 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_crypto.h>
+#include <riscv_bitmanip.h>
+
+#if !defined (__riscv_intrinsic_zkn) || !defined (__riscv_intrinsic_zks)
+#error "missing scalar composite intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_zkn != 1 || __riscv_intrinsic_zks != 1
+#error "bad scalar composite intrinsic detection macro value"
+#endif
diff --git a/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar.c 
b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar.c
new file mode 100644
index 000000000000..f60a76afa650
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar.c
@@ -0,0 +1,44 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_bitmanip.h>
+#include <riscv_crypto.h>
+
+#if defined (__riscv_zbb) || defined (__riscv_zbc) \
+    || defined (__riscv_zbkb) || defined (__riscv_zbkc) \
+    || defined (__riscv_zbkx) || defined (__riscv_zkne) \
+    || defined (__riscv_zknd) || defined (__riscv_zknh) \
+    || defined (__riscv_zkn) || defined (__riscv_zks) \
+    || defined (__riscv_zksed) || defined (__riscv_zksh)
+#error "unexpected scalar ISA extension macro"
+#endif
+
+#if !defined (__riscv_intrinsic_zbb) \
+    || !defined (__riscv_intrinsic_zbc) \
+    || !defined (__riscv_intrinsic_zbkb) \
+    || !defined (__riscv_intrinsic_zbkc) \
+    || !defined (__riscv_intrinsic_zbkx) \
+    || !defined (__riscv_intrinsic_zkn) \
+    || !defined (__riscv_intrinsic_zknd) \
+    || !defined (__riscv_intrinsic_zkne) \
+    || !defined (__riscv_intrinsic_zknh) \
+    || !defined (__riscv_intrinsic_zks) \
+    || !defined (__riscv_intrinsic_zksed) \
+    || !defined (__riscv_intrinsic_zksh)
+#error "missing scalar intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_zbb != 1 \
+    || __riscv_intrinsic_zbc != 1 \
+    || __riscv_intrinsic_zbkb != 1 \
+    || __riscv_intrinsic_zbkc != 1 \
+    || __riscv_intrinsic_zbkx != 1 \
+    || __riscv_intrinsic_zkn != 1 \
+    || __riscv_intrinsic_zknd != 1 \
+    || __riscv_intrinsic_zkne != 1 \
+    || __riscv_intrinsic_zknh != 1 \
+    || __riscv_intrinsic_zks != 1 \
+    || __riscv_intrinsic_zksed != 1 \
+    || __riscv_intrinsic_zksh != 1
+#error "bad scalar intrinsic detection macro value"
+#endif
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c
new file mode 100644
index 000000000000..d11cd26afa38
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c
@@ -0,0 +1,91 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_vector.h>
+#include <sifive_vector.h>
+#include <andes_vector.h>
+
+#if defined (__riscv_vector) || defined (__riscv_zvbb) \
+    || defined (__riscv_zve32f) || defined (__riscv_zve32x) \
+    || defined (__riscv_zve64d) || defined (__riscv_zve64f) \
+    || defined (__riscv_zve64x) \
+    || defined (__riscv_zvbc) || defined (__riscv_zvfbfmin) \
+    || defined (__riscv_zvfbfwma) || defined (__riscv_zvfh) \
+    || defined (__riscv_zvfhmin) || defined (__riscv_zvkb) \
+    || defined (__riscv_zvkg) || defined (__riscv_zvkned) \
+    || defined (__riscv_zvknha) || defined (__riscv_zvknhb) \
+    || defined (__riscv_zvksed) || defined (__riscv_zvksh)
+#error "unexpected vector ISA extension macro"
+#endif
+
+#if !defined (__riscv_intrinsic_v) \
+    || !defined (__riscv_intrinsic_zve32f) \
+    || !defined (__riscv_intrinsic_zve32x) \
+    || !defined (__riscv_intrinsic_zve64d) \
+    || !defined (__riscv_intrinsic_zve64f) \
+    || !defined (__riscv_intrinsic_zve64x) \
+    || !defined (__riscv_intrinsic_zvbb) \
+    || !defined (__riscv_intrinsic_zvbc) \
+    || !defined (__riscv_intrinsic_zvfbfmin) \
+    || !defined (__riscv_intrinsic_zvfbfwma) \
+    || !defined (__riscv_intrinsic_zvfh) \
+    || !defined (__riscv_intrinsic_zvfhmin) \
+    || !defined (__riscv_intrinsic_zvkb) \
+    || !defined (__riscv_intrinsic_zvkg) \
+    || !defined (__riscv_intrinsic_zvkn) \
+    || !defined (__riscv_intrinsic_zvknc) \
+    || !defined (__riscv_intrinsic_zvkned) \
+    || !defined (__riscv_intrinsic_zvkng) \
+    || !defined (__riscv_intrinsic_zvknha) \
+    || !defined (__riscv_intrinsic_zvknhb) \
+    || !defined (__riscv_intrinsic_zvks) \
+    || !defined (__riscv_intrinsic_zvksc) \
+    || !defined (__riscv_intrinsic_zvksed) \
+    || !defined (__riscv_intrinsic_zvksg) \
+    || !defined (__riscv_intrinsic_zvksh) \
+    || !defined (__riscv_intrinsic_xsfvcp) \
+    || !defined (__riscv_intrinsic_xsfvfnrclipxfqf) \
+    || !defined (__riscv_intrinsic_xsfvqmaccdod) \
+    || !defined (__riscv_intrinsic_xsfvqmaccqoq) \
+    || !defined (__riscv_intrinsic_xandesvbfhcvt) \
+    || !defined (__riscv_intrinsic_xandesvdot) \
+    || !defined (__riscv_intrinsic_xandesvpackfph) \
+    || !defined (__riscv_intrinsic_xandesvsintload)
+#error "missing vector intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_v != 1 \
+    || __riscv_intrinsic_zve32f != 1 \
+    || __riscv_intrinsic_zve32x != 1 \
+    || __riscv_intrinsic_zve64d != 1 \
+    || __riscv_intrinsic_zve64f != 1 \
+    || __riscv_intrinsic_zve64x != 1 \
+    || __riscv_intrinsic_zvbb != 1 \
+    || __riscv_intrinsic_zvbc != 1 \
+    || __riscv_intrinsic_zvfbfmin != 1 \
+    || __riscv_intrinsic_zvfbfwma != 1 \
+    || __riscv_intrinsic_zvfh != 1 \
+    || __riscv_intrinsic_zvfhmin != 1 \
+    || __riscv_intrinsic_zvkb != 1 \
+    || __riscv_intrinsic_zvkg != 1 \
+    || __riscv_intrinsic_zvkn != 1 \
+    || __riscv_intrinsic_zvknc != 1 \
+    || __riscv_intrinsic_zvkned != 1 \
+    || __riscv_intrinsic_zvkng != 1 \
+    || __riscv_intrinsic_zvknha != 1 \
+    || __riscv_intrinsic_zvknhb != 1 \
+    || __riscv_intrinsic_zvks != 1 \
+    || __riscv_intrinsic_zvksc != 1 \
+    || __riscv_intrinsic_zvksed != 1 \
+    || __riscv_intrinsic_zvksg != 1 \
+    || __riscv_intrinsic_zvksh != 1 \
+    || __riscv_intrinsic_xsfvcp != 1 \
+    || __riscv_intrinsic_xsfvfnrclipxfqf != 1 \
+    || __riscv_intrinsic_xsfvqmaccdod != 1 \
+    || __riscv_intrinsic_xsfvqmaccqoq != 1 \
+    || __riscv_intrinsic_xandesvbfhcvt != 1 \
+    || __riscv_intrinsic_xandesvdot != 1 \
+    || __riscv_intrinsic_xandesvpackfph != 1 \
+    || __riscv_intrinsic_xandesvsintload != 1
+#error "bad vector intrinsic detection macro value"
+#endif

Reply via email to