[clang] [clang] constexpr built-in reduce min/max function. (PR #120866)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Dec 22 03:49:04 PST 2024
https://github.com/c8ef updated https://github.com/llvm/llvm-project/pull/120866
>From 4e16d47641bd02203753752636f1fe90182552e9 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 22 Dec 2024 11:08:43 +0800
Subject: [PATCH 1/2] constexpr reduce min/max
---
clang/docs/LanguageExtensions.rst | 7 ++++---
clang/docs/ReleaseNotes.rst | 3 ++-
clang/include/clang/Basic/Builtins.td | 4 ++--
clang/lib/AST/ExprConstant.cpp | 12 +++++++++++-
clang/test/Sema/constant_builtins_vector.cpp | 15 +++++++++++++++
5 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 3d4f68b818bce7..cc5f1d4ddf4477 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -736,9 +736,10 @@ at the end to the next power of 2.
These reductions support both fixed-sized and scalable vector types.
-The integer reduction intrinsics, including ``__builtin_reduce_add``,
-``__builtin_reduce_mul``, ``__builtin_reduce_and``, ``__builtin_reduce_or``,
-and ``__builtin_reduce_xor``, can be called in a ``constexpr`` context.
+The integer reduction intrinsics, including ``__builtin_reduce_max``,
+``__builtin_reduce_min``, ``__builtin_reduce_add``, ``__builtin_reduce_mul``,
+``__builtin_reduce_and``, ``__builtin_reduce_or``, and ``__builtin_reduce_xor``,
+can be called in a ``constexpr`` context.
Example:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6b9e1109f3906e..8b984ecaefecaf 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -421,7 +421,8 @@ Non-comprehensive list of changes in this release
``__builtin_reduce_mul``, ``__builtin_reduce_and``, ``__builtin_reduce_or``,
``__builtin_reduce_xor``, ``__builtin_elementwise_popcount``,
``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``,
- ``__builtin_elementwise_sub_sat``.
+ ``__builtin_elementwise_sub_sat``, ``__builtin_reduce_min`` (For integral element type),
+ ``__builtin_reduce_max`` (For integral element type).
- Clang now rejects ``_BitInt`` matrix element types if the bit width is less than ``CHAR_WIDTH`` or
not a power of two, matching preexisting behaviour for vector types.
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index d64a66fc9d9cf7..b5b47ae2746011 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1462,13 +1462,13 @@ def ElementwiseSubSat : Builtin {
def ReduceMax : Builtin {
let Spellings = ["__builtin_reduce_max"];
- let Attributes = [NoThrow, Const, CustomTypeChecking];
+ let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}
def ReduceMin : Builtin {
let Spellings = ["__builtin_reduce_min"];
- 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 89c515e6392764..dd75dca647540a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13604,7 +13604,9 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
case Builtin::BI__builtin_reduce_mul:
case Builtin::BI__builtin_reduce_and:
case Builtin::BI__builtin_reduce_or:
- case Builtin::BI__builtin_reduce_xor: {
+ case Builtin::BI__builtin_reduce_xor:
+ case Builtin::BI__builtin_reduce_min:
+ case Builtin::BI__builtin_reduce_max: {
APValue Source;
if (!EvaluateAsRValue(Info, E->getArg(0), Source))
return false;
@@ -13641,6 +13643,14 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
Reduced ^= Source.getVectorElt(EltNum).getInt();
break;
}
+ case Builtin::BI__builtin_reduce_min: {
+ Reduced = std::min(Reduced, Source.getVectorElt(EltNum).getInt());
+ break;
+ }
+ case Builtin::BI__builtin_reduce_max: {
+ Reduced = std::max(Reduced, Source.getVectorElt(EltNum).getInt());
+ break;
+ }
}
}
diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp
index b2f56e5a87ab1a..d8f04b313835ea 100644
--- a/clang/test/Sema/constant_builtins_vector.cpp
+++ b/clang/test/Sema/constant_builtins_vector.cpp
@@ -838,3 +838,18 @@ static_assert(__builtin_elementwise_sub_sat((1 << 31), 42) == (1 << 31));
static_assert(__builtin_elementwise_sub_sat(0U, 1U) == 0U);
static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_sub_sat((vector4char){5, 4, 3, 2}, (vector4char){1, 1, 1, 1})) == (LITTLE_END ? 0x01020304 : 0x04030201));
static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_sub_sat((vector4short){(short)0x8000, (short)0x8001, (short)0x8002, (short)0x8003}, (vector4short){7, 8, 9, 10}) == (LITTLE_END ? 0x8000800080008000 : 0x8000800080008000)));
+
+static_assert(__builtin_reduce_min((vector4char){}) == 0);
+static_assert(__builtin_reduce_min((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0x88);
+static_assert(__builtin_reduce_min((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0x8888);
+static_assert(__builtin_reduce_min((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0x88888888);
+static_assert(__builtin_reduce_min((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0x8888888888888888L);
+static_assert(__builtin_reduce_min((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0x11111111U);
+static_assert(__builtin_reduce_min((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0x1111111111111111UL);
+static_assert(__builtin_reduce_max((vector4char){}) == 0);
+static_assert(__builtin_reduce_max((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0x44);
+static_assert(__builtin_reduce_max((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0x4444);
+static_assert(__builtin_reduce_max((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0x44444444);
+static_assert(__builtin_reduce_max((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0x4444444444444444L);
+static_assert(__builtin_reduce_max((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0x88888888U);
+static_assert(__builtin_reduce_max((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0x8888888888888888UL);
>From 93f453716c9e39161a382df923881e4de5172ec3 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 22 Dec 2024 19:48:53 +0800
Subject: [PATCH 2/2] address review comments
---
clang/test/Sema/constant_builtins_vector.cpp | 30 ++++++++++----------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp
index d8f04b313835ea..8659fa9e46612d 100644
--- a/clang/test/Sema/constant_builtins_vector.cpp
+++ b/clang/test/Sema/constant_builtins_vector.cpp
@@ -798,6 +798,21 @@ 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_reduce_min((vector4char){}) == 0);
+static_assert(__builtin_reduce_min((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0x88);
+static_assert(__builtin_reduce_min((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0x8888);
+static_assert(__builtin_reduce_min((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0x88888888);
+static_assert(__builtin_reduce_min((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0x8888888888888888L);
+static_assert(__builtin_reduce_min((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0x11111111U);
+static_assert(__builtin_reduce_min((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0x1111111111111111UL);
+static_assert(__builtin_reduce_max((vector4char){}) == 0);
+static_assert(__builtin_reduce_max((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0x44);
+static_assert(__builtin_reduce_max((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0x4444);
+static_assert(__builtin_reduce_max((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0x44444444);
+static_assert(__builtin_reduce_max((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0x4444444444444444L);
+static_assert(__builtin_reduce_max((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0x88888888U);
+static_assert(__builtin_reduce_max((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0x8888888888888888UL);
+
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 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);
@@ -838,18 +853,3 @@ static_assert(__builtin_elementwise_sub_sat((1 << 31), 42) == (1 << 31));
static_assert(__builtin_elementwise_sub_sat(0U, 1U) == 0U);
static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_sub_sat((vector4char){5, 4, 3, 2}, (vector4char){1, 1, 1, 1})) == (LITTLE_END ? 0x01020304 : 0x04030201));
static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_sub_sat((vector4short){(short)0x8000, (short)0x8001, (short)0x8002, (short)0x8003}, (vector4short){7, 8, 9, 10}) == (LITTLE_END ? 0x8000800080008000 : 0x8000800080008000)));
-
-static_assert(__builtin_reduce_min((vector4char){}) == 0);
-static_assert(__builtin_reduce_min((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0x88);
-static_assert(__builtin_reduce_min((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0x8888);
-static_assert(__builtin_reduce_min((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0x88888888);
-static_assert(__builtin_reduce_min((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0x8888888888888888L);
-static_assert(__builtin_reduce_min((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0x11111111U);
-static_assert(__builtin_reduce_min((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0x1111111111111111UL);
-static_assert(__builtin_reduce_max((vector4char){}) == 0);
-static_assert(__builtin_reduce_max((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0x44);
-static_assert(__builtin_reduce_max((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0x4444);
-static_assert(__builtin_reduce_max((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0x44444444);
-static_assert(__builtin_reduce_max((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0x4444444444444444L);
-static_assert(__builtin_reduce_max((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0x88888888U);
-static_assert(__builtin_reduce_max((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0x8888888888888888UL);
More information about the cfe-commits
mailing list