Skip to content

Commit 271dc4a

Browse files
authored
[clang][x86] Add constexpr support for PDEP/PEXT intrinsics (llvm#110535)
1 parent 09b8dbf commit 271dc4a

File tree

6 files changed

+60
-8
lines changed

6 files changed

+60
-8
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,8 @@ X86 Support
523523
all bextr intrinsics in bmiintrin.h
524524
all tzcnt intrinsics in bmiintrin.h
525525
all bzhi intrinsics in bmi2intrin.h
526+
all pdep intrinsics in bmi2intrin.h
527+
all pext intrinsics in bmi2intrin.h
526528
all intrinsics in tbmintrin.h
527529

528530
Arm and AArch64 Support

clang/include/clang/Basic/BuiltinsX86.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,8 @@ TARGET_BUILTIN(__builtin_ia32_tzcnt_u32, "UiUi", "ncE", "")
561561

562562
// BMI2
563563
TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "ncE", "bmi2")
564-
TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "nc", "bmi2")
565-
TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "nc", "bmi2")
564+
TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "ncE", "bmi2")
565+
TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "ncE", "bmi2")
566566

567567
// TBM
568568
TARGET_BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "ncE", "tbm")

clang/include/clang/Basic/BuiltinsX86_64.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ 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", "")
7676
TARGET_BUILTIN(__builtin_ia32_bzhi_di, "UOiUOiUOi", "ncE", "bmi2")
77-
TARGET_BUILTIN(__builtin_ia32_pdep_di, "UOiUOiUOi", "nc", "bmi2")
78-
TARGET_BUILTIN(__builtin_ia32_pext_di, "UOiUOiUOi", "nc", "bmi2")
77+
TARGET_BUILTIN(__builtin_ia32_pdep_di, "UOiUOiUOi", "ncE", "bmi2")
78+
TARGET_BUILTIN(__builtin_ia32_pext_di, "UOiUOiUOi", "ncE", "bmi2")
7979
TARGET_BUILTIN(__builtin_ia32_bextri_u64, "UOiUOiIUOi", "ncE", "tbm")
8080
TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcUOiUiIUi", "n", "lwp")
8181
TARGET_BUILTIN(__builtin_ia32_lwpval64, "vUOiUiIUi", "n", "lwp")

clang/lib/AST/ExprConstant.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13518,6 +13518,36 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1351813518
return false;
1351913519
return Success(Val.countTrailingZeros(), E);
1352013520
}
13521+
13522+
case clang::X86::BI__builtin_ia32_pdep_si:
13523+
case clang::X86::BI__builtin_ia32_pdep_di: {
13524+
APSInt Val, Msk;
13525+
if (!EvaluateInteger(E->getArg(0), Val, Info) ||
13526+
!EvaluateInteger(E->getArg(1), Msk, Info))
13527+
return false;
13528+
13529+
unsigned BitWidth = Val.getBitWidth();
13530+
APInt Result = APInt::getZero(BitWidth);
13531+
for (unsigned I = 0, P = 0; I != BitWidth; ++I)
13532+
if (Msk[I])
13533+
Result.setBitVal(I, Val[P++]);
13534+
return Success(Result, E);
13535+
}
13536+
13537+
case clang::X86::BI__builtin_ia32_pext_si:
13538+
case clang::X86::BI__builtin_ia32_pext_di: {
13539+
APSInt Val, Msk;
13540+
if (!EvaluateInteger(E->getArg(0), Val, Info) ||
13541+
!EvaluateInteger(E->getArg(1), Msk, Info))
13542+
return false;
13543+
13544+
unsigned BitWidth = Val.getBitWidth();
13545+
APInt Result = APInt::getZero(BitWidth);
13546+
for (unsigned I = 0, P = 0; I != BitWidth; ++I)
13547+
if (Msk[I])
13548+
Result.setBitVal(P++, Val[I]);
13549+
return Success(Result, E);
13550+
}
1352113551
}
1352213552
}
1352313553

