https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/110508
>From ef0ee711abb4568f9da2de7f54e45141330d03c7 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <llvm-...@redking.me.uk> Date: Mon, 30 Sep 2024 14:16:31 +0100 Subject: [PATCH] [clang][x86] Add constexpr support for BZHI intrinsics --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/Basic/BuiltinsX86.def | 2 +- clang/include/clang/Basic/BuiltinsX86_64.def | 2 +- clang/lib/AST/ExprConstant.cpp | 14 +++++++++++ clang/lib/Headers/bmi2intrin.h | 10 ++++++-- clang/test/CodeGen/X86/bmi2-builtins.c | 25 ++++++++++++++++---- 6 files changed, 46 insertions(+), 8 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d48601db023553..0996718bf7106d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -515,6 +515,7 @@ X86 Support 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 bextr intrinsics in tbmintrin.h Arm and AArch64 Support diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def index e68dcd922acbff..8cf9dbdef9bb3c 100644 --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -560,7 +560,7 @@ TARGET_BUILTIN(__builtin_ia32_tzcnt_u16, "UsUs", "ncE", "") TARGET_BUILTIN(__builtin_ia32_tzcnt_u32, "UiUi", "ncE", "") // BMI2 -TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "nc", "bmi2") +TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "ncE", "bmi2") TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "nc", "bmi2") TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "nc", "bmi2") diff --git a/clang/include/clang/Basic/BuiltinsX86_64.def b/clang/include/clang/Basic/BuiltinsX86_64.def index 5f4252c91b8847..dd4b15bac81989 100644 --- a/clang/include/clang/Basic/BuiltinsX86_64.def +++ b/clang/include/clang/Basic/BuiltinsX86_64.def @@ -73,7 +73,7 @@ TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiUOi*", "n", "rdseed") TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "UOiUOi", "ncE", "lzcnt") TARGET_BUILTIN(__builtin_ia32_bextr_u64, "UOiUOiUOi", "ncE", "bmi") TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "UOiUOi", "ncE", "") -TARGET_BUILTIN(__builtin_ia32_bzhi_di, "UOiUOiUOi", "nc", "bmi2") +TARGET_BUILTIN(__builtin_ia32_bzhi_di, "UOiUOiUOi", "ncE", "bmi2") TARGET_BUILTIN(__builtin_ia32_pdep_di, "UOiUOiUOi", "nc", "bmi2") TARGET_BUILTIN(__builtin_ia32_pext_di, "UOiUOiUOi", "nc", "bmi2") TARGET_BUILTIN(__builtin_ia32_bextri_u64, "UOiUOiIUOi", "ncE", "tbm") diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 834a7a1e2eb239..402fd5dbae9a0f 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13487,6 +13487,20 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, return Success(Result, E); } + case clang::X86::BI__builtin_ia32_bzhi_si: + case clang::X86::BI__builtin_ia32_bzhi_di: { + APSInt Val, Idx; + if (!EvaluateInteger(E->getArg(0), Val, Info) || + !EvaluateInteger(E->getArg(1), Idx, Info)) + return false; + + unsigned BitWidth = Val.getBitWidth(); + unsigned Index = Idx.extractBitsAsZExtValue(8, 0); + if (Index < BitWidth) + Val.clearHighBits(BitWidth - Index); + return Success(Val, E); + } + case clang::X86::BI__builtin_ia32_lzcnt_u16: case clang::X86::BI__builtin_ia32_lzcnt_u32: case clang::X86::BI__builtin_ia32_lzcnt_u64: { diff --git a/clang/lib/Headers/bmi2intrin.h b/clang/lib/Headers/bmi2intrin.h index f0a3343bef9150..31d97e62719109 100644 --- a/clang/lib/Headers/bmi2intrin.h +++ b/clang/lib/Headers/bmi2intrin.h @@ -17,6 +17,12 @@ /* Define the default attributes for the functions in this file. */ #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("bmi2"))) +#if defined(__cplusplus) && (__cplusplus >= 201103L) +#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr +#else +#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS +#endif + /// Copies the unsigned 32-bit integer \a __X and zeroes the upper bits /// starting at bit number \a __Y. /// @@ -37,7 +43,7 @@ /// \param __Y /// The lower 8 bits specify the bit number of the lowest bit to zero. /// \returns The partially zeroed 32-bit value. -static __inline__ unsigned int __DEFAULT_FN_ATTRS +static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR _bzhi_u32(unsigned int __X, unsigned int __Y) { return __builtin_ia32_bzhi_si(__X, __Y); @@ -153,7 +159,7 @@ _mulx_u32(unsigned int __X, unsigned int __Y, unsigned int *__P) /// \param __Y /// The lower 8 bits specify the bit number of the lowest bit to zero. /// \returns The partially zeroed 64-bit value. -static __inline__ unsigned long long __DEFAULT_FN_ATTRS +static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR _bzhi_u64(unsigned long long __X, unsigned long long __Y) { return __builtin_ia32_bzhi_di(__X, __Y); diff --git a/clang/test/CodeGen/X86/bmi2-builtins.c b/clang/test/CodeGen/X86/bmi2-builtins.c index a9e9bc5862a347..9312192f85a932 100644 --- a/clang/test/CodeGen/X86/bmi2-builtins.c +++ b/clang/test/CodeGen/X86/bmi2-builtins.c @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s --check-prefix=B32 +// RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -x c -ffreestanding %s -triple=i386-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s --check-prefix=B32 +// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple=i386-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s --check-prefix=B32 #include <immintrin.h> @@ -22,7 +24,6 @@ unsigned int test_pext_u32(unsigned int __X, unsigned int __Y) { #ifdef __i386__ unsigned int test_mulx_u32(unsigned int __X, unsigned int __Y, unsigned int *__P) { - // B32: @test_mulx_u32 // B32: mul i64 return _mulx_u32(__X, __Y, __P); } @@ -46,8 +47,24 @@ unsigned long long test_pext_u64(unsigned long long __X, unsigned long long __Y) unsigned long long test_mulx_u64(unsigned long long __X, unsigned long long __Y, unsigned long long *__P) { - // CHECK: @test_mulx_u64 // CHECK: mul i128 return _mulx_u64(__X, __Y, __P); } #endif + +// Test constexpr handling. +#if defined(__cplusplus) && (__cplusplus >= 201103L) +char bzhi32_0[_bzhi_u32(0x89ABCDEF, 0) == 0x00000000 ? 1 : -1]; +char bzhi32_1[_bzhi_u32(0x89ABCDEF, 16) == 0x0000CDEF ? 1 : -1]; +char bzhi32_2[_bzhi_u32(0x89ABCDEF, 31) == 0x09ABCDEF ? 1 : -1]; +char bzhi32_3[_bzhi_u32(0x89ABCDEF, 32) == 0x89ABCDEF ? 1 : -1]; +char bzhi32_4[_bzhi_u32(0x89ABCDEF, 99) == 0x89ABCDEF ? 1 : -1]; +char bzhi32_5[_bzhi_u32(0x89ABCDEF, 260) == 0x0000000F ? 1 : -1]; + +#ifdef __x86_64__ +char bzhi64_0[_bzhi_u64(0x0123456789ABCDEFULL, 0) == 0x0000000000000000ULL ? 1 : -1]; +char bzhi64_1[_bzhi_u64(0x0123456789ABCDEFULL, 32) == 0x0000000089ABCDEFULL ? 1 : -1]; +char bzhi64_2[_bzhi_u64(0x0123456789ABCDEFULL, 99) == 0x0123456789ABCDEFULL ? 1 : -1]; +char bzhi64_3[_bzhi_u64(0x0123456789ABCDEFULL, 520) == 0x00000000000000EFULL ? 1 : -1]; +#endif +#endif \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits