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

Reply via email to