Skip to content

Commit 1e4646d

Browse files
c8efFznamznon
andauthored
[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 <[email protected]>
1 parent c25c6c3 commit 1e4646d

File tree

4 files changed

+42
-1
lines changed

4 files changed

+42
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ Non-comprehensive list of changes in this release
355355
The flexible array member (FAM) can now be accessed immediately without causing
356356
issues with the sanitizer because the counter is automatically set.
357357

358+
- ``__builtin_reduce_add`` function can now be used in constant expressions.
359+
358360
New Compiler Flags
359361
------------------
360362

clang/include/clang/Basic/Builtins.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1504,7 +1504,7 @@ def ReduceAnd : Builtin {
15041504

15051505
def ReduceAdd : Builtin {
15061506
let Spellings = ["__builtin_reduce_add"];
1507-
let Attributes = [NoThrow, Const, CustomTypeChecking];
1507+
let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
15081508
let Prototype = "void(...)";
15091509
}
15101510

clang/lib/AST/ExprConstant.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13527,6 +13527,23 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1352713527
return Success(DidOverflow, E);
1352813528
}
1352913529

13530+
case Builtin::BI__builtin_reduce_add: {
13531+
APValue Source;
13532+
if (!EvaluateAsRValue(Info, E->getArg(0), Source))
13533+
return false;
13534+
13535+
unsigned SourceLen = Source.getVectorLength();
13536+
APSInt Reduced = Source.getVectorElt(0).getInt();
13537+
for (unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
13538+
if (!CheckedIntArithmetic(
13539+
Info, E, Reduced, Source.getVectorElt(EltNum).getInt(),
13540+
Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
13541+
return false;
13542+
}
13543+
13544+
return Success(Reduced, E);
13545+
}
13546+
1353013547
case clang::X86::BI__builtin_ia32_addcarryx_u32:
1353113548
case clang::X86::BI__builtin_ia32_addcarryx_u64:
1353213549
case clang::X86::BI__builtin_ia32_subborrow_u32:

clang/test/Sema/constant_builtins_vector.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ typedef double vector4double __attribute__((__vector_size__(32)));
1919
typedef float vector4float __attribute__((__vector_size__(16)));
2020
typedef long long vector4long __attribute__((__vector_size__(32)));
2121
typedef int vector4int __attribute__((__vector_size__(16)));
22+
typedef unsigned long long vector4ulong __attribute__((__vector_size__(32)));
23+
typedef unsigned int vector4uint __attribute__((__vector_size__(16)));
2224
typedef short vector4short __attribute__((__vector_size__(8)));
2325
typedef char vector4char __attribute__((__vector_size__(4)));
2426
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
723725
permitted in a constexpr context}}
724726
vector4charConst1,
725727
vector4charConst2, -1, -1, -1, -1);
728+
729+
static_assert(__builtin_reduce_add((vector4char){}) == 0);
730+
static_assert(__builtin_reduce_add((vector4char){1, 2, 3, 4}) == 10);
731+
static_assert(__builtin_reduce_add((vector4short){10, 20, 30, 40}) == 100);
732+
static_assert(__builtin_reduce_add((vector4int){100, 200, 300, 400}) == 1000);
733+
static_assert(__builtin_reduce_add((vector4long){1000, 2000, 3000, 4000}) == 10000);
734+
constexpr int reduceAddInt1 = __builtin_reduce_add((vector4int){~(1 << 31), 0, 0, 1});
735+
// expected-error@-1 {{must be initialized by a constant expression}} \
736+
// expected-note@-1 {{outside the range of representable values of type 'int'}}
737+
constexpr long long reduceAddLong1 = __builtin_reduce_add((vector4long){~(1LL << 63), 0, 0, 1});
738+
// expected-error@-1 {{must be initialized by a constant expression}} \
739+
// expected-note@-1 {{outside the range of representable values of type 'long long'}}
740+
constexpr int reduceAddInt2 = __builtin_reduce_add((vector4int){(1 << 31), 0, 0, -1});
741+
// expected-error@-1 {{must be initialized by a constant expression}} \
742+
// expected-note@-1 {{outside the range of representable values of type 'int'}}
743+
constexpr long long reduceAddLong2 = __builtin_reduce_add((vector4long){(1LL << 63), 0, 0, -1});
744+
// expected-error@-1 {{must be initialized by a constant expression}} \
745+
// expected-note@-1 {{outside the range of representable values of type 'long long'}}
746+
static_assert(__builtin_reduce_add((vector4uint){~0U, 0, 0, 1}) == 0);
747+
static_assert(__builtin_reduce_add((vector4ulong){~0ULL, 0, 0, 1}) == 0);

0 commit comments

Comments
 (0)