[clang] [clang] constexpr built-in reduce add function. (PR #116243)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 15 03:45:41 PST 2024
https://github.com/c8ef updated https://github.com/llvm/llvm-project/pull/116243
>From b2f4d35d33684381648ef6662cf9f943b90e146e Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Thu, 14 Nov 2024 15:11:00 +0000
Subject: [PATCH 1/2] 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 <c8ef at outlook.com>
Date: Fri, 15 Nov 2024 11:45:30 +0000
Subject: [PATCH 2/2] 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 at -1 {{must be initialized by a constant expression}} \
+// expected-note at -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 at -1 {{must be initialized by a constant expression}} \
+// expected-note at -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 at -1 {{must be initialized by a constant expression}} \
+// expected-note at -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 at -1 {{must be initialized by a constant expression}} \
+// expected-note at -1 {{outside the range of representable values of type 'long long'}}
More information about the cfe-commits
mailing list