https://github.com/c8ef updated https://github.com/llvm/llvm-project/pull/117473
>From 95f2b6b0742b9b5b675f5d2f24aa4eb90c03b18c Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Sun, 24 Nov 2024 18:14:51 +0800 Subject: [PATCH 1/6] constexpr elementwise popcount --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/Basic/Builtins.td | 2 +- clang/lib/AST/ExprConstant.cpp | 27 ++++++++++++++++++++ clang/test/Sema/constant_builtins_vector.cpp | 5 ++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8bd06fadfdc984..16a151da38bb5d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -370,6 +370,7 @@ Non-comprehensive list of changes in this release - ``__builtin_reduce_mul`` function can now be used in constant expressions. - ``__builtin_reduce_and`` function can now be used in constant expressions. - ``__builtin_reduce_or`` and ``__builtin_reduce_xor`` functions can now be used in constant expressions. +- ``__builtin_elementwise_popcount`` function can now be used in constant expressions. New Compiler Flags ------------------ diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 83c90b3d6e681b..246250442ef62c 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -1354,7 +1354,7 @@ def ElementwiseLog10 : Builtin { def ElementwisePopcount : Builtin { let Spellings = ["__builtin_elementwise_popcount"]; - let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; let Prototype = "void(...)"; } diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index c6a210459240a8..bdd056d0618c6d 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11005,6 +11005,7 @@ namespace { bool VisitUnaryImag(const UnaryOperator *E); bool VisitBinaryOperator(const BinaryOperator *E); bool VisitUnaryOperator(const UnaryOperator *E); + bool VisitCallExpr(const CallExpr *E); bool VisitConvertVectorExpr(const ConvertVectorExpr *E); bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E); @@ -11302,6 +11303,32 @@ static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, return false; } +bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { + switch (E->getBuiltinCallee()) { + default: + return false; + case Builtin::BI__builtin_elementwise_popcount: { + APValue Source; + if (!EvaluateAsRValue(Info, E->getArg(0), Source)) + return false; + + QualType DestTy = E->getType()->castAs<VectorType>()->getElementType(); + unsigned SourceLen = Source.getVectorLength(); + SmallVector<APValue, 4> ResultElements; + ResultElements.reserve(SourceLen); + + for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) { + APSInt Elt = Source.getVectorElt(EltNum).getInt(); + ResultElements.push_back( + APValue(APSInt(APInt(Info.Ctx.getIntWidth(DestTy), Elt.popcount()), + DestTy->isUnsignedIntegerOrEnumerationType()))); + } + + return Success(APValue(ResultElements.data(), ResultElements.size()), E); + } + } +} + bool VectorExprEvaluator::VisitConvertVectorExpr(const ConvertVectorExpr *E) { APValue Source; QualType SourceVecType = E->getSrcExpr()->getType(); diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp index e84d09b24672b4..76d8bdfda3690a 100644 --- a/clang/test/Sema/constant_builtins_vector.cpp +++ b/clang/test/Sema/constant_builtins_vector.cpp @@ -797,3 +797,8 @@ static_assert(__builtin_reduce_xor((vector4int){(int)0x11111111, (int)0x22222222 static_assert(__builtin_reduce_xor((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0xFFFFFFFFFFFFFFFFL); static_assert(__builtin_reduce_xor((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0xFFFFFFFFU); static_assert(__builtin_reduce_xor((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0xFFFFFFFFFFFFFFFFUL); + +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){1, 2, 3, 4})) == 5); +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){0, 0xF0F0, ~0, ~0xF0F0})) == 16 * sizeof(int)); +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){1L, 2L, 3L, 4L})) == 5L); +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){0L, 0xF0F0L, ~0L, ~0xF0F0L})) == 16 * sizeof(long long)); >From 316f6085fb129de24da3297c1bd8b110d763b23d Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Sun, 24 Nov 2024 18:27:55 +0800 Subject: [PATCH 2/6] fix bug --- clang/lib/AST/ExprConstant.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index bdd056d0618c6d..8a3ced30be9440 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11304,6 +11304,9 @@ static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, } bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { + if (!IsConstantEvaluatedBuiltinCall(E)) + return ExprEvaluatorBaseTy::VisitCallExpr(E); + switch (E->getBuiltinCallee()) { default: return false; >From 5dba71fda1a412c2e610fb0a2ce05102dba84c1e Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Sun, 24 Nov 2024 23:31:26 +0800 Subject: [PATCH 3/6] fix bug; add more test cases --- clang/lib/AST/ExprConstant.cpp | 1 + clang/test/Sema/constant_builtins_vector.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 8a3ced30be9440..323a371fe957db 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13148,6 +13148,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, case Builtin::BI__builtin_popcountl: case Builtin::BI__builtin_popcountll: case Builtin::BI__builtin_popcountg: + case Builtin::BI__builtin_elementwise_popcount: case Builtin::BI__popcnt16: // Microsoft variants of popcount case Builtin::BI__popcnt: case Builtin::BI__popcnt64: { diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp index 76d8bdfda3690a..29149b01c236e3 100644 --- a/clang/test/Sema/constant_builtins_vector.cpp +++ b/clang/test/Sema/constant_builtins_vector.cpp @@ -802,3 +802,16 @@ static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){1 static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){0, 0xF0F0, ~0, ~0xF0F0})) == 16 * sizeof(int)); static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){1L, 2L, 3L, 4L})) == 5L); static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){0L, 0xF0F0L, ~0L, ~0xF0F0L})) == 16 * sizeof(long long)); +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4uint){1U, 2U, 3U, 4U})) == 5U); +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4uint){0U, 0xF0F0U, ~0U, ~0xF0F0U})) == 16 * sizeof(int)); +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4ulong){1UL, 2UL, 3UL, 4UL})) == 5L); +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4ulong){0UL, 0xF0F0UL, ~0UL, ~0xF0F0UL})) == 16 * sizeof(long long)); +static_assert(__builtin_elementwise_popcount(0) == 0); +static_assert(__builtin_elementwise_popcount(0xF0F0) == 8); +static_assert(__builtin_elementwise_popcount(~0) == 8 * sizeof(int)); +static_assert(__builtin_elementwise_popcount(0U) == 0); +static_assert(__builtin_elementwise_popcount(0xF0F0U) == 8); +static_assert(__builtin_elementwise_popcount(~0U) == 8 * sizeof(int)); +static_assert(__builtin_elementwise_popcount(0L) == 0); +static_assert(__builtin_elementwise_popcount(0xF0F0L) == 8); +static_assert(__builtin_elementwise_popcount(~0LL) == 8 * sizeof(long long)); >From 60216a46a3c332f084aaa2acbb71522725960b6b Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Sun, 24 Nov 2024 23:48:21 +0800 Subject: [PATCH 4/6] fix test --- .../test/CodeGen/builtins-elementwise-math.c | 30 ++----------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/clang/test/CodeGen/builtins-elementwise-math.c b/clang/test/CodeGen/builtins-elementwise-math.c index 748b5e4add7c76..a9e10f77d906fb 100644 --- a/clang/test/CodeGen/builtins-elementwise-math.c +++ b/clang/test/CodeGen/builtins-elementwise-math.c @@ -666,40 +666,16 @@ void test_builtin_elementwise_log2(float f1, float f2, double d1, double d2, vf2 = __builtin_elementwise_log2(vf1); } -void test_builtin_elementwise_popcount(si8 vi1, si8 vi2, - long long int i1, long long int i2, short si, - _BitInt(31) bi1, _BitInt(31) bi2) { - - - // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 - // CHECK-NEXT: call i64 @llvm.ctpop.i64(i64 [[I1]]) +void test_builtin_elementwise_popcount(si8 vi1, si8 vi2, long long int i1, + long long int i2, short si, + _BitInt(31) bi1, _BitInt(31) bi2) { i2 = __builtin_elementwise_popcount(i1); - - // CHECK: [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16 - // CHECK-NEXT: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> [[VI1]]) vi2 = __builtin_elementwise_popcount(vi1); - - // CHECK: [[CVI2:%.+]] = load <8 x i16>, ptr %cvi2, align 16 - // CHECK-NEXT: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> [[CVI2]]) const si8 cvi2 = vi2; vi2 = __builtin_elementwise_popcount(cvi2); - - // CHECK: [[BI1:%.+]] = load i32, ptr %bi1.addr, align 4 - // CHECK-NEXT: [[LOADEDV:%.+]] = trunc i32 [[BI1]] to i31 - // CHECK-NEXT: call i31 @llvm.ctpop.i31(i31 [[LOADEDV]]) bi2 = __builtin_elementwise_popcount(bi1); - - // CHECK: [[IA1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4 - // CHECK-NEXT: call i32 @llvm.ctpop.i32(i32 [[IA1]]) b = __builtin_elementwise_popcount(int_as_one); - - // CHECK: call i32 @llvm.ctpop.i32(i32 -10) b = __builtin_elementwise_popcount(-10); - - // CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2 - // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32 - // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.ctpop.i32(i32 [[SI_EXT]]) - // CHECK-NEXT: = trunc i32 [[RES]] to i16 si = __builtin_elementwise_popcount(si); } >From 6ec9aa51e5256caae9030aca347ed74f04140578 Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Mon, 25 Nov 2024 00:39:05 +0800 Subject: [PATCH 5/6] fix test --- clang/test/Sema/constant_builtins_vector.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp index 29149b01c236e3..672cb1b4387beb 100644 --- a/clang/test/Sema/constant_builtins_vector.cpp +++ b/clang/test/Sema/constant_builtins_vector.cpp @@ -804,8 +804,8 @@ static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){ static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){0L, 0xF0F0L, ~0L, ~0xF0F0L})) == 16 * sizeof(long long)); static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4uint){1U, 2U, 3U, 4U})) == 5U); static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4uint){0U, 0xF0F0U, ~0U, ~0xF0F0U})) == 16 * sizeof(int)); -static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4ulong){1UL, 2UL, 3UL, 4UL})) == 5L); -static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4ulong){0UL, 0xF0F0UL, ~0UL, ~0xF0F0UL})) == 16 * sizeof(long long)); +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4ulong){1UL, 2UL, 3UL, 4UL})) == 5UL); +static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4ulong){0ULL, 0xF0F0ULL, ~0ULL, ~0xF0F0ULL})) == 16 * sizeof(unsigned long long)); static_assert(__builtin_elementwise_popcount(0) == 0); static_assert(__builtin_elementwise_popcount(0xF0F0) == 8); static_assert(__builtin_elementwise_popcount(~0) == 8 * sizeof(int)); >From af8ef3ac364c91c47196cd50d19c5cf07c275193 Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Mon, 25 Nov 2024 22:51:19 +0800 Subject: [PATCH 6/6] address review comments --- clang/lib/AST/ExprConstant.cpp | 6 ++--- .../test/CodeGen/builtins-elementwise-math.c | 22 +++++++++++++++++++ clang/test/Sema/constant_builtins_vector.cpp | 2 ++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 323a371fe957db..06cb433eaecf2c 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11315,7 +11315,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { if (!EvaluateAsRValue(Info, E->getArg(0), Source)) return false; - QualType DestTy = E->getType()->castAs<VectorType>()->getElementType(); + QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType(); unsigned SourceLen = Source.getVectorLength(); SmallVector<APValue, 4> ResultElements; ResultElements.reserve(SourceLen); @@ -11323,8 +11323,8 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) { APSInt Elt = Source.getVectorElt(EltNum).getInt(); ResultElements.push_back( - APValue(APSInt(APInt(Info.Ctx.getIntWidth(DestTy), Elt.popcount()), - DestTy->isUnsignedIntegerOrEnumerationType()))); + APValue(APSInt(APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()), + DestEltTy->isUnsignedIntegerOrEnumerationType()))); } return Success(APValue(ResultElements.data(), ResultElements.size()), E); diff --git a/clang/test/CodeGen/builtins-elementwise-math.c b/clang/test/CodeGen/builtins-elementwise-math.c index a9e10f77d906fb..f1f34432ca0ea1 100644 --- a/clang/test/CodeGen/builtins-elementwise-math.c +++ b/clang/test/CodeGen/builtins-elementwise-math.c @@ -669,13 +669,35 @@ void test_builtin_elementwise_log2(float f1, float f2, double d1, double d2, void test_builtin_elementwise_popcount(si8 vi1, si8 vi2, long long int i1, long long int i2, short si, _BitInt(31) bi1, _BitInt(31) bi2) { + // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 + // CHECK-NEXT: call i64 @llvm.ctpop.i64(i64 [[I1]]) i2 = __builtin_elementwise_popcount(i1); + + // CHECK: [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16 + // CHECK-NEXT: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> [[VI1]]) vi2 = __builtin_elementwise_popcount(vi1); + + // CHECK: [[CVI2:%.+]] = load <8 x i16>, ptr %cvi2, align 16 + // CHECK-NEXT: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> [[CVI2]]) const si8 cvi2 = vi2; vi2 = __builtin_elementwise_popcount(cvi2); + + // CHECK: [[BI1:%.+]] = load i32, ptr %bi1.addr, align 4 + // CHECK-NEXT: [[LOADEDV:%.+]] = trunc i32 [[BI1]] to i31 + // CHECK-NEXT: call i31 @llvm.ctpop.i31(i31 [[LOADEDV]]) bi2 = __builtin_elementwise_popcount(bi1); + + // CHECK: [[IA1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4 + // CHECK-NEXT: call i32 @llvm.ctpop.i32(i32 [[IA1]]) b = __builtin_elementwise_popcount(int_as_one); + + // CHECK: store i32 30, ptr @b, align 4 b = __builtin_elementwise_popcount(-10); + + // CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2 + // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32 + // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.ctpop.i32(i32 [[SI_EXT]]) + // CHECK-NEXT: = trunc i32 [[RES]] to i16 si = __builtin_elementwise_popcount(si); } diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp index 672cb1b4387beb..2bfc0fbe226dfe 100644 --- a/clang/test/Sema/constant_builtins_vector.cpp +++ b/clang/test/Sema/constant_builtins_vector.cpp @@ -798,6 +798,8 @@ static_assert(__builtin_reduce_xor((vector4long){(long long)0x1111111111111111L, static_assert(__builtin_reduce_xor((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0xFFFFFFFFU); static_assert(__builtin_reduce_xor((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0xFFFFFFFFFFFFFFFFUL); +static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_popcount((vector4char){1, 2, 3, 4})) == (LITTLE_END ? 0x01020101 : 0x01010201)); +static_assert(__builtin_bit_cast(unsigned long, __builtin_elementwise_popcount((vector4short){0, 0x0F0F, ~0, ~0x0F0F})) == (LITTLE_END ? 0x0008001000080000 : 0x0000000800100008)); static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){1, 2, 3, 4})) == 5); static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){0, 0xF0F0, ~0, ~0xF0F0})) == 16 * sizeof(int)); static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){1L, 2L, 3L, 4L})) == 5L); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits