Skip to content

Commit 2867c70

Browse files
RKSimonpuja2196
authored andcommitted
[clang][x86] Add constexpr support for BZHI intrinsics (#110508)
1 parent 08cd673 commit 2867c70

File tree

6 files changed

+46
-8
lines changed

6 files changed

+46
-8
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ X86 Support
515515
all lzcnt intrinsics in lzcntintrin.h
516516
all bextr intrinsics in bmiintrin.h
517517
all tzcnt intrinsics in bmiintrin.h
518+
all bzhi intrinsics in bmi2intrin.h
518519
all bextr intrinsics in tbmintrin.h
519520

520521
Arm and AArch64 Support

clang/include/clang/Basic/BuiltinsX86.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ TARGET_BUILTIN(__builtin_ia32_tzcnt_u16, "UsUs", "ncE", "")
560560
TARGET_BUILTIN(__builtin_ia32_tzcnt_u32, "UiUi", "ncE", "")
561561

562562
// BMI2
563-
TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "nc", "bmi2")
563+
TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "ncE", "bmi2")
564564
TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "nc", "bmi2")
565565
TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "nc", "bmi2")
566566

clang/include/clang/Basic/BuiltinsX86_64.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiUOi*", "n", "rdseed")
7373
TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "UOiUOi", "ncE", "lzcnt")
7474
TARGET_BUILTIN(__builtin_ia32_bextr_u64, "UOiUOiUOi", "ncE", "bmi")
7575
TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "UOiUOi", "ncE", "")
76-
TARGET_BUILTIN(__builtin_ia32_bzhi_di, "UOiUOiUOi", "nc", "bmi2")
76+
TARGET_BUILTIN(__builtin_ia32_bzhi_di, "UOiUOiUOi", "ncE", "bmi2")
7777
TARGET_BUILTIN(__builtin_ia32_pdep_di, "UOiUOiUOi", "nc", "bmi2")
7878
TARGET_BUILTIN(__builtin_ia32_pext_di, "UOiUOiUOi", "nc", "bmi2")
7979
TARGET_BUILTIN(__builtin_ia32_bextri_u64, "UOiUOiIUOi", "ncE", "tbm")

clang/lib/AST/ExprConstant.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13487,6 +13487,20 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1348713487
return Success(Result, E);
1348813488
}
1348913489

13490+
case clang::X86::BI__builtin_ia32_bzhi_si:
13491+
case clang::X86::BI__builtin_ia32_bzhi_di: {
13492+
APSInt Val, Idx;
13493+
if (!EvaluateInteger(E->getArg(0), Val, Info) ||
13494+
!EvaluateInteger(E->getArg(1), Idx, Info))
13495+
return false;
13496+
13497+
unsigned BitWidth = Val.getBitWidth();
13498+
unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
13499+
if (Index < BitWidth)
13500+
Val.clearHighBits(BitWidth - Index);
13501+
return Success(Val, E);
13502+
}
13503+
1349013504
case clang::X86::BI__builtin_ia32_lzcnt_u16:
1349113505
case clang::X86::BI__builtin_ia32_lzcnt_u32:
1349213506
case clang::X86::BI__builtin_ia32_lzcnt_u64: {

clang/lib/Headers/bmi2intrin.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
/* Define the default attributes for the functions in this file. */
1818
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("bmi2")))
1919

20+
#if defined(__cplusplus) && (__cplusplus >= 201103L)
21+
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr
22+
#else
23+
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
24+
#endif
25+
2026
/// Copies the unsigned 32-bit integer \a __X and zeroes the upper bits
2127
/// starting at bit number \a __Y.
2228
///
@@ -37,7 +43,7 @@
3743
/// \param __Y
3844
/// The lower 8 bits specify the bit number of the lowest bit to zero.
3945
/// \returns The partially zeroed 32-bit value.
40-
static __inline__ unsigned int __DEFAULT_FN_ATTRS
46+
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
4147
_bzhi_u32(unsigned int __X, unsigned int __Y)
4248
{
4349
return __builtin_ia32_bzhi_si(__X, __Y);
@@ -153,7 +159,7 @@ _mulx_u32(unsigned int __X, unsigned int __Y, unsigned int *__P)
153159
/// \param __Y
154160
/// The lower 8 bits specify the bit number of the lowest bit to zero.
155161
/// \returns The partially zeroed 64-bit value.
156-
static __inline__ unsigned long long __DEFAULT_FN_ATTRS
162+
static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
157163
_bzhi_u64(unsigned long long __X, unsigned long long __Y)
158164
{
159165
return __builtin_ia32_bzhi_di(__X, __Y);

clang/test/CodeGen/X86/bmi2-builtins.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s
2-
// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s --check-prefix=B32
1+
// RUN: %clang_cc1 -x c -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s
2+
// RUN: %clang_cc1 -x c -ffreestanding %s -triple=i386-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s --check-prefix=B32
3+
// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s
4+
// RUN: %clang_cc1 -x c++ -ffreestanding %s -triple=i386-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s --check-prefix=B32
35

46

57
#include <immintrin.h>
@@ -22,7 +24,6 @@ unsigned int test_pext_u32(unsigned int __X, unsigned int __Y) {
2224
#ifdef __i386__
2325
unsigned int test_mulx_u32(unsigned int __X, unsigned int __Y,
2426
unsigned int *__P) {
25-
// B32: @test_mulx_u32
2627
// B32: mul i64
2728
return _mulx_u32(__X, __Y, __P);
2829
}
@@ -46,8 +47,24 @@ unsigned long long test_pext_u64(unsigned long long __X, unsigned long long __Y)
4647

4748
unsigned long long test_mulx_u64(unsigned long long __X, unsigned long long __Y,
4849
unsigned long long *__P) {
49-
// CHECK: @test_mulx_u64
5050
// CHECK: mul i128
5151
return _mulx_u64(__X, __Y, __P);
5252
}
5353
#endif
54+
55+
// Test constexpr handling.
56+
#if defined(__cplusplus) && (__cplusplus >= 201103L)
57+
char bzhi32_0[_bzhi_u32(0x89ABCDEF, 0) == 0x00000000 ? 1 : -1];
58+
char bzhi32_1[_bzhi_u32(0x89ABCDEF, 16) == 0x0000CDEF ? 1 : -1];
59+
char bzhi32_2[_bzhi_u32(0x89ABCDEF, 31) == 0x09ABCDEF ? 1 : -1];
60+
char bzhi32_3[_bzhi_u32(0x89ABCDEF, 32) == 0x89ABCDEF ? 1 : -1];
61+
char bzhi32_4[_bzhi_u32(0x89ABCDEF, 99) == 0x89ABCDEF ? 1 : -1];
62+
char bzhi32_5[_bzhi_u32(0x89ABCDEF, 260) == 0x0000000F ? 1 : -1];
63+
64+
#ifdef __x86_64__
65+
char bzhi64_0[_bzhi_u64(0x0123456789ABCDEFULL, 0) == 0x0000000000000000ULL ? 1 : -1];
66+
char bzhi64_1[_bzhi_u64(0x0123456789ABCDEFULL, 32) == 0x0000000089ABCDEFULL ? 1 : -1];
67+
char bzhi64_2[_bzhi_u64(0x0123456789ABCDEFULL, 99) == 0x0123456789ABCDEFULL ? 1 : -1];
68+
char bzhi64_3[_bzhi_u64(0x0123456789ABCDEFULL, 520) == 0x00000000000000EFULL ? 1 : -1];
69+
#endif
70+
#endif

0 commit comments

Comments
 (0)