Skip to content

Commit 2af0eb6

Browse files
committed
constexpr elementwise add_sat
1 parent 69227a1 commit 2af0eb6

File tree

6 files changed

+48
-3
lines changed

6 files changed

+48
-3
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,8 @@ elementwise to the input.
648648
Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = ±infinity
649649

650650
The integer elementwise intrinsics, including ``__builtin_elementwise_popcount``,
651-
``__builtin_elementwise_bitreverse``, can be called in a ``constexpr`` context.
651+
``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``, can be
652+
called in a ``constexpr`` context.
652653

653654
============================================== ====================================================================== =========================================
654655
Name Operation Supported element types

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ Non-comprehensive list of changes in this release
414414
- ``__builtin_reduce_or`` and ``__builtin_reduce_xor`` functions can now be used in constant expressions.
415415
- ``__builtin_elementwise_popcount`` function can now be used in constant expressions.
416416
- ``__builtin_elementwise_bitreverse`` function can now be used in constant expressions.
417+
- ``__builtin_elementwise_add_sat`` function can now be used in constant expressions.
417418

418419
New Compiler Flags
419420
------------------

clang/include/clang/Basic/Builtins.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,7 @@ def ElementwiseFma : Builtin {
14501450

14511451
def ElementwiseAddSat : Builtin {
14521452
let Spellings = ["__builtin_elementwise_add_sat"];
1453-
let Attributes = [NoThrow, Const, CustomTypeChecking];
1453+
let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
14541454
let Prototype = "void(...)";
14551455
}
14561456

clang/lib/AST/ExprConstant.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11339,6 +11339,31 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1133911339

1134011340
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
1134111341
}
11342+
case Builtin::BI__builtin_elementwise_add_sat: {
11343+
APValue SourceLHS, SourceRHS;
11344+
if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) ||
11345+
!EvaluateAsRValue(Info, E->getArg(1), SourceRHS))
11346+
return false;
11347+
11348+
QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
11349+
unsigned SourceLen = SourceLHS.getVectorLength();
11350+
SmallVector<APValue, 4> ResultElements;
11351+
ResultElements.reserve(SourceLen);
11352+
11353+
for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11354+
APSInt LHS = SourceLHS.getVectorElt(EltNum).getInt();
11355+
APSInt RHS = SourceRHS.getVectorElt(EltNum).getInt();
11356+
switch (E->getBuiltinCallee()) {
11357+
case Builtin::BI__builtin_elementwise_add_sat:
11358+
ResultElements.push_back(APValue(
11359+
APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : RHS.uadd_sat(RHS),
11360+
DestEltTy->isUnsignedIntegerOrEnumerationType())));
11361+
break;
11362+
}
11363+
}
11364+
11365+
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11366+
}
1134211367
}
1134311368
}
1134411369

@@ -13204,6 +13229,16 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1320413229
return Success(Val.rotr(Amt.urem(Val.getBitWidth())), E);
1320513230
}
1320613231

13232+
case Builtin::BI__builtin_elementwise_add_sat: {
13233+
APSInt LHS, RHS;
13234+
if (!EvaluateInteger(E->getArg(0), LHS, Info) ||
13235+
!EvaluateInteger(E->getArg(1), RHS, Info))
13236+
return false;
13237+
13238+
APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
13239+
return Success(APSInt(Result, !LHS.isSigned()), E);
13240+
}
13241+
1320713242
case Builtin::BIstrlen:
1320813243
case Builtin::BIwcslen:
1320913244
// A call to strlen is not a constant expression.

clang/test/CodeGen/builtins-elementwise-math.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ void test_builtin_elementwise_add_sat(float f1, float f2, double d1, double d2,
112112
// CHECK-NEXT: call i32 @llvm.sadd.sat.i32(i32 [[IAS1]], i32 [[B]])
113113
int_as_one = __builtin_elementwise_add_sat(int_as_one, b);
114114

115-
// CHECK: call i32 @llvm.sadd.sat.i32(i32 1, i32 97)
115+
// CHECK: store i64 98, ptr %i1.addr, align 8
116116
i1 = __builtin_elementwise_add_sat(1, 'a');
117117
}
118118

clang/test/Sema/constant_builtins_vector.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,3 +822,11 @@ static_assert(__builtin_elementwise_bitreverse(0x12345678) == 0x1E6A2C48);
822822
static_assert(__builtin_elementwise_bitreverse(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480);
823823
static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_bitreverse((vector4char){1, 2, 4, 8})) == (LITTLE_END ? 0x10204080 : 0x80402010));
824824
static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_bitreverse((vector4short){1, 2, 4, 8})) == (LITTLE_END ? 0x1000200040008000 : 0x8000400020001000));
825+
826+
static_assert(__builtin_elementwise_add_sat(1, 2) == 3);
827+
static_assert(__builtin_elementwise_add_sat(1U, 2U) == 3U);
828+
static_assert(__builtin_elementwise_add_sat(~(1 << 31), 42) == ~(1 << 31));
829+
static_assert(__builtin_elementwise_add_sat((1 << 31), -42) == (1 << 31));
830+
static_assert(__builtin_elementwise_add_sat(~0U, 1U) == ~0U);
831+
static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_add_sat((vector4char){1, 2, 3, 4}, (vector4char){4, 3, 2, 1})) == (LITTLE_END ? 0x05050505 : 0x05050505));
832+
static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_add_sat((vector4short){(short)0x8000, (short)0x8001, (short)0x8002, (short)0x8003}, (vector4short){-7, -8, -9, -10}) == (LITTLE_END ? 0x8000800080008000 : 0x8000800080008000)));

0 commit comments

Comments
 (0)