Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,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
------------------

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -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(...)";
}

Expand Down
14 changes: 14 additions & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13528,6 +13528,20 @@ 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;

auto SourceLen = Source.getVectorLength();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(style) Avoid auto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

APSInt Reduced = Source.getVectorElt(0).getInt();
for (unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
Reduced += Source.getVectorElt(EltNum).getInt();
}

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:
Expand Down
6 changes: 6 additions & 0 deletions clang/test/Sema/constant_builtins_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,3 +723,9 @@ 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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this handled? I'd have expected Source.getVectorElt(0).getInt() to have failed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is similar to zero initializing a vector with 4 char elements.

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);
Loading