[clang] 1e4646d - [clang] constexpr built-in reduce add function. (#116243)

via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 18 04:47:11 PST 2024


Author: c8ef
Date: 2024-11-18T20:47:07+08:00
New Revision: 1e4646d8191b13ac9c4d8c2cd3bb20a184f1966f

URL: https://github.com/llvm/llvm-project/commit/1e4646d8191b13ac9c4d8c2cd3bb20a184f1966f
DIFF: https://github.com/llvm/llvm-project/commit/1e4646d8191b13ac9c4d8c2cd3bb20a184f1966f.diff

LOG: [clang] constexpr built-in reduce add function.  (#116243)

Part of #51787.

This patch adds constexpr support for the built-in reduce add function.
If this is the right way to go, I will add support for other reduce
functions in later patches.

---------

Co-authored-by: Mariya Podchishchaeva <mariya.podchishchaeva at intel.com>

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 044f62e770a7a0..2bd67138ecc048 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -355,6 +355,8 @@ Non-comprehensive list of changes in this release
   The flexible array member (FAM) can now be accessed immediately without causing
   issues with the sanitizer because the counter is automatically set.
 
+- ``__builtin_reduce_add`` 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 8653474744c58f..f5124f4633364f 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1504,7 +1504,7 @@ def ReduceAnd : Builtin {
 
 def ReduceAdd : Builtin {
   let Spellings = ["__builtin_reduce_add"];
-  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 5f016b0eb5873b..833b99bf1bd9f1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13527,6 +13527,23 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     return Success(DidOverflow, E);
   }
 
+  case Builtin::BI__builtin_reduce_add: {
+    APValue Source;
+    if (!EvaluateAsRValue(Info, E->getArg(0), Source))
+      return false;
+
+    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))
+        return false;
+    }
+
+    return Success(Reduced, E);
+  }
+
   case clang::X86::BI__builtin_ia32_addcarryx_u32:
   case clang::X86::BI__builtin_ia32_addcarryx_u64:
   case clang::X86::BI__builtin_ia32_subborrow_u32:

diff  --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp
index c6b1b37cef28b4..d15c587cfffc49 100644
--- a/clang/test/Sema/constant_builtins_vector.cpp
+++ b/clang/test/Sema/constant_builtins_vector.cpp
@@ -19,6 +19,8 @@ typedef double vector4double __attribute__((__vector_size__(32)));
 typedef float vector4float __attribute__((__vector_size__(16)));
 typedef long long vector4long __attribute__((__vector_size__(32)));
 typedef int vector4int __attribute__((__vector_size__(16)));
+typedef unsigned long long vector4ulong __attribute__((__vector_size__(32)));
+typedef unsigned int vector4uint __attribute__((__vector_size__(16)));
 typedef short vector4short __attribute__((__vector_size__(8)));
 typedef char vector4char __attribute__((__vector_size__(4)));
 typedef BitInt8 vector4BitInt8 __attribute__((__vector_size__(4)));
@@ -723,3 +725,23 @@ not within the bounds of the input vectors; index of -1 found at position 0 is n
 permitted in a constexpr context}}
         vector4charConst1,
         vector4charConst2, -1, -1, -1, -1);
+
+static_assert(__builtin_reduce_add((vector4char){}) == 0);
+static_assert(__builtin_reduce_add((vector4char){1, 2, 3, 4}) == 10);
+static_assert(__builtin_reduce_add((vector4short){10, 20, 30, 40}) == 100);
+static_assert(__builtin_reduce_add((vector4int){100, 200, 300, 400}) == 1000);
+static_assert(__builtin_reduce_add((vector4long){1000, 2000, 3000, 4000}) == 10000);
+constexpr int reduceAddInt1 = __builtin_reduce_add((vector4int){~(1 << 31), 0, 0, 1});
+// 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 reduceAddLong1 = __builtin_reduce_add((vector4long){~(1LL << 63), 0, 0, 1});
+// 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 reduceAddInt2 = __builtin_reduce_add((vector4int){(1 << 31), 0, 0, -1});
+// 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 reduceAddLong2 = __builtin_reduce_add((vector4long){(1LL << 63), 0, 0, -1});
+// 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_add((vector4uint){~0U, 0, 0, 1}) == 0);
+static_assert(__builtin_reduce_add((vector4ulong){~0ULL, 0, 0, 1}) == 0);


        


More information about the cfe-commits mailing list