https://github.com/c8ef updated https://github.com/llvm/llvm-project/pull/116243
>From b2f4d35d33684381648ef6662cf9f943b90e146e Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Thu, 14 Nov 2024 15:11:00 +0000 Subject: [PATCH 1/3] constexpr reduce_add --- clang/docs/ReleaseNotes.rst | 2 ++ clang/include/clang/Basic/Builtins.td | 2 +- clang/lib/AST/ExprConstant.cpp | 14 ++++++++++++++ clang/test/Sema/constant_builtins_vector.cpp | 6 ++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 78ba70c624d18c..2bc2bda663168e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -353,6 +353,8 @@ Non-comprehensive list of changes in this release The flexible array member (FAM) can now be accessed immediately without causing issues with the sanitizer because the counter is automatically set. +- ``__builtin_reduce_add`` 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 e866605ac05c09..a17e1353b2e1b4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -1504,7 +1504,7 @@ def ReduceAnd : Builtin { def ReduceAdd : Builtin { let Spellings = ["__builtin_reduce_add"]; - 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 d664c503655ba6..e9fb3b4b00d164 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13528,6 +13528,20 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, return Success(DidOverflow, E); } + case Builtin::BI__builtin_reduce_add: { + APValue Source; + if (!EvaluateAsRValue(Info, E->getArg(0), Source)) + return false; + + auto SourceLen = Source.getVectorLength(); + APSInt Reduced = Source.getVectorElt(0).getInt(); + for (unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) { + Reduced += Source.getVectorElt(EltNum).getInt(); + } + + return Success(Reduced, E); + } + case clang::X86::BI__builtin_ia32_addcarryx_u32: case clang::X86::BI__builtin_ia32_addcarryx_u64: case clang::X86::BI__builtin_ia32_subborrow_u32: diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp index c6b1b37cef28b4..6d2db6e5111eff 100644 --- a/clang/test/Sema/constant_builtins_vector.cpp +++ b/clang/test/Sema/constant_builtins_vector.cpp @@ -723,3 +723,9 @@ not within the bounds of the input vectors; index of -1 found at position 0 is n permitted in a constexpr context}} vector4charConst1, vector4charConst2, -1, -1, -1, -1); + +static_assert(__builtin_reduce_add((vector4char){}) == 0); +static_assert(__builtin_reduce_add((vector4char){1, 2, 3, 4}) == 10); +static_assert(__builtin_reduce_add((vector4short){10, 20, 30, 40}) == 100); +static_assert(__builtin_reduce_add((vector4int){100, 200, 300, 400}) == 1000); +static_assert(__builtin_reduce_add((vector4long){1000, 2000, 3000, 4000}) == 10000); >From e02f44306a42b55f48927f2d5cdd12a4e278b537 Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Fri, 15 Nov 2024 11:45:30 +0000 Subject: [PATCH 2/3] address review comments --- clang/lib/AST/ExprConstant.cpp | 8 ++++++-- clang/test/Sema/constant_builtins_vector.cpp | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index e9fb3b4b00d164..d924ca442076ca 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13533,10 +13533,14 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, if (!EvaluateAsRValue(Info, E->getArg(0), Source)) return false; - auto SourceLen = Source.getVectorLength(); + unsigned SourceLen = Source.getVectorLength(); APSInt Reduced = Source.getVectorElt(0).getInt(); for (unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) { - Reduced += Source.getVectorElt(EltNum).getInt(); + if (!CheckedIntArithmetic( + Info, E, Reduced, Source.getVectorElt(EltNum).getInt(), + Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced)) { + return false; + } } return Success(Reduced, E); diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp index 6d2db6e5111eff..72aaba4d29c419 100644 --- a/clang/test/Sema/constant_builtins_vector.cpp +++ b/clang/test/Sema/constant_builtins_vector.cpp @@ -729,3 +729,15 @@ static_assert(__builtin_reduce_add((vector4char){1, 2, 3, 4}) == 10); static_assert(__builtin_reduce_add((vector4short){10, 20, 30, 40}) == 100); static_assert(__builtin_reduce_add((vector4int){100, 200, 300, 400}) == 1000); static_assert(__builtin_reduce_add((vector4long){1000, 2000, 3000, 4000}) == 10000); +constexpr int reduceAddInt1 = __builtin_reduce_add((vector4int){~(1 << 31), 0, 0, 1}); +// expected-error@-1 {{must be initialized by a constant expression}} \ +// expected-note@-1 {{outside the range of representable values of type 'int'}} +constexpr long long reduceAddLong1 = __builtin_reduce_add((vector4long){~(1LL << 63), 0, 0, 1}); +// expected-error@-1 {{must be initialized by a constant expression}} \ +// expected-note@-1 {{outside the range of representable values of type 'long long'}} +constexpr int reduceAddInt2 = __builtin_reduce_add((vector4int){(1 << 31), 0, 0, -1}); +// expected-error@-1 {{must be initialized by a constant expression}} \ +// expected-note@-1 {{outside the range of representable values of type 'int'}} +constexpr long long reduceAddLong2 = __builtin_reduce_add((vector4long){(1LL << 63), 0, 0, -1}); +// expected-error@-1 {{must be initialized by a constant expression}} \ +// expected-note@-1 {{outside the range of representable values of type 'long long'}} >From a7d242bf45021a610c749be74ce46c199231b35c Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Fri, 15 Nov 2024 11:52:35 +0000 Subject: [PATCH 3/3] add more test --- clang/test/Sema/constant_builtins_vector.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp index 72aaba4d29c419..d15c587cfffc49 100644 --- a/clang/test/Sema/constant_builtins_vector.cpp +++ b/clang/test/Sema/constant_builtins_vector.cpp @@ -19,6 +19,8 @@ typedef double vector4double __attribute__((__vector_size__(32))); typedef float vector4float __attribute__((__vector_size__(16))); typedef long long vector4long __attribute__((__vector_size__(32))); typedef int vector4int __attribute__((__vector_size__(16))); +typedef unsigned long long vector4ulong __attribute__((__vector_size__(32))); +typedef unsigned int vector4uint __attribute__((__vector_size__(16))); typedef short vector4short __attribute__((__vector_size__(8))); typedef char vector4char __attribute__((__vector_size__(4))); typedef BitInt8 vector4BitInt8 __attribute__((__vector_size__(4))); @@ -741,3 +743,5 @@ constexpr int reduceAddInt2 = __builtin_reduce_add((vector4int){(1 << 31), 0, 0, constexpr long long reduceAddLong2 = __builtin_reduce_add((vector4long){(1LL << 63), 0, 0, -1}); // expected-error@-1 {{must be initialized by a constant expression}} \ // expected-note@-1 {{outside the range of representable values of type 'long long'}} +static_assert(__builtin_reduce_add((vector4uint){~0U, 0, 0, 1}) == 0); +static_assert(__builtin_reduce_add((vector4ulong){~0ULL, 0, 0, 1}) == 0); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits