Skip to content

Commit dd577c0

Browse files
authored
[clang] constexpr built-in reduce min/max function. (#120866)
Part of #51787. This patch adds constexpr support for the built-in reduce min/max function.
1 parent 34d55df commit dd577c0

File tree

5 files changed

+34
-7
lines changed

5 files changed

+34
-7
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,9 +736,10 @@ at the end to the next power of 2.
736736

737737
These reductions support both fixed-sized and scalable vector types.
738738

739-
The integer reduction intrinsics, including ``__builtin_reduce_add``,
740-
``__builtin_reduce_mul``, ``__builtin_reduce_and``, ``__builtin_reduce_or``,
741-
and ``__builtin_reduce_xor``, can be called in a ``constexpr`` context.
739+
The integer reduction intrinsics, including ``__builtin_reduce_max``,
740+
``__builtin_reduce_min``, ``__builtin_reduce_add``, ``__builtin_reduce_mul``,
741+
``__builtin_reduce_and``, ``__builtin_reduce_or``, and ``__builtin_reduce_xor``,
742+
can be called in a ``constexpr`` context.
742743

743744
Example:
744745

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,8 @@ Non-comprehensive list of changes in this release
421421
``__builtin_reduce_mul``, ``__builtin_reduce_and``, ``__builtin_reduce_or``,
422422
``__builtin_reduce_xor``, ``__builtin_elementwise_popcount``,
423423
``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``,
424-
``__builtin_elementwise_sub_sat``.
424+
``__builtin_elementwise_sub_sat``, ``__builtin_reduce_min`` (For integral element type),
425+
``__builtin_reduce_max`` (For integral element type).
425426

426427
- Clang now rejects ``_BitInt`` matrix element types if the bit width is less than ``CHAR_WIDTH`` or
427428
not a power of two, matching preexisting behaviour for vector types.

clang/include/clang/Basic/Builtins.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,13 +1462,13 @@ def ElementwiseSubSat : Builtin {
14621462

14631463
def ReduceMax : Builtin {
14641464
let Spellings = ["__builtin_reduce_max"];
1465-
let Attributes = [NoThrow, Const, CustomTypeChecking];
1465+
let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
14661466
let Prototype = "void(...)";
14671467
}
14681468

14691469
def ReduceMin : Builtin {
14701470
let Spellings = ["__builtin_reduce_min"];
1471-
let Attributes = [NoThrow, Const, CustomTypeChecking];
1471+
let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
14721472
let Prototype = "void(...)";
14731473
}
14741474

clang/lib/AST/ExprConstant.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13604,7 +13604,9 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1360413604
case Builtin::BI__builtin_reduce_mul:
1360513605
case Builtin::BI__builtin_reduce_and:
1360613606
case Builtin::BI__builtin_reduce_or:
13607-
case Builtin::BI__builtin_reduce_xor: {
13607+
case Builtin::BI__builtin_reduce_xor:
13608+
case Builtin::BI__builtin_reduce_min:
13609+
case Builtin::BI__builtin_reduce_max: {
1360813610
APValue Source;
1360913611
if (!EvaluateAsRValue(Info, E->getArg(0), Source))
1361013612
return false;
@@ -13641,6 +13643,14 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1364113643
Reduced ^= Source.getVectorElt(EltNum).getInt();
1364213644
break;
1364313645
}
13646+
case Builtin::BI__builtin_reduce_min: {
13647+
Reduced = std::min(Reduced, Source.getVectorElt(EltNum).getInt());
13648+
break;
13649+
}
13650+
case Builtin::BI__builtin_reduce_max: {
13651+
Reduced = std::max(Reduced, Source.getVectorElt(EltNum).getInt());
13652+
break;
13653+
}
1364413654
}
1364513655
}
1364613656

clang/test/Sema/constant_builtins_vector.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,21 @@ static_assert(__builtin_reduce_xor((vector4long){(long long)0x1111111111111111L,
798798
static_assert(__builtin_reduce_xor((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0xFFFFFFFFU);
799799
static_assert(__builtin_reduce_xor((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0xFFFFFFFFFFFFFFFFUL);
800800

801+
static_assert(__builtin_reduce_min((vector4char){}) == 0);
802+
static_assert(__builtin_reduce_min((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0x88);
803+
static_assert(__builtin_reduce_min((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0x8888);
804+
static_assert(__builtin_reduce_min((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0x88888888);
805+
static_assert(__builtin_reduce_min((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0x8888888888888888L);
806+
static_assert(__builtin_reduce_min((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0x11111111U);
807+
static_assert(__builtin_reduce_min((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0x1111111111111111UL);
808+
static_assert(__builtin_reduce_max((vector4char){}) == 0);
809+
static_assert(__builtin_reduce_max((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0x44);
810+
static_assert(__builtin_reduce_max((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0x4444);
811+
static_assert(__builtin_reduce_max((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0x44444444);
812+
static_assert(__builtin_reduce_max((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0x4444444444444444L);
813+
static_assert(__builtin_reduce_max((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0x88888888U);
814+
static_assert(__builtin_reduce_max((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0x8888888888888888UL);
815+
801816
static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_popcount((vector4char){1, 2, 3, 4})) == (LITTLE_END ? 0x01020101 : 0x01010201));
802817
static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_popcount((vector4short){0, 0x0F0F, ~0, ~0x0F0F})) == (LITTLE_END ? 0x0008001000080000 : 0x0000000800100008));
803818
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){1, 2, 3, 4})) == 5);

0 commit comments

Comments
 (0)