-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] constexpr built-in reduce mul function. #116626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: None (c8ef) ChangesPart of #51787. This patch adds constexpr support for the built-in reduce mul function. Full diff: https://github.com/llvm/llvm-project/pull/116626.diff 4 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2bd67138ecc048..af0c7f41baa3e7 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -356,6 +356,7 @@ Non-comprehensive list of changes in this release
issues with the sanitizer because the counter is automatically set.
- ``__builtin_reduce_add`` function can now be used in constant expressions.
+- ``__builtin_reduce_mul`` 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 f5124f4633364f..f9c36bd64943db 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1510,7 +1510,7 @@ def ReduceAdd : Builtin {
def ReduceMul : Builtin {
let Spellings = ["__builtin_reduce_mul"];
- 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 833b99bf1bd9f1..f597f05807069c 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13527,7 +13527,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return Success(DidOverflow, E);
}
- case Builtin::BI__builtin_reduce_add: {
+ case Builtin::BI__builtin_reduce_add:
+ case Builtin::BI__builtin_reduce_mul: {
APValue Source;
if (!EvaluateAsRValue(Info, E->getArg(0), Source))
return false;
@@ -13535,10 +13536,24 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
unsigned SourceLen = Source.getVectorLength();
APSInt Reduced = Source.getVectorElt(0).getInt();
for (unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
- if (!CheckedIntArithmetic(
- Info, E, Reduced, Source.getVectorElt(EltNum).getInt(),
- Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
+ switch (BuiltinOp) {
+ default:
return false;
+ case Builtin::BI__builtin_reduce_add: {
+ if (!CheckedIntArithmetic(
+ Info, E, Reduced, Source.getVectorElt(EltNum).getInt(),
+ Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
+ return false;
+ break;
+ }
+ case Builtin::BI__builtin_reduce_mul: {
+ if (!CheckedIntArithmetic(
+ Info, E, Reduced, Source.getVectorElt(EltNum).getInt(),
+ Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
+ return false;
+ break;
+ }
+ }
}
return Success(Reduced, E);
diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp
index d15c587cfffc49..b9dc17f73f7a92 100644
--- a/clang/test/Sema/constant_builtins_vector.cpp
+++ b/clang/test/Sema/constant_builtins_vector.cpp
@@ -745,3 +745,23 @@ constexpr long long reduceAddLong2 = __builtin_reduce_add((vector4long){(1LL <<
// 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);
+
+static_assert(__builtin_reduce_mul((vector4char){}) == 0);
+static_assert(__builtin_reduce_mul((vector4char){1, 2, 3, 4}) == 24);
+static_assert(__builtin_reduce_mul((vector4short){1, 2, 30, 40}) == 2400);
+static_assert(__builtin_reduce_mul((vector4int){10, 20, 300, 400}) == 24000000);
+static_assert(__builtin_reduce_mul((vector4long){1000L, 2000L, 3000L, 4000L}) == 24000000000000L);
+constexpr int reduceMulInt1 = __builtin_reduce_mul((vector4int){~(1 << 31), 1, 1, 2});
+// 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 reduceMulLong1 = __builtin_reduce_mul((vector4long){~(1LL << 63), 1, 1, 2});
+// 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 reduceMulInt2 = __builtin_reduce_mul((vector4int){(1 << 31), 1, 1, 2});
+// 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 reduceMulLong2 = __builtin_reduce_mul((vector4long){(1LL << 63), 1, 1, 2});
+// 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_mul((vector4uint){~0U, 1, 1, 2}) == ~0U - 1);
+static_assert(__builtin_reduce_mul((vector4ulong){~0ULL, 1, 1, 2}) == ~0ULL - 1);
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - cheers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Part of #51787.
Follow up of #116243.
This patch adds constexpr support for the built-in reduce mul function.