[clang] [X86] Allow using the lzcnt intrinsics for non-LZCNT targets (PR #128284)

Phoebe Wang via cfe-commits cfe-commits at lists.llvm.org
Sat Feb 22 03:41:29 PST 2025


https://github.com/phoebewang updated https://github.com/llvm/llvm-project/pull/128284

>From eef9ec3ca38a2ba1dd12c8a8f8bfcacf38ab7926 Mon Sep 17 00:00:00 2001
From: "Wang, Phoebe" <phoebe.wang at intel.com>
Date: Sat, 22 Feb 2025 12:20:09 +0800
Subject: [PATCH 1/2] [X86] Allow using the lzcnt intrinsics for non-LZCNT
 targets

Similar to D14748, we can relax lzcnt intrinsics too, especially with
improved BSR lowering by #123623
---
 clang/include/clang/Basic/BuiltinsX86.td    | 7 ++-----
 clang/include/clang/Basic/BuiltinsX86_64.td | 5 +----
 clang/lib/Headers/lzcntintrin.h             | 5 ++---
 clang/test/CodeGen/X86/lzcnt-builtins.c     | 6 +++---
 4 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td
index 572ac7235be02..e2252620bab56 100644
--- a/clang/include/clang/Basic/BuiltinsX86.td
+++ b/clang/include/clang/Basic/BuiltinsX86.td
@@ -832,11 +832,6 @@ let Features = "rdseed", Attributes = [NoThrow] in {
   def rdseed32_step : X86Builtin<"unsigned int(unsigned int *)">;
 }
 
-let Features = "lzcnt", Attributes = [NoThrow, Const, Constexpr] in {
-  def lzcnt_u16 : X86Builtin<"unsigned short(unsigned short)">;
-  def lzcnt_u32 : X86Builtin<"unsigned int(unsigned int)">;
-}
-
 let Features = "bmi", Attributes = [NoThrow, Const, Constexpr] in {
   def bextr_u32 : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
 }
@@ -844,6 +839,8 @@ let Features = "bmi", Attributes = [NoThrow, Const, Constexpr] in {
 let Attributes = [NoThrow, Const, Constexpr] in {
   def tzcnt_u16 : X86Builtin<"unsigned short(unsigned short)">;
   def tzcnt_u32 : X86Builtin<"unsigned int(unsigned int)">;
+  def lzcnt_u16 : X86Builtin<"unsigned short(unsigned short)">;
+  def lzcnt_u32 : X86Builtin<"unsigned int(unsigned int)">;
 }
 
 let Features = "bmi2", Attributes = [NoThrow, Const, Constexpr] in {
diff --git a/clang/include/clang/Basic/BuiltinsX86_64.td b/clang/include/clang/Basic/BuiltinsX86_64.td
index 4958265298d1b..f2b35874e3876 100644
--- a/clang/include/clang/Basic/BuiltinsX86_64.td
+++ b/clang/include/clang/Basic/BuiltinsX86_64.td
@@ -126,16 +126,13 @@ let Features = "rdseed", Attributes = [NoThrow] in {
   def rdseed64_step : X86Builtin<"unsigned int(unsigned long long int *)">;
 }
 
-let Features = "lzcnt", Attributes = [NoThrow, Const, Constexpr] in {
-  def lzcnt_u64 : X86Builtin<"unsigned long long int(unsigned long long int)">;
-}
-
 let Features = "bmi", Attributes = [NoThrow, Const, Constexpr] in {
   def bextr_u64 : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
 }
 
 let Attributes = [NoThrow, Const, Constexpr] in {
   def tzcnt_u64 : X86Builtin<"unsigned long long int(unsigned long long int)">;
+  def lzcnt_u64 : X86Builtin<"unsigned long long int(unsigned long long int)">;
 }
 
 let Features = "bmi2", Attributes = [NoThrow, Const, Constexpr] in {
diff --git a/clang/lib/Headers/lzcntintrin.h b/clang/lib/Headers/lzcntintrin.h
index 27509021ec258..8d2d39f094aa0 100644
--- a/clang/lib/Headers/lzcntintrin.h
+++ b/clang/lib/Headers/lzcntintrin.h
@@ -17,10 +17,9 @@
 /* Define the default attributes for the functions in this file. */
 #if defined(__cplusplus) && (__cplusplus >= 201103L)
 #define __DEFAULT_FN_ATTRS                                                     \
-  __attribute__((__always_inline__, __nodebug__, __target__("lzcnt"))) constexpr
+  __attribute__((__always_inline__, __nodebug__)) constexpr
 #else
-#define __DEFAULT_FN_ATTRS                                                     \
-  __attribute__((__always_inline__, __nodebug__, __target__("lzcnt")))
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
 #endif
 
 #ifndef _MSC_VER
diff --git a/clang/test/CodeGen/X86/lzcnt-builtins.c b/clang/test/CodeGen/X86/lzcnt-builtins.c
index 18ced89fc79b1..212155f123adc 100644
--- a/clang/test/CodeGen/X86/lzcnt-builtins.c
+++ b/clang/test/CodeGen/X86/lzcnt-builtins.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +lzcnt -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -x c++ -std=c++11 -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 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
 
 
 #include <immintrin.h>
@@ -56,4 +56,4 @@ char lzcntu32_2[_lzcnt_u32(0x00000010) == 27 ? 1 : -1];
 char lzcntu64_0[_lzcnt_u64(0x0000000000000000ULL) == 64 ? 1 : -1];
 char lzcntu64_1[_lzcnt_u64(0x8000000000000000ULL) ==  0 ? 1 : -1];
 char lzcntu64_2[_lzcnt_u64(0x0000000100000000ULL) == 31 ? 1 : -1];
-#endif
\ No newline at end of file
+#endif

>From 2a271ce372f618382168219c5482340ba9fea6b6 Mon Sep 17 00:00:00 2001
From: "Wang, Phoebe" <phoebe.wang at intel.com>
Date: Sat, 22 Feb 2025 19:41:13 +0800
Subject: [PATCH 2/2] Add comment

---
 clang/lib/Headers/lzcntintrin.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Headers/lzcntintrin.h b/clang/lib/Headers/lzcntintrin.h
index 8d2d39f094aa0..123a42a888214 100644
--- a/clang/lib/Headers/lzcntintrin.h
+++ b/clang/lib/Headers/lzcntintrin.h
@@ -14,7 +14,10 @@
 #ifndef __LZCNTINTRIN_H
 #define __LZCNTINTRIN_H
 
-/* Define the default attributes for the functions in this file. */
+/* Define the default attributes for the functions in this file.
+   Allow using the lzcnt intrinsics even for non-LZCNT targets. Since the LZCNT
+   intrinsics are mapped to llvm.ctlz.*, false, which can be lowered to BSR on
+   non-LZCNT targets with zero-value input handled correctly. */
 #if defined(__cplusplus) && (__cplusplus >= 201103L)
 #define __DEFAULT_FN_ATTRS                                                     \
   __attribute__((__always_inline__, __nodebug__)) constexpr



More information about the cfe-commits mailing list