Skip to content

Commit de0e829

Browse files
authored
[Headers][X86] Allow basic AVX512 predicate ops to be used in constexpr (llvm#159998)
Fixes llvm#158646
1 parent 5b3dd43 commit de0e829

File tree

9 files changed

+410
-102
lines changed

9 files changed

+410
-102
lines changed

clang/include/clang/Basic/BuiltinsX86.td

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,15 +1219,15 @@ let Features = "avx512f", Attributes = [NoThrow, RequiredVectorWidth<512>] in {
12191219
def scatterdiv16si : X86Builtin<"void(void *, unsigned char, _Vector<8, long long int>, _Vector<8, int>, _Constant int)">;
12201220
}
12211221

1222-
let Features = "avx512dq", Attributes = [NoThrow, Const] in {
1222+
let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in {
12231223
def knotqi : X86Builtin<"unsigned char(unsigned char)">;
12241224
}
12251225

1226-
let Features = "avx512f", Attributes = [NoThrow, Const] in {
1226+
let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in {
12271227
def knothi : X86Builtin<"unsigned short(unsigned short)">;
12281228
}
12291229

1230-
let Features = "avx512bw", Attributes = [NoThrow, Const] in {
1230+
let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in {
12311231
def knotsi : X86Builtin<"unsigned int(unsigned int)">;
12321232
def knotdi : X86Builtin<"unsigned long long int(unsigned long long int)">;
12331233
}
@@ -3076,51 +3076,51 @@ let Features = "avx512dq", Attributes = [NoThrow, Const, RequiredVectorWidth<128
30763076
def fpclassss_mask : X86Builtin<"unsigned char(_Vector<4, float>, _Constant int, unsigned char)">;
30773077
}
30783078

3079-
let Features = "avx512dq", Attributes = [NoThrow, Const] in {
3079+
let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in {
30803080
def kaddqi : X86Builtin<"unsigned char(unsigned char, unsigned char)">;
30813081
def kaddhi : X86Builtin<"unsigned short(unsigned short, unsigned short)">;
30823082
}
30833083

3084-
let Features = "avx512bw", Attributes = [NoThrow, Const] in {
3084+
let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in {
30853085
def kaddsi : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
30863086
def kadddi : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
30873087
}
30883088

3089-
let Features = "avx512dq", Attributes = [NoThrow, Const] in {
3089+
let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in {
30903090
def kandqi : X86Builtin<"unsigned char(unsigned char, unsigned char)">;
30913091
}
30923092

3093-
let Features = "avx512f", Attributes = [NoThrow, Const] in {
3093+
let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in {
30943094
def kandhi : X86Builtin<"unsigned short(unsigned short, unsigned short)">;
30953095
}
30963096

3097-
let Features = "avx512bw", Attributes = [NoThrow, Const] in {
3097+
let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in {
30983098
def kandsi : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
30993099
def kanddi : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
31003100
}
31013101

3102-
let Features = "avx512dq", Attributes = [NoThrow, Const] in {
3102+
let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in {
31033103
def kandnqi : X86Builtin<"unsigned char(unsigned char, unsigned char)">;
31043104
}
31053105

3106-
let Features = "avx512f", Attributes = [NoThrow, Const] in {
3106+
let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in {
31073107
def kandnhi : X86Builtin<"unsigned short(unsigned short, unsigned short)">;
31083108
}
31093109

3110-
let Features = "avx512bw", Attributes = [NoThrow, Const] in {
3110+
let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in {
31113111
def kandnsi : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
31123112
def kandndi : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
31133113
}
31143114

3115-
let Features = "avx512dq", Attributes = [NoThrow, Const] in {
3115+
let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in {
31163116
def korqi : X86Builtin<"unsigned char(unsigned char, unsigned char)">;
31173117
}
31183118

3119-
let Features = "avx512f", Attributes = [NoThrow, Const] in {
3119+
let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in {
31203120
def korhi : X86Builtin<"unsigned short(unsigned short, unsigned short)">;
31213121
}
31223122

3123-
let Features = "avx512bw", Attributes = [NoThrow, Const] in {
3123+
let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in {
31243124
def korsi : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
31253125
def kordi : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
31263126
}
@@ -3160,28 +3160,28 @@ let Features = "avx512f", Attributes = [NoThrow, Const] in {
31603160
def kunpckhi : X86Builtin<"unsigned short(unsigned short, unsigned short)">;
31613161
}
31623162

3163-
let Features = "avx512dq", Attributes = [NoThrow, Const] in {
3163+
let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in {
31643164
def kxnorqi : X86Builtin<"unsigned char(unsigned char, unsigned char)">;
31653165
}
31663166

3167-
let Features = "avx512f", Attributes = [NoThrow, Const] in {
3167+
let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in {
31683168
def kxnorhi : X86Builtin<"unsigned short(unsigned short, unsigned short)">;
31693169
}
31703170

3171-
let Features = "avx512bw", Attributes = [NoThrow, Const] in {
3171+
let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in {
31723172
def kxnorsi : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
31733173
def kxnordi : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
31743174
}
31753175

3176-
let Features = "avx512dq", Attributes = [NoThrow, Const] in {
3176+
let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr] in {
31773177
def kxorqi : X86Builtin<"unsigned char(unsigned char, unsigned char)">;
31783178
}
31793179

3180-
let Features = "avx512f", Attributes = [NoThrow, Const] in {
3180+
let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr] in {
31813181
def kxorhi : X86Builtin<"unsigned short(unsigned short, unsigned short)">;
31823182
}
31833183

3184-
let Features = "avx512bw", Attributes = [NoThrow, Const] in {
3184+
let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr] in {
31853185
def kxorsi : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
31863186
def kxordi : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
31873187
}

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,16 @@ static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
666666
return true;
667667
}
668668

669+
static bool interp__builtin_knot(InterpState &S, CodePtr OpPC,
670+
const InterpFrame *Frame,
671+
const CallExpr *Call) {
672+
APSInt Val =
673+
popToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(0)->getType()));
674+
APInt Result = ~Val;
675+
pushInteger(S, APSInt(std::move(Result), true), Call->getType());
676+
return true;
677+
}
678+
669679
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC,
670680
const InterpFrame *Frame,
671681
const CallExpr *Call) {
@@ -3607,6 +3617,60 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
36073617
case X86::BI__builtin_ia32_selectpd_512:
36083618
return interp__builtin_select(S, OpPC, Call);
36093619

3620+
case X86::BI__builtin_ia32_kandqi:
3621+
case X86::BI__builtin_ia32_kandhi:
3622+
case X86::BI__builtin_ia32_kandsi:
3623+
case X86::BI__builtin_ia32_kanddi:
3624+
return interp__builtin_elementwise_int_binop(
3625+
S, OpPC, Call,
3626+
[](const APSInt &LHS, const APSInt &RHS) { return LHS & RHS; });
3627+
3628+
case X86::BI__builtin_ia32_kandnqi:
3629+
case X86::BI__builtin_ia32_kandnhi:
3630+
case X86::BI__builtin_ia32_kandnsi:
3631+
case X86::BI__builtin_ia32_kandndi:
3632+
return interp__builtin_elementwise_int_binop(
3633+
S, OpPC, Call,
3634+
[](const APSInt &LHS, const APSInt &RHS) { return ~LHS & RHS; });
3635+
3636+
case X86::BI__builtin_ia32_korqi:
3637+
case X86::BI__builtin_ia32_korhi:
3638+
case X86::BI__builtin_ia32_korsi:
3639+
case X86::BI__builtin_ia32_kordi:
3640+
return interp__builtin_elementwise_int_binop(
3641+
S, OpPC, Call,
3642+
[](const APSInt &LHS, const APSInt &RHS) { return LHS | RHS; });
3643+
3644+
case X86::BI__builtin_ia32_kxnorqi:
3645+
case X86::BI__builtin_ia32_kxnorhi:
3646+
case X86::BI__builtin_ia32_kxnorsi:
3647+
case X86::BI__builtin_ia32_kxnordi:
3648+
return interp__builtin_elementwise_int_binop(
3649+
S, OpPC, Call,
3650+
[](const APSInt &LHS, const APSInt &RHS) { return ~(LHS ^ RHS); });
3651+
3652+
case X86::BI__builtin_ia32_kxorqi:
3653+
case X86::BI__builtin_ia32_kxorhi:
3654+
case X86::BI__builtin_ia32_kxorsi:
3655+
case X86::BI__builtin_ia32_kxordi:
3656+
return interp__builtin_elementwise_int_binop(
3657+
S, OpPC, Call,
3658+
[](const APSInt &LHS, const APSInt &RHS) { return LHS ^ RHS; });
3659+
3660+
case X86::BI__builtin_ia32_knotqi:
3661+
case X86::BI__builtin_ia32_knothi:
3662+
case X86::BI__builtin_ia32_knotsi:
3663+
case X86::BI__builtin_ia32_knotdi:
3664+
return interp__builtin_knot(S, OpPC, Frame, Call);
3665+
3666+
case X86::BI__builtin_ia32_kaddqi:
3667+
case X86::BI__builtin_ia32_kaddhi:
3668+
case X86::BI__builtin_ia32_kaddsi:
3669+
case X86::BI__builtin_ia32_kadddi:
3670+
return interp__builtin_elementwise_int_binop(
3671+
S, OpPC, Call,
3672+
[](const APSInt &LHS, const APSInt &RHS) { return LHS + RHS; });
3673+
36103674
case Builtin::BI__builtin_elementwise_fshl:
36113675
return interp__builtin_elementwise_triop(S, OpPC, Call,
36123676
llvm::APIntOps::fshl);

clang/lib/AST/ExprConstant.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13588,6 +13588,20 @@ static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info,
1358813588

1358913589
bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1359013590
unsigned BuiltinOp) {
13591+
13592+
auto HandleMaskBinOp =
13593+
[&](llvm::function_ref<APSInt(const APSInt &, const APSInt &)> Fn)
13594+
-> bool {
13595+
APValue LHS, RHS;
13596+
if (!Evaluate(LHS, Info, E->getArg(0)) ||
13597+
!Evaluate(RHS, Info, E->getArg(1)))
13598+
return false;
13599+
13600+
APSInt ResultInt = Fn(LHS.getInt(), RHS.getInt());
13601+
13602+
return Success(APValue(ResultInt), E);
13603+
};
13604+
1359113605
switch (BuiltinOp) {
1359213606
default:
1359313607
return false;
@@ -14687,6 +14701,65 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1468714701
Result.setBitVal(P++, Val[I]);
1468814702
return Success(Result, E);
1468914703
}
14704+
14705+
case X86::BI__builtin_ia32_kandqi:
14706+
case X86::BI__builtin_ia32_kandhi:
14707+
case X86::BI__builtin_ia32_kandsi:
14708+
case X86::BI__builtin_ia32_kanddi: {
14709+
return HandleMaskBinOp(
14710+
[](const APSInt &LHS, const APSInt &RHS) { return LHS & RHS; });
14711+
}
14712+
14713+
case X86::BI__builtin_ia32_kandnqi:
14714+
case X86::BI__builtin_ia32_kandnhi:
14715+
case X86::BI__builtin_ia32_kandnsi:
14716+
case X86::BI__builtin_ia32_kandndi: {
14717+
return HandleMaskBinOp(
14718+
[](const APSInt &LHS, const APSInt &RHS) { return ~LHS & RHS; });
14719+
}
14720+
14721+
case X86::BI__builtin_ia32_korqi:
14722+
case X86::BI__builtin_ia32_korhi:
14723+
case X86::BI__builtin_ia32_korsi:
14724+
case X86::BI__builtin_ia32_kordi: {
14725+
return HandleMaskBinOp(
14726+
[](const APSInt &LHS, const APSInt &RHS) { return LHS | RHS; });
14727+
}
14728+
14729+
case X86::BI__builtin_ia32_kxnorqi:
14730+
case X86::BI__builtin_ia32_kxnorhi:
14731+
case X86::BI__builtin_ia32_kxnorsi:
14732+
case X86::BI__builtin_ia32_kxnordi: {
14733+
return HandleMaskBinOp(
14734+
[](const APSInt &LHS, const APSInt &RHS) { return ~(LHS ^ RHS); });
14735+
}
14736+
14737+
case X86::BI__builtin_ia32_kxorqi:
14738+
case X86::BI__builtin_ia32_kxorhi:
14739+
case X86::BI__builtin_ia32_kxorsi:
14740+
case X86::BI__builtin_ia32_kxordi: {
14741+
return HandleMaskBinOp(
14742+
[](const APSInt &LHS, const APSInt &RHS) { return LHS ^ RHS; });
14743+
}
14744+
14745+
case X86::BI__builtin_ia32_knotqi:
14746+
case X86::BI__builtin_ia32_knothi:
14747+
case X86::BI__builtin_ia32_knotsi:
14748+
case X86::BI__builtin_ia32_knotdi: {
14749+
APSInt Val;
14750+
if (!EvaluateInteger(E->getArg(0), Val, Info))
14751+
return false;
14752+
APSInt Result = ~Val;
14753+
return Success(APValue(Result), E);
14754+
}
14755+
14756+
case X86::BI__builtin_ia32_kaddqi:
14757+
case X86::BI__builtin_ia32_kaddhi:
14758+
case X86::BI__builtin_ia32_kaddsi:
14759+
case X86::BI__builtin_ia32_kadddi: {
14760+
return HandleMaskBinOp(
14761+
[](const APSInt &LHS, const APSInt &RHS) { return LHS + RHS; });
14762+
}
1469014763
}
1469114764
}
1469214765

clang/lib/Headers/avx512bwintrin.h

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,68 +32,63 @@ typedef unsigned long long __mmask64;
3232
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
3333
#endif
3434

35-
static __inline __mmask32 __DEFAULT_FN_ATTRS
36-
_knot_mask32(__mmask32 __M)
37-
{
35+
static __inline __mmask32
36+
__DEFAULT_FN_ATTRS_CONSTEXPR _knot_mask32(__mmask32 __M) {
3837
return __builtin_ia32_knotsi(__M);
3938
}
4039

41-
static __inline __mmask64 __DEFAULT_FN_ATTRS _knot_mask64(__mmask64 __M) {
40+
static __inline __mmask64 __DEFAULT_FN_ATTRS_CONSTEXPR
41+
_knot_mask64(__mmask64 __M) {
4242
return __builtin_ia32_knotdi(__M);
4343
}
4444

45-
static __inline__ __mmask32 __DEFAULT_FN_ATTRS
46-
_kand_mask32(__mmask32 __A, __mmask32 __B)
47-
{
45+
static __inline__ __mmask32 __DEFAULT_FN_ATTRS_CONSTEXPR
46+
_kand_mask32(__mmask32 __A, __mmask32 __B) {
4847
return (__mmask32)__builtin_ia32_kandsi((__mmask32)__A, (__mmask32)__B);
4948
}
5049

51-
static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kand_mask64(__mmask64 __A,
52-
__mmask64 __B) {
50+
static __inline__ __mmask64 __DEFAULT_FN_ATTRS_CONSTEXPR
51+
_kand_mask64(__mmask64 __A, __mmask64 __B) {
5352
return (__mmask64)__builtin_ia32_kanddi((__mmask64)__A, (__mmask64)__B);
5453
}
5554

56-
static __inline__ __mmask32 __DEFAULT_FN_ATTRS
57-
_kandn_mask32(__mmask32 __A, __mmask32 __B)
58-
{
55+
static __inline__ __mmask32 __DEFAULT_FN_ATTRS_CONSTEXPR
56+
_kandn_mask32(__mmask32 __A, __mmask32 __B) {
5957
return (__mmask32)__builtin_ia32_kandnsi((__mmask32)__A, (__mmask32)__B);
6058
}
6159

62-
static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kandn_mask64(__mmask64 __A,
63-
__mmask64 __B) {
60+
static __inline__ __mmask64 __DEFAULT_FN_ATTRS_CONSTEXPR
61+
_kandn_mask64(__mmask64 __A, __mmask64 __B) {
6462
return (__mmask64)__builtin_ia32_kandndi((__mmask64)__A, (__mmask64)__B);
6563
}
6664

67-
static __inline__ __mmask32 __DEFAULT_FN_ATTRS
68-
_kor_mask32(__mmask32 __A, __mmask32 __B)
69-
{
65+
static __inline__ __mmask32 __DEFAULT_FN_ATTRS_CONSTEXPR
66+
_kor_mask32(__mmask32 __A, __mmask32 __B) {
7067
return (__mmask32)__builtin_ia32_korsi((__mmask32)__A, (__mmask32)__B);
7168
}
7269

73-
static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kor_mask64(__mmask64 __A,
74-
__mmask64 __B) {
70+
static __inline__ __mmask64 __DEFAULT_FN_ATTRS_CONSTEXPR
71+
_kor_mask64(__mmask64 __A, __mmask64 __B) {
7572
return (__mmask64)__builtin_ia32_kordi((__mmask64)__A, (__mmask64)__B);
7673
}
7774

78-
static __inline__ __mmask32 __DEFAULT_FN_ATTRS
79-
_kxnor_mask32(__mmask32 __A, __mmask32 __B)
80-
{
75+
static __inline__ __mmask32 __DEFAULT_FN_ATTRS_CONSTEXPR
76+
_kxnor_mask32(__mmask32 __A, __mmask32 __B) {
8177
return (__mmask32)__builtin_ia32_kxnorsi((__mmask32)__A, (__mmask32)__B);
8278
}
8379

84-
static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kxnor_mask64(__mmask64 __A,
85-
__mmask64 __B) {
80+
static __inline__ __mmask64 __DEFAULT_FN_ATTRS_CONSTEXPR
81+
_kxnor_mask64(__mmask64 __A, __mmask64 __B) {
8682
return (__mmask64)__builtin_ia32_kxnordi((__mmask64)__A, (__mmask64)__B);
8783
}
8884

89-
static __inline__ __mmask32 __DEFAULT_FN_ATTRS
90-
_kxor_mask32(__mmask32 __A, __mmask32 __B)
91-
{
85+
static __inline__ __mmask32 __DEFAULT_FN_ATTRS_CONSTEXPR
86+
_kxor_mask32(__mmask32 __A, __mmask32 __B) {
9287
return (__mmask32)__builtin_ia32_kxorsi((__mmask32)__A, (__mmask32)__B);
9388
}
9489

95-
static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kxor_mask64(__mmask64 __A,
96-
__mmask64 __B) {
90+
static __inline__ __mmask64 __DEFAULT_FN_ATTRS_CONSTEXPR
91+
_kxor_mask64(__mmask64 __A, __mmask64 __B) {
9792
return (__mmask64)__builtin_ia32_kxordi((__mmask64)__A, (__mmask64)__B);
9893
}
9994

@@ -165,14 +160,13 @@ _ktest_mask64_u8(__mmask64 __A, __mmask64 __B, unsigned char *__C) {
165160
return (unsigned char)__builtin_ia32_ktestzdi(__A, __B);
166161
}
167162

168-
static __inline__ __mmask32 __DEFAULT_FN_ATTRS
169-
_kadd_mask32(__mmask32 __A, __mmask32 __B)
170-
{
163+
static __inline__ __mmask32 __DEFAULT_FN_ATTRS_CONSTEXPR
164+
_kadd_mask32(__mmask32 __A, __mmask32 __B) {
171165
return (__mmask32)__builtin_ia32_kaddsi((__mmask32)__A, (__mmask32)__B);
172166
}
173167

174-
static __inline__ __mmask64 __DEFAULT_FN_ATTRS _kadd_mask64(__mmask64 __A,
175-
__mmask64 __B) {
168+
static __inline__ __mmask64 __DEFAULT_FN_ATTRS_CONSTEXPR
169+
_kadd_mask64(__mmask64 __A, __mmask64 __B) {
176170
return (__mmask64)__builtin_ia32_kadddi((__mmask64)__A, (__mmask64)__B);
177171
}
178172

0 commit comments

Comments
 (0)