[clang] b03a747 - [clang] constexpr built-in reduce mul function. (#116626)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 19 04:47:45 PST 2024
Author: c8ef
Date: 2024-11-19T20:47:42+08:00
New Revision: b03a747fc0fc27ddcad3b50f2117d8150ee262f1
URL: https://github.com/llvm/llvm-project/commit/b03a747fc0fc27ddcad3b50f2117d8150ee262f1
DIFF: https://github.com/llvm/llvm-project/commit/b03a747fc0fc27ddcad3b50f2117d8150ee262f1.diff
LOG: [clang] constexpr built-in reduce mul function. (#116626)
Part of #51787.
Follow up of #116243.
This patch adds constexpr support for the built-in reduce mul function.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/Builtins.td
clang/lib/AST/ExprConstant.cpp
clang/test/Sema/constant_builtins_vector.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4514f9f591ffa4..6cdd7f0cdf46cc 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 191dfa1dd2c77c..83e5b52b4e3a9e 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 at -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 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 reduceMulLong1 = __builtin_reduce_mul((vector4long){~(1LL << 63), 1, 1, 2});
+// 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 reduceMulInt2 = __builtin_reduce_mul((vector4int){(1 << 31), 1, 1, 2});
+// 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 reduceMulLong2 = __builtin_reduce_mul((vector4long){(1LL << 63), 1, 1, 2});
+// 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'}}
+static_assert(__builtin_reduce_mul((vector4uint){~0U, 1, 1, 2}) == ~0U - 1);
+static_assert(__builtin_reduce_mul((vector4ulong){~0ULL, 1, 1, 2}) == ~0ULL - 1);
More information about the cfe-commits
mailing list