Skip to content

Commit b03a747

Browse files
authored
[clang] constexpr built-in reduce mul function. (#116626)
Part of #51787. Follow up of #116243. This patch adds constexpr support for the built-in reduce mul function.
1 parent c4030c8 commit b03a747

File tree

4 files changed

+41
-5
lines changed

4 files changed

+41
-5
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ Non-comprehensive list of changes in this release
356356
issues with the sanitizer because the counter is automatically set.
357357

358358
- ``__builtin_reduce_add`` function can now be used in constant expressions.
359+
- ``__builtin_reduce_mul`` function can now be used in constant expressions.
359360

360361
New Compiler Flags
361362
------------------

clang/include/clang/Basic/Builtins.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1510,7 +1510,7 @@ def ReduceAdd : Builtin {
15101510

15111511
def ReduceMul : Builtin {
15121512
let Spellings = ["__builtin_reduce_mul"];
1513-
let Attributes = [NoThrow, Const, CustomTypeChecking];
1513+
let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
15141514
let Prototype = "void(...)";
15151515
}
15161516

clang/lib/AST/ExprConstant.cpp

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

13530-
case Builtin::BI__builtin_reduce_add: {
13530+
case Builtin::BI__builtin_reduce_add:
13531+
case Builtin::BI__builtin_reduce_mul: {
1353113532
APValue Source;
1353213533
if (!EvaluateAsRValue(Info, E->getArg(0), Source))
1353313534
return false;
1353413535

1353513536
unsigned SourceLen = Source.getVectorLength();
1353613537
APSInt Reduced = Source.getVectorElt(0).getInt();
1353713538
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))
13539+
switch (BuiltinOp) {
13540+
default:
1354113541
return false;
13542+
case Builtin::BI__builtin_reduce_add: {
13543+
if (!CheckedIntArithmetic(
13544+
Info, E, Reduced, Source.getVectorElt(EltNum).getInt(),
13545+
Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
13546+
return false;
13547+
break;
13548+
}
13549+
case Builtin::BI__builtin_reduce_mul: {
13550+
if (!CheckedIntArithmetic(
13551+
Info, E, Reduced, Source.getVectorElt(EltNum).getInt(),
13552+
Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
13553+
return false;
13554+
break;
13555+
}
13556+
}
1354213557
}
1354313558

1354413559
return Success(Reduced, E);

clang/test/Sema/constant_builtins_vector.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,3 +745,23 @@ constexpr long long reduceAddLong2 = __builtin_reduce_add((vector4long){(1LL <<
745745
// expected-note@-1 {{outside the range of representable values of type 'long long'}}
746746
static_assert(__builtin_reduce_add((vector4uint){~0U, 0, 0, 1}) == 0);
747747
static_assert(__builtin_reduce_add((vector4ulong){~0ULL, 0, 0, 1}) == 0);
748+
749+
static_assert(__builtin_reduce_mul((vector4char){}) == 0);
750+
static_assert(__builtin_reduce_mul((vector4char){1, 2, 3, 4}) == 24);
751+
static_assert(__builtin_reduce_mul((vector4short){1, 2, 30, 40}) == 2400);
752+
static_assert(__builtin_reduce_mul((vector4int){10, 20, 300, 400}) == 24000000);
753+
static_assert(__builtin_reduce_mul((vector4long){1000L, 2000L, 3000L, 4000L}) == 24000000000000L);
754+
constexpr int reduceMulInt1 = __builtin_reduce_mul((vector4int){~(1 << 31), 1, 1, 2});
755+
// expected-error@-1 {{must be initialized by a constant expression}} \
756+
// expected-note@-1 {{outside the range of representable values of type 'int'}}
757+
constexpr long long reduceMulLong1 = __builtin_reduce_mul((vector4long){~(1LL << 63), 1, 1, 2});
758+
// expected-error@-1 {{must be initialized by a constant expression}} \
759+
// expected-note@-1 {{outside the range of representable values of type 'long long'}}
760+
constexpr int reduceMulInt2 = __builtin_reduce_mul((vector4int){(1 << 31), 1, 1, 2});
761+
// expected-error@-1 {{must be initialized by a constant expression}} \
762+
// expected-note@-1 {{outside the range of representable values of type 'int'}}
763+
constexpr long long reduceMulLong2 = __builtin_reduce_mul((vector4long){(1LL << 63), 1, 1, 2});
764+
// expected-error@-1 {{must be initialized by a constant expression}} \
765+
// expected-note@-1 {{outside the range of representable values of type 'long long'}}
766+
static_assert(__builtin_reduce_mul((vector4uint){~0U, 1, 1, 2}) == ~0U - 1);
767+
static_assert(__builtin_reduce_mul((vector4ulong){~0ULL, 1, 1, 2}) == ~0ULL - 1);

0 commit comments

Comments
 (0)