https://github.com/c8ef created https://github.com/llvm/llvm-project/pull/120866
Part of #51787. This patch adds constexpr support for the built-in reduce min/max function. >From 4e16d47641bd02203753752636f1fe90182552e9 Mon Sep 17 00:00:00 2001 From: c8ef <c...@outlook.com> Date: Sun, 22 Dec 2024 11:08:43 +0800 Subject: [PATCH] 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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits