[clang] [X86] Enable constexpr on LZCNT & BMI intrinsics (PR #94161)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jun 2 07:31:15 PDT 2024
https://github.com/aniplcc created https://github.com/llvm/llvm-project/pull/94161
Closes #86128.
>From ad4c0e737f3d8de3202e027646c05d916a695e30 Mon Sep 17 00:00:00 2001
From: aniplcc <aniplccode at gmail.com>
Date: Sun, 2 Jun 2024 19:47:10 +0530
Subject: [PATCH 1/2] [X86] Enable constexpr on LZCNT & BMI intrinsics
---
clang/lib/Headers/bmiintrin.h | 50 ++++++----
clang/lib/Headers/lzcntintrin.h | 13 ++-
clang/test/CodeGen/X86/bmi-builtins.c | 125 +++++++++++++++++++++++-
clang/test/CodeGen/X86/lzcnt-builtins.c | 37 ++++++-
4 files changed, 198 insertions(+), 27 deletions(-)
diff --git a/clang/lib/Headers/bmiintrin.h b/clang/lib/Headers/bmiintrin.h
index 78bffe68e221a..c5b57a1d1e43c 100644
--- a/clang/lib/Headers/bmiintrin.h
+++ b/clang/lib/Headers/bmiintrin.h
@@ -19,6 +19,11 @@
to use it as a potentially faster version of BSF. */
#define __RELAXED_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
+#if defined (__cplusplus) && (__cplusplus >= 201103L)
+#define __RELAXED_FN_ATTRS_CONSTEXPR __RELAXED_FN_ATTRS constexpr
+#else
+#define __RELAXED_FN_ATTRS_CONSTEXPR __RELAXED_FN_ATTRS
+
/// Counts the number of trailing zero bits in the operand.
///
/// \headerfile <x86intrin.h>
@@ -30,7 +35,7 @@
/// \returns An unsigned 16-bit integer containing the number of trailing zero
/// bits in the operand.
/// \see _tzcnt_u16
-static __inline__ unsigned short __RELAXED_FN_ATTRS
+static __inline__ unsigned short __RELAXED_FN_ATTRS_CONSTEXPR
__tzcnt_u16(unsigned short __X)
{
return __builtin_ia32_tzcnt_u16(__X);
@@ -64,7 +69,7 @@ __tzcnt_u16(unsigned short __X)
/// \returns An unsigned 32-bit integer containing the number of trailing zero
/// bits in the operand.
/// \see { _mm_tzcnt_32 _tzcnt_u32 }
-static __inline__ unsigned int __RELAXED_FN_ATTRS
+static __inline__ unsigned int __RELAXED_FN_ATTRS_CONSTEXPR
__tzcnt_u32(unsigned int __X)
{
return __builtin_ia32_tzcnt_u32(__X);
@@ -81,7 +86,7 @@ __tzcnt_u32(unsigned int __X)
/// \returns A 32-bit integer containing the number of trailing zero bits in
/// the operand.
/// \see { __tzcnt_u32 _tzcnt_u32 }
-static __inline__ int __RELAXED_FN_ATTRS
+static __inline__ int __RELAXED_FN_ATTRS_CONSTEXPR
_mm_tzcnt_32(unsigned int __X)
{
return (int)__builtin_ia32_tzcnt_u32(__X);
@@ -117,7 +122,7 @@ _mm_tzcnt_32(unsigned int __X)
/// \returns An unsigned 64-bit integer containing the number of trailing zero
/// bits in the operand.
/// \see { _mm_tzcnt_64 _tzcnt_u64 }
-static __inline__ unsigned long long __RELAXED_FN_ATTRS
+static __inline__ unsigned long long __RELAXED_FN_ATTRS_CONSTEXPR
__tzcnt_u64(unsigned long long __X)
{
return __builtin_ia32_tzcnt_u64(__X);
@@ -134,7 +139,7 @@ __tzcnt_u64(unsigned long long __X)
/// \returns An 64-bit integer containing the number of trailing zero bits in
/// the operand.
/// \see { __tzcnt_u64 _tzcnt_u64 }
-static __inline__ long long __RELAXED_FN_ATTRS
+static __inline__ long long __RELAXED_FN_ATTRS_CONSTEXPR
_mm_tzcnt_64(unsigned long long __X)
{
return (long long)__builtin_ia32_tzcnt_u64(__X);
@@ -160,12 +165,18 @@ _mm_tzcnt_64(unsigned long long __X)
#endif /* __x86_64__ */
#undef __RELAXED_FN_ATTRS
+#undef __RELAXED_FN_ATTRS_CONSTEXPR
#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
+#else
+#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
+
/// Performs a bitwise AND of the second operand with the one's
/// complement of the first operand.
///
@@ -180,7 +191,7 @@ _mm_tzcnt_64(unsigned long long __X)
/// \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
+static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__andn_u32(unsigned int __X, unsigned int __Y)
{
return ~__X & __Y;
@@ -223,7 +234,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
+static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__bextr_u32(unsigned int __X, unsigned int __Y)
{
return __builtin_ia32_bextr_u32(__X, __Y);
@@ -248,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
+static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
_bextr_u32(unsigned int __X, unsigned int __Y, unsigned int __Z)
{
return __builtin_ia32_bextr_u32 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
@@ -271,7 +282,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
+static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
_bextr2_u32(unsigned int __X, unsigned int __Y) {
return __builtin_ia32_bextr_u32(__X, __Y);
}
@@ -288,7 +299,7 @@ _bextr2_u32(unsigned int __X, unsigned int __Y) {
/// \returns An unsigned integer containing the result of clearing the bits from
/// the source operand.
/// \see _blsi_u32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS
+static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__blsi_u32(unsigned int __X)
{
return __X & -__X;
@@ -324,7 +335,7 @@ __blsi_u32(unsigned int __X)
/// An unsigned integer used to create the mask.
/// \returns An unsigned integer containing the newly created mask.
/// \see _blsmsk_u32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS
+static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__blsmsk_u32(unsigned int __X)
{
return __X ^ (__X - 1);
@@ -360,7 +371,7 @@ __blsmsk_u32(unsigned int __X)
/// \returns An unsigned integer containing the result of clearing the source
/// operand.
/// \see _blsr_u32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS
+static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__blsr_u32(unsigned int __X)
{
return __X & (__X - 1);
@@ -400,7 +411,7 @@ __blsr_u32(unsigned int __X)
/// \returns An unsigned 64-bit integer containing the bitwise AND of the second
/// operand with the one's complement of the first operand.
/// \see _andn_u64
-static __inline__ unsigned long long __DEFAULT_FN_ATTRS
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
__andn_u64 (unsigned long long __X, unsigned long long __Y)
{
return ~__X & __Y;
@@ -444,7 +455,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
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
__bextr_u64(unsigned long long __X, unsigned long long __Y)
{
return __builtin_ia32_bextr_u64(__X, __Y);
@@ -469,7 +480,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
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
_bextr_u64(unsigned long long __X, unsigned int __Y, unsigned int __Z)
{
return __builtin_ia32_bextr_u64 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
@@ -492,7 +503,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
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
_bextr2_u64(unsigned long long __X, unsigned long long __Y) {
return __builtin_ia32_bextr_u64(__X, __Y);
}
@@ -509,7 +520,7 @@ _bextr2_u64(unsigned long long __X, unsigned long long __Y) {
/// \returns An unsigned 64-bit integer containing the result of clearing the
/// bits from the source operand.
/// \see _blsi_u64
-static __inline__ unsigned long long __DEFAULT_FN_ATTRS
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
__blsi_u64(unsigned long long __X)
{
return __X & -__X;
@@ -545,7 +556,7 @@ __blsi_u64(unsigned long long __X)
/// An unsigned 64-bit integer used to create the mask.
/// \returns An unsigned 64-bit integer containing the newly created mask.
/// \see _blsmsk_u64
-static __inline__ unsigned long long __DEFAULT_FN_ATTRS
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
__blsmsk_u64(unsigned long long __X)
{
return __X ^ (__X - 1);
@@ -581,7 +592,7 @@ __blsmsk_u64(unsigned long long __X)
/// \returns An unsigned 64-bit integer containing the result of clearing the
/// source operand.
/// \see _blsr_u64
-static __inline__ unsigned long long __DEFAULT_FN_ATTRS
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
__blsr_u64(unsigned long long __X)
{
return __X & (__X - 1);
@@ -608,6 +619,7 @@ __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/lib/Headers/lzcntintrin.h b/clang/lib/Headers/lzcntintrin.h
index f4ddce9d0e683..190fe66f3d72f 100644
--- a/clang/lib/Headers/lzcntintrin.h
+++ b/clang/lib/Headers/lzcntintrin.h
@@ -17,6 +17,12 @@
/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("lzcnt")))
+#if defined (__cplusplus) && (__cplusplus >= 201103L)
+#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr
+#else
+#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
+#endif
+
#ifndef _MSC_VER
/// Counts the number of leading zero bits in the operand.
///
@@ -42,7 +48,7 @@
/// \returns An unsigned 32-bit integer containing the number of leading zero
/// bits in the operand.
/// \see _lzcnt_u32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS
+static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__lzcnt32(unsigned int __X)
{
return __builtin_ia32_lzcnt_u32(__X);
@@ -59,7 +65,7 @@ __lzcnt32(unsigned int __X)
/// \returns An unsigned 32-bit integer containing the number of leading zero
/// bits in the operand.
/// \see __lzcnt32
-static __inline__ unsigned int __DEFAULT_FN_ATTRS
+static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
_lzcnt_u32(unsigned int __X)
{
return __builtin_ia32_lzcnt_u32(__X);
@@ -92,7 +98,7 @@ _lzcnt_u32(unsigned int __X)
/// \returns An unsigned 64-bit integer containing the number of leading zero
/// bits in the operand.
/// \see __lzcnt64
-static __inline__ unsigned long long __DEFAULT_FN_ATTRS
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
_lzcnt_u64(unsigned long long __X)
{
return __builtin_ia32_lzcnt_u64(__X);
@@ -100,5 +106,6 @@ _lzcnt_u64(unsigned long long __X)
#endif
#undef __DEFAULT_FN_ATTRS
+#undef __DEFAULT_FN_ATTRS_CONSTEXPR
#endif /* __LZCNTINTRIN_H */
diff --git a/clang/test/CodeGen/X86/bmi-builtins.c b/clang/test/CodeGen/X86/bmi-builtins.c
index 81405429b9b6c..a34c346dd6177 100644
--- a/clang/test/CodeGen/X86/bmi-builtins.c
+++ b/clang/test/CodeGen/X86/bmi-builtins.c
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=CHECK,TZCNT
-// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -emit-llvm -o - -Wall -Werror -DTEST_TZCNT | FileCheck %s --check-prefix=TZCNT
-
+// RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=CHECK,TZCNT
+// RUN: %clang_cc1 -x c++ -std=c++11 -std -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=CHECK,TZCNT
+// RUN: %clang_cc1 -x c -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -emit-llvm -o - -Wall -Werror -DTEST_TZCNT | FileCheck %s --check-prefix=TZCNT
+// RUN: %clang_cc1 -x c++ -std=c++11 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -emit-llvm -o - -Wall -Werror -DTEST_TZCNT | FileCheck %s --check-prefix=TZCNT
#include <immintrin.h>
@@ -232,3 +233,121 @@ unsigned long long test_blsr_u64(unsigned long long __X) {
#endif
#endif // !defined(TEST_TZCNT)
+
+// Test constexpr handling.
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+
+char cttz16_0[__tzcnt_u16(0x0000) == 16 ? 1 : -1];
+char cttz16_1[__tzcnt_u16(0x10F0) == 4 ? 1 : -1];
+
+char cttz32_0[__tzcnt_u32(0x0FF00000) == 20 ? 1 : -1];
+char cttz32_1[__tzcnt_u32(0x000000F0) == 4 ? 1 : -1];
+
+char mm_cttz32_0[_mm_tzcnt_u32(0x00030F00) == 8 ? 1 : -1];
+char mm_cttz32_1[_mm_tzcnt_u32(0x01000000) == 24 ? 1 : -1];
+
+//Intel
+char _tzcnt_u16_0[_tzcnt_u16(0x0010) == 4 ? 1 : -1];
+char _tzcnt_u16_1[_tzcnt_u16(0x0100) == 8 ? 1 : -1];
+
+char _tzcnt_u32_0[_tzcnt_u32(0x00110011) == 0 ? 1 : -1;
+char _tzcnt_u32_1[_tzcnt_u32(0x10011000) == 12 ? 1 : -1;
+
+#ifdef __x86_64__
+char mm_cttz64_0[mm_tzcnt_u64(0x0000000000000000ULL) == 0 ? 1 : -1];
+char mm_cttz64_1[mm_tzcnt_u64(0xF000010000000000ULL) == 40 ? 1 : -1];
+
+//Intel
+char __tzcnt_u64_0[__tzcnt_u64(0x0100000000000000ULL) == 56 ? 1 : -1];
+char __tzcnt_u64_1[__tzcnt_u64(0xF000000000000001ULL) == 0 ? 1 : -1];
+#endif //__X86_64__
+
+#if !defined(TEST_TZCNT)
+
+//ANDN
+char andn_u32_0[__andn_u32(0X0FFF0FFF, 0XFFFFFFFF) == 0xF000F000 ? 1 : -1];
+char andn_u32_1[__andn_u32(0x0F0FFFFF, 0xF0F00000) == 0xF0F00000 ? 1 : -1];
+
+//Intel
+char _andn_u32_0[_andn_u32(0xFFFF1FFF, 0x0000F000) == 0x0000E000 ? 1 : -1];
+char _andn_u32_1[_andn_u32(0xF0F0F0F0, 0x01010101) == 0x01010101 ? 1 : -1];
+
+#ifdef __X86_64__
+char andn_u64_0[__andn_u64(0x0000FFFF11110000, 0x0101010101010101) == 0x0101000000000101 ? 1 : -1];
+char andn_u64_1[__andn_u64(0x0FFFFFFFFFFF137F, 0xF00000000000FFFF) == 0xF00000000000EC80 ? 1 : -1];
+
+//Intel
+char _andn_u64_0[_andn_u64(0xFFFF0000FFFF0000, 0x0000FFFF0000FFFF) == 0x0000FFFF0000FFFF ? 1 : -1];
+char _andn_u64_1[_andn_u64(0xFFFFEDCBFFFFA987, 0x0000FFFF0000FF00) == 0x0000123400005600 ? 1 : -1];
+#endif
+
+//BEXTR
+char bextr_u32_0[__bextr_u32(0xFFFF0000, 0x00001010) == 0x0000FFFF ? 1 : -1];
+char bextr_u32_1[__bextr_u32(0x00FFF800, 0x0000100B) == 0x00001FFF ? 1 : -1];
+
+//Intel
+char _bextr_u32_0[_bextr_u32(0x10FFF800, 20, 9) == 0x0000010F ? 1 : -1];
+char _bextr_u32_1[_bextr_u32(0x0000FF10, 16, 16) == 0x00000000 ? 1 : -1];
+
+#ifdef __X86_64__
+char bextr_u64_0[__bextr_u64(0x7FFF00001111FFFF, 0x00002020) == 0x000000007FFF0000 ? 1 : -1];
+char bextr_u64_1[__bextr_u64(0xF0FFF800FFFF1111, 0x00004040) == 0x0000000000000000 ? 1 : -1];
+
+//Intel
+char _bextr_u64_0[_bextr_u64(0x7FFFFFFF10FF1111, 32, 32) == 0x000000007FFFFFFF ? 1 : -1];
+char _bextr_u64_1[_bextr_u64(0x1111FFFF0000FF10, 48, 16) == 0x0000000000001111 ? 1 : -1];
+#endif
+
+//BLSI
+char blsi_u32_0[__blsi_u32(0x0000FFF8) == 0x00000008 ? 1 : -1];
+char blsi_u32_1[__blsi_u32(0x00FF0000) == 0x00010000 ? 1 : -1];
+
+//Intel
+char _blsi_u32_0[_blsi_u32(0x70000B00) == 0x00000100 ? 1 : -1];
+char _blsi_u32_1[_blsi_u32(0x80000000) == 0x80000000 ? 1 : -1];
+
+#ifdef __X86_64__
+char blsi_u64_0[__blsi_u64(0xF0FFF800FFF00000) == 0x100000 ? 1 : -1];
+char blsi_u64_1[__blsi_u64(0x0AE0000000000000) == 0x0020000000000000 ? 1 : -1];
+
+//Intel
+char _blsi_u64_0[_blsi_u64(0xFFFFFC0000000000) == 0x0000040000000000 ? 1 : -1];
+char _blsi_u64_1[_blsi_u64(0x0FE0000000000000) == 0x0020000000000000 ? 1 : -1];
+#endif
+
+//BLSMSK
+char blsmsk_u32_0[__blsmsk_u32(0xF0F0F0F0) == 0x0000001F ? 1 : -1];
+char blsmsk_u32_1[__blsmsk_u32(0x7FFFFC00) == 0x000007FF ? 1 : -1];
+
+//Intel
+char _blsmsk_u32_0[_blsmsk_u32(0xB0000000) == 0x1FFFFFFF ? 1 : -1];
+char _blsmsk_u32_1[_blsmsk_u32(0x00000000) == 0xFFFFFFFF ? 1 : -1];
+
+#ifdef __X86_64__
+char blsmsk_u64_0[__blsmsk_u64(0xF0F0F0F000A00000) == 0x00000000003FFFFF ? 1 : -1];
+char blsmsk_u64_1[__blsmsk_u64(0x1111100000000800) == 0x0000000000000FFF ? 1 : -1];
+
+//Intel
+char _blsmsk_u64_0[_blsmsk_u64(0xFFFFFC0000000000) == 0x000007FFFFFFFFFF ? 1 : -1];
+char _blsmsk_u64_1[_blsmsk_u64(0xFFFFFFFFFFFFFFFF) == 0x0000000000000001 ? 1 : -1];
+#endif
+
+//BLSR
+char blsr_u32_0[__blsr_u32(0xB00FFFFF) == 0xB00FFFFE ? 1 : -1];
+char blsr_u32_1[__blsr_u32(0xFFFFFFFF) == 0xFFFFFFFE ? 1 : -1];
+
+//Intel
+char _blsr_u32_0[_blsr_u32(0xB0000000) == 0xA0000000 ? 1 : -1];
+char _blsr_u32_1[_blsr_u32(0x00000000) == 0x00000000 ? 1 : -1];
+
+#ifdef __X86_64__
+char blsr_u64_0[__blsr_u64(0xB00FF70000000000) == 0xB00FF60000000000 ? 1 : -1];
+char blsr_u64_1[__blsr_u64(0xFFFFFFFFFFFFFFFF) == 0xFFFFFFFFFFFFFFFE ? 1 : -1];
+
+//Intel
+char _blsr_u64_0[_blsr_u64(0xB00FFFFFFFFF0000) == 0xB00FFFFFFFFE0000 ? 1 : -1];
+char _blsr_u64_1[_blsr_u64(0x8000000000000000) == 0x0000000000000000 ? 1 : -1];
+#endif //ifdef __X86_64__
+
+#endif //!(defined(TEST_TZCNT)
+#endif // __cplusplus
diff --git a/clang/test/CodeGen/X86/lzcnt-builtins.c b/clang/test/CodeGen/X86/lzcnt-builtins.c
index 9255207ffaef4..a9c643bae0855 100644
--- a/clang/test/CodeGen/X86/lzcnt-builtins.c
+++ b/clang/test/CodeGen/X86/lzcnt-builtins.c
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +lzcnt -emit-llvm -o - | FileCheck %s
-
+// RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +lzcnt -no-enable-noundef-analysis -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +lzcnt -no-enable-noundef-analysis -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -no-enable-noundef-analysis -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -no-enable-noundef-analysis -emit-llvm -o - | FileCheck %s
#include <immintrin.h>
@@ -32,3 +34,34 @@ unsigned long long test__lzcnt_u64(unsigned long long __X)
// CHECK: @llvm.ctlz.i64(i64 %{{.*}}, i1 false)
return _lzcnt_u64(__X);
}
+
+// Test constexpr handling.
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+
+#if defined(_MSC_VER)
+char ms_ctlz16_0[__lzcnt16(0x3FF0) == 2 ? 1 : -1];
+char ms_ctlz16_1[__lzcnt16(0xF000) == 0 ? 1 : -1];
+
+char ms_ctlz32_0[__lzcnt32(0xFFF00000) == 0 ? 1 : -1];
+char ms_ctlz32_1[__lzcnt32(0x000001F0) == 23 ? 1 : -1];
+#endif
+
+#if defined(__LZCNT__)
+char ctlz32_0[_lzcnt_u32(0x00000000) == 0 ? 1 : -1];
+char ctlz32_1[_lzcnt_u32(0x000000F0) == 24 ? 1 : -1];
+#endif
+
+#ifdef __x86_64__
+
+#if defined(_MSC_VER)
+char ms_ctlz64_0[__lzcnt64(0x00000000FFF00000) == 32 ? 1 : -1];
+char ms_ctlz64_1[__lzcnt64(0x00F00000000001F0) == 8 ? 1 : -1];
+#endif
+
+#if defined(__LZCNT__)
+char ctlz64_0[_lzcnt_u64(0x000000000000F000ULL) == 48 ? 1 : -1];
+char ctlz64_1[_lzcnt_u64(0x0100000000000001ULL) == 7 ? 1 : -1];
+#endif
+
+#endif
+#endif
>From 4a6193171376ee1a39ce6a2e408c62cba9a785aa Mon Sep 17 00:00:00 2001
From: aniplcc <aniplccode at gmail.com>
Date: Sun, 2 Jun 2024 19:52:51 +0530
Subject: [PATCH 2/2] format fixes
---
clang/lib/Headers/bmiintrin.h | 4 ++--
clang/lib/Headers/lzcntintrin.h | 11 ++++-------
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Headers/bmiintrin.h b/clang/lib/Headers/bmiintrin.h
index c5b57a1d1e43c..56e62fc98d6dc 100644
--- a/clang/lib/Headers/bmiintrin.h
+++ b/clang/lib/Headers/bmiintrin.h
@@ -19,7 +19,7 @@
to use it as a potentially faster version of BSF. */
#define __RELAXED_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
-#if defined (__cplusplus) && (__cplusplus >= 201103L)
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define __RELAXED_FN_ATTRS_CONSTEXPR __RELAXED_FN_ATTRS constexpr
#else
#define __RELAXED_FN_ATTRS_CONSTEXPR __RELAXED_FN_ATTRS
@@ -172,7 +172,7 @@ _mm_tzcnt_64(unsigned long long __X)
/* 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)
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr
#else
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
diff --git a/clang/lib/Headers/lzcntintrin.h b/clang/lib/Headers/lzcntintrin.h
index 190fe66f3d72f..dd2d1d53eed25 100644
--- a/clang/lib/Headers/lzcntintrin.h
+++ b/clang/lib/Headers/lzcntintrin.h
@@ -17,7 +17,7 @@
/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("lzcnt")))
-#if defined (__cplusplus) && (__cplusplus >= 201103L)
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr
#else
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
@@ -49,8 +49,7 @@
/// bits in the operand.
/// \see _lzcnt_u32
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
-__lzcnt32(unsigned int __X)
-{
+__lzcnt32(unsigned int __X) {
return __builtin_ia32_lzcnt_u32(__X);
}
@@ -66,8 +65,7 @@ __lzcnt32(unsigned int __X)
/// bits in the operand.
/// \see __lzcnt32
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
-_lzcnt_u32(unsigned int __X)
-{
+_lzcnt_u32(unsigned int __X) {
return __builtin_ia32_lzcnt_u32(__X);
}
@@ -99,8 +97,7 @@ _lzcnt_u32(unsigned int __X)
/// bits in the operand.
/// \see __lzcnt64
static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
-_lzcnt_u64(unsigned long long __X)
-{
+_lzcnt_u64(unsigned long long __X) {
return __builtin_ia32_lzcnt_u64(__X);
}
#endif
More information about the cfe-commits
mailing list