clang/lib/Headers/bmi2intrin.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ _bzhi_u32(unsigned int __X, unsigned int __Y)
7373
/// \param __Y
7474
/// The 32-bit mask specifying where to deposit source bits.
7575
/// \returns The 32-bit result.
76-
static __inline__ unsigned int __DEFAULT_FN_ATTRS
76+
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
7777
_pdep_u32(unsigned int __X, unsigned int __Y)
7878
{
7979
return __builtin_ia32_pdep_si(__X, __Y);
@@ -103,7 +103,7 @@ _pdep_u32(unsigned int __X, unsigned int __Y)
103103
/// \param __Y
104104
/// The 32-bit mask specifying which source bits to extract.
105105
/// \returns The 32-bit result.
106-
static __inline__ unsigned int __DEFAULT_FN_ATTRS
106+
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
107107
_pext_u32(unsigned int __X, unsigned int __Y)
108108
{
109109
return __builtin_ia32_pext_si(__X, __Y);
@@ -189,7 +189,7 @@ _bzhi_u64(unsigned long long __X, unsigned long long __Y)
189189
/// \param __Y
190190
/// The 64-bit mask specifying where to deposit source bits.
191191
/// \returns The 64-bit result.
192-
static __inline__ unsigned long long __DEFAULT_FN_ATTRS
192+
static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
193193
_pdep_u64(unsigned long long __X, unsigned long long __Y)
194194
{
195195
return __builtin_ia32_pdep_di(__X, __Y);
@@ -219,7 +219,7 @@ _pdep_u64(unsigned long long __X, unsigned long long __Y)
219219
/// \param __Y
220220
/// The 64-bit mask specifying which source bits to extract.
221221
/// \returns The 64-bit result.
222-
static __inline__ unsigned long long __DEFAULT_FN_ATTRS
222+
static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
223223
_pext_u64(unsigned long long __X, unsigned long long __Y)
224224
{
225225
return __builtin_ia32_pext_di(__X, __Y);

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,30 @@ char bzhi32_3[_bzhi_u32(0x89ABCDEF, 32) == 0x89ABCDEF ? 1 : -1];
6161
char bzhi32_4[_bzhi_u32(0x89ABCDEF, 99) == 0x89ABCDEF ? 1 : -1];
6262
char bzhi32_5[_bzhi_u32(0x89ABCDEF, 260) == 0x0000000F ? 1 : -1];
6363

64+
char pdep32_0[_pdep_u32(0x89ABCDEF, 0x00000000) == 0x00000000 ? 1 : -1];
65+
char pdep32_1[_pdep_u32(0x89ABCDEF, 0x000000F0) == 0x000000F0 ? 1 : -1];
66+
char pdep32_2[_pdep_u32(0x89ABCDEF, 0xF00000F0) == 0xE00000F0 ? 1 : -1];
67+
char pdep32_3[_pdep_u32(0x89ABCDEF, 0xFFFFFFFF) == 0x89ABCDEF ? 1 : -1];
68+
69+
char pext32_0[_pext_u32(0x89ABCDEF, 0x00000000) == 0x00000000 ? 1 : -1];
70+
char pext32_1[_pext_u32(0x89ABCDEF, 0x000000F0) == 0x0000000E ? 1 : -1];
71+
char pext32_2[_pext_u32(0x89ABCDEF, 0xF00000F0) == 0x0000008E ? 1 : -1];
72+
char pext32_3[_pext_u32(0x89ABCDEF, 0xFFFFFFFF) == 0x89ABCDEF ? 1 : -1];
73+
6474
#ifdef __x86_64__
6575
char bzhi64_0[_bzhi_u64(0x0123456789ABCDEFULL, 0) == 0x0000000000000000ULL ? 1 : -1];
6676
char bzhi64_1[_bzhi_u64(0x0123456789ABCDEFULL, 32) == 0x0000000089ABCDEFULL ? 1 : -1];
6777
char bzhi64_2[_bzhi_u64(0x0123456789ABCDEFULL, 99) == 0x0123456789ABCDEFULL ? 1 : -1];
6878
char bzhi64_3[_bzhi_u64(0x0123456789ABCDEFULL, 520) == 0x00000000000000EFULL ? 1 : -1];
79+
80+
char pdep64_0[_pdep_u64(0x0123456789ABCDEFULL, 0x0000000000000000ULL) == 0x0000000000000000ULL ? 1 : -1];
81+
char pdep64_1[_pdep_u64(0x0123456789ABCDEFULL, 0x00000000000000F0ULL) == 0x00000000000000F0ULL ? 1 : -1];
82+
char pdep64_2[_pdep_u64(0x0123456789ABCDEFULL, 0xF00000F0F00000F0ULL) == 0xC00000D0E00000F0ULL ? 1 : -1];
83+
char pdep64_3[_pdep_u64(0x0123456789ABCDEFULL, 0xFFFFFFFFFFFFFFFFULL) == 0x0123456789ABCDEFULL ? 1 : -1];
84+
85+
char pext64_0[_pext_u64(0x0123456789ABCDEFULL, 0x0000000000000000ULL) == 0x0000000000000000ULL ? 1 : -1];
86+
char pext64_1[_pext_u64(0x0123456789ABCDEFULL, 0x00000000000000F0ULL) == 0x000000000000000EULL ? 1 : -1];
87+
char pext64_2[_pext_u64(0x0123456789ABCDEFULL, 0xF00000F0F00000F0ULL) == 0x000000000000068EULL ? 1 : -1];
88+
char pext64_3[_pext_u64(0x0123456789ABCDEFULL, 0xFFFFFFFFFFFFFFFFULL) == 0x0123456789ABCDEFULL ? 1 : -1];
6989
#endif
7090
#endif

0 commit comments

Comments
 (0)