-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][x86] Add constexpr support for all remaining BMI1 intrinsics #110581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-backend-x86 Author: Simon Pilgrim (RKSimon) ChangesBEXTR/TZCNT are already handled, so we just need to tag the rest of the intrinsics, which are all expanded to generic patterns. Full diff: https://github.com/llvm/llvm-project/pull/110581.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 02dfbfaaea2071..5a3b19e866d6f9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -511,12 +511,13 @@ X86 Support
* Supported MINMAX intrinsics of ``*_(mask(z)))_minmax(ne)_p[s|d|h|bh]`` and
``*_(mask(z)))_minmax_s[s|d|h]``.
-- The following bit manipulation intrinsics can now be used in constant expressions:
- all lzcnt intrinsics in lzcntintrin.h
- all bextr intrinsics in bmiintrin.h
- all tzcnt intrinsics in bmiintrin.h
- all bzhi intrinsics in bmi2intrin.h
- all intrinsics in tbmintrin.h
+- All intrinsics in lzcntintrin.h can now be used in constant expressions.
+
+- All intrinsics in bmiintrin.h can now be used in constant expressions.
+
+- All bzhi intrinsics in bmi2intrin.h can now be used in constant expressions.
+
+- All intrinsics in tbmintrin.h can now be used in constant expressions.
Arm and AArch64 Support
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Headers/bmiintrin.h b/clang/lib/Headers/bmiintrin.h
index bf12a22d0f9904..c7ce96096d9714 100644
--- a/clang/lib/Headers/bmiintrin.h
+++ b/clang/lib/Headers/bmiintrin.h
@@ -169,12 +169,13 @@ _mm_tzcnt_64(unsigned long long __X)
#if !defined(__SCE__) || __has_feature(modules) || defined(__BMI__)
/* Define the default attributes for the functions in this file. */
-#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("bmi")))
-
#if defined(__cplusplus) && (__cplusplus >= 201103L)
-#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr
+#define __DEFAULT_FN_ATTRS \
+ __attribute__((__always_inline__, __nodebug__, __target__("bmi"))) constexpr
+constexpr
#else
-#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
+#define __DEFAULT_FN_ATTRS \
+ __attribute__((__always_inline__, __nodebug__, __target__("bmi")))
#endif
/// Performs a bitwise AND of the second operand with the one's
@@ -234,7 +235,7 @@ __andn_u32(unsigned int __X, unsigned int __Y)
/// \returns An unsigned integer whose least significant bits contain the
/// extracted bits.
/// \see _bextr_u32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ unsigned int __DEFAULT_FN_ATTRS
__bextr_u32(unsigned int __X, unsigned int __Y) {
return __builtin_ia32_bextr_u32(__X, __Y);
}
@@ -258,7 +259,7 @@ __bextr_u32(unsigned int __X, unsigned int __Y) {
/// \returns An unsigned integer whose least significant bits contain the
/// extracted bits.
/// \see __bextr_u32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ unsigned int __DEFAULT_FN_ATTRS
_bextr_u32(unsigned int __X, unsigned int __Y, unsigned int __Z) {
return __builtin_ia32_bextr_u32(__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
}
@@ -280,7 +281,7 @@ _bextr_u32(unsigned int __X, unsigned int __Y, unsigned int __Z) {
/// \returns An unsigned integer whose least significant bits contain the
/// extracted bits.
/// \see __bextr_u32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ unsigned int __DEFAULT_FN_ATTRS
_bextr2_u32(unsigned int __X, unsigned int __Y) {
return __builtin_ia32_bextr_u32(__X, __Y);
}
@@ -453,7 +454,7 @@ __andn_u64 (unsigned long long __X, unsigned long long __Y)
/// \returns An unsigned 64-bit integer whose least significant bits contain the
/// extracted bits.
/// \see _bextr_u64
-static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS
__bextr_u64(unsigned long long __X, unsigned long long __Y) {
return __builtin_ia32_bextr_u64(__X, __Y);
}
@@ -477,7 +478,7 @@ __bextr_u64(unsigned long long __X, unsigned long long __Y) {
/// \returns An unsigned 64-bit integer whose least significant bits contain the
/// extracted bits.
/// \see __bextr_u64
-static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS
_bextr_u64(unsigned long long __X, unsigned int __Y, unsigned int __Z) {
return __builtin_ia32_bextr_u64(__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
}
@@ -499,7 +500,7 @@ _bextr_u64(unsigned long long __X, unsigned int __Y, unsigned int __Z) {
/// \returns An unsigned 64-bit integer whose least significant bits contain the
/// extracted bits.
/// \see __bextr_u64
-static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS
_bextr2_u64(unsigned long long __X, unsigned long long __Y) {
return __builtin_ia32_bextr_u64(__X, __Y);
}
@@ -615,7 +616,6 @@ __blsr_u64(unsigned long long __X)
#endif /* __x86_64__ */
#undef __DEFAULT_FN_ATTRS
-#undef __DEFAULT_FN_ATTRS_CONSTEXPR
#endif /* !defined(__SCE__) || __has_feature(modules) || defined(__BMI__) */
diff --git a/clang/test/CodeGen/X86/bmi-builtins.c b/clang/test/CodeGen/X86/bmi-builtins.c
index 6c0b2c440ea081..ded40ca59781e2 100644
--- a/clang/test/CodeGen/X86/bmi-builtins.c
+++ b/clang/test/CodeGen/X86/bmi-builtins.c
@@ -237,6 +237,9 @@ unsigned long long test_blsr_u64(unsigned long long __X) {
// Test constexpr handling.
#if defined(__cplusplus) && (__cplusplus >= 201103L)
+char andnu32[__andn_u32(0x01234567, 0xFECDBA98) == (~0x01234567 & 0xFECDBA98) ? 1 : -1];
+char andn2u32[_andn_u32(0x01234567, 0xFECDBA98) == (~0x01234567 & 0xFECDBA98) ? 1 : -1];
+
char bextr32_0[__bextr_u32(0x00000000, 0x00000000) == 0x00000000 ? 1 : -1];
char bextr32_1[__bextr_u32(0x000003F0, 0xFFFF1004) == 0x0000003F ? 1 : -1];
char bextr32_2[__bextr_u32(0x000003F0, 0xFFFF3008) == 0x00000003 ? 1 : -1];
@@ -249,6 +252,15 @@ char bextr32_6[_bextr_u32(0x00000000, 0x00000000, 0x00000000) == 0x00000000 ? 1
char bextr32_7[_bextr_u32(0x000003F0, 0xFFFFFF04, 0xFFFFFF10) == 0x0000003F ? 1 : -1];
char bextr32_8[_bextr_u32(0x000003F0, 0xFFFFFF08, 0xFFFFFF30) == 0x00000003 ? 1 : -1];
+char blsiu32[__blsi_u32(0x89ABCDEF) == (0x89ABCDEF & -0x89ABCDEF) ? 1 : -1];
+char blsi2u32[_blsi_u32(0x89ABCDEF) == (0x89ABCDEF & -0x89ABCDEF) ? 1 : -1];
+
+char blsmasku32[__blsmsk_u32(0x89ABCDEF) == (0x89ABCDEF ^ (0x89ABCDEF - 1)) ? 1 : -1];
+char blsmask2u32[_blsmsk_u32(0x89ABCDEF) == (0x89ABCDEF ^ (0x89ABCDEF - 1)) ? 1 : -1];
+
+char blsru32[__blsr_u32(0x89ABCDEF) == (0x89ABCDEF & (0x89ABCDEF - 1)) ? 1 : -1];
+char blsr2u32[_blsr_u32(0x89ABCDEF) == (0x89ABCDEF & (0x89ABCDEF - 1)) ? 1 : -1];
+
char tzcntu16_0[__tzcnt_u16(0x0000) == 16 ? 1 : -1];
char tzcntu16_1[__tzcnt_u16(0x0001) == 0 ? 1 : -1];
char tzcntu16_2[__tzcnt_u16(0x0010) == 4 ? 1 : -1];
@@ -270,6 +282,9 @@ char tzcnt3u32_1[_mm_tzcnt_32(0x00000001) == 0 ? 1 : -1];
char tzcnt3u32_2[_mm_tzcnt_32(0x00000080) == 7 ? 1 : -1];
#ifdef __x86_64__
+char andnu64[__andn_u64(0x0123456789ABCDEFULL, 0xFECDBA9876543210ULL) == (~0x0123456789ABCDEFULL & 0xFECDBA9876543210ULL) ? 1 : -1];
+char andn2u64[_andn_u64(0x0123456789ABCDEFULL, 0xFECDBA9876543210ULL) == (~0x0123456789ABCDEFULL & 0xFECDBA9876543210ULL) ? 1 : -1];
+
char bextr64_0[__bextr_u64(0x0000000000000000ULL, 0x0000000000000000ULL) == 0x0000000000000000ULL ? 1 : -1];
char bextr64_1[__bextr_u64(0xF000000000000001ULL, 0x0000000000004001ULL) == 0x7800000000000000ULL ? 1 : -1];
char bextr64_2[__bextr_u64(0xF000000000000001ULL, 0xFFFFFFFFFFFF1001ULL) == 0x0000000000000000ULL ? 1 : -1];
@@ -282,6 +297,15 @@ char bextr64_6[_bextr_u64(0x0000000000000000ULL, 0x0000000000000000ULL, 0x000000
char bextr64_7[_bextr_u64(0xF000000000000001ULL, 0x0000000000000001ULL, 0x0000000000000040ULL) == 0x7800000000000000ULL ? 1 : -1];
char bextr64_8[_bextr_u64(0xF000000000000001ULL, 0xFFFFFFFFFFFFFF01ULL, 0xFFFFFFFFFFFFFF10ULL) == 0x0000000000000000ULL ? 1 : -1];
+char blsiu64[__blsi_u64(0x0123456789ABCDEFULL) == (0x0123456789ABCDEFULL & -0x0123456789ABCDEFULL) ? 1 : -1];
+char blsi2u64[_blsi_u64(0x0123456789ABCDEFULL) == (0x0123456789ABCDEFULL & -0x0123456789ABCDEFULL) ? 1 : -1];
+
+char blsmasku64[__blsmsk_u64(0x0123456789ABCDEFULL) == (0x0123456789ABCDEFULL ^ (0x0123456789ABCDEFULL - 1)) ? 1 : -1];
+char blsmask2u64[_blsmsk_u64(0x0123456789ABCDEFULL) == (0x0123456789ABCDEFULL ^ (0x0123456789ABCDEFULL - 1)) ? 1 : -1];
+
+char blsru64[__blsr_u64(0x0123456789ABCDEFULL) == (0x0123456789ABCDEFULL & (0x0123456789ABCDEFULL - 1)) ? 1 : -1];
+char blsr2u64[_blsr_u64(0x0123456789ABCDEFULL) == (0x0123456789ABCDEFULL & (0x0123456789ABCDEFULL - 1)) ? 1 : -1];
+
char tzcntu64_0[__tzcnt_u64(0x0000000000000000ULL) == 64 ? 1 : -1];
char tzcntu64_1[__tzcnt_u64(0x0000000000000001ULL) == 0 ? 1 : -1];
char tzcntu64_2[__tzcnt_u64(0x0000000800000000ULL) == 35 ? 1 : -1];
|
You can test this locally with the following command:git-clang-format --diff a5f3a2a8414a16077ca9a5544d30dd44b30b901e ee0079cb053f3f49da80b83237808453cf2669fd --extensions h,c -- clang/lib/Headers/bmiintrin.h clang/test/CodeGen/X86/bmi-builtins.c View the diff from clang-format here.diff --git a/clang/lib/Headers/bmiintrin.h b/clang/lib/Headers/bmiintrin.h
index c7ce96096d..dd4851c303 100644
--- a/clang/lib/Headers/bmiintrin.h
+++ b/clang/lib/Headers/bmiintrin.h
@@ -178,23 +178,22 @@ constexpr
__attribute__((__always_inline__, __nodebug__, __target__("bmi")))
#endif
-/// Performs a bitwise AND of the second operand with the one's
-/// complement of the first operand.
-///
-/// \headerfile <x86intrin.h>
-///
-/// This intrinsic corresponds to the \c ANDN instruction.
-///
-/// \param __X
-/// An unsigned integer containing one of the operands.
-/// \param __Y
-/// An unsigned integer containing one of the operands.
-/// \returns An unsigned integer containing the bitwise AND of the second
-/// operand with the one's complement of the first operand.
-/// \see _andn_u32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS
-__andn_u32(unsigned int __X, unsigned int __Y)
-{
+ /// Performs a bitwise AND of the second operand with the one's
+ /// complement of the first operand.
+ ///
+ /// \headerfile <x86intrin.h>
+ ///
+ /// This intrinsic corresponds to the \c ANDN instruction.
+ ///
+ /// \param __X
+ /// An unsigned integer containing one of the operands.
+ /// \param __Y
+ /// An unsigned integer containing one of the operands.
+ /// \returns An unsigned integer containing the bitwise AND of the second
+ /// operand with the one's complement of the first operand.
+ /// \see _andn_u32
+ static __inline__ unsigned int __DEFAULT_FN_ATTRS
+ __andn_u32(unsigned int __X, unsigned int __Y) {
return ~__X & __Y;
}
@@ -259,8 +258,9 @@ __bextr_u32(unsigned int __X, unsigned int __Y) {
/// \returns An unsigned integer whose least significant bits contain the
/// extracted bits.
/// \see __bextr_u32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS
-_bextr_u32(unsigned int __X, unsigned int __Y, unsigned int __Z) {
+static __inline__ unsigned int __DEFAULT_FN_ATTRS _bextr_u32(unsigned int __X,
+ unsigned int __Y,
+ unsigned int __Z) {
return __builtin_ia32_bextr_u32(__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
}
|
LG but in official headers need to fix fmt. |
6dd2030
to
f9584fb
Compare
…ics support - one entry per header
BEXTR/TZCNT are already handled, so we just need to tag the rest of the intrinsics, which are all expanded to generic patterns.
f9584fb
to
ee0079c
Compare
Thanks, I'll do a clang-format cleanup pass after I've got these constexpr changes done. |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/8350 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/3/builds/5505 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/6842 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/153/builds/10546 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/56/builds/8784 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/60/builds/9056 Here is the relevant piece of the build log for the reference
|
…lvm#110581) BEXTR/TZCNT are already handled, so we just need to tag the rest of the intrinsics, which are all expanded to generic patterns.
BEXTR/TZCNT are already handled, so we just need to tag the rest of the intrinsics, which are all expanded to generic patterns.