Skip to content

Commit 3ffcc78

Browse files
committed
implement constexpr sub sat
1 parent b20f08c commit 3ffcc78

File tree

6 files changed

+30
-6
lines changed

6 files changed

+30
-6
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,8 +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``, ``__builtin_elementwise_add_sat``, can be
652-
called in a ``constexpr`` context.
651+
``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``,
652+
``__builtin_elementwise_sub_sat`` can be called in a ``constexpr`` context.
653653

654654
============================================== ====================================================================== =========================================
655655
Name Operation Supported element types

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ Non-comprehensive list of changes in this release
411411
- The following builtins can now be used in constant expressions: ``__builtin_reduce_add``,
412412
``__builtin_reduce_mul``, ``__builtin_reduce_and``, ``__builtin_reduce_or``,
413413
``__builtin_reduce_xor``, ``__builtin_elementwise_popcount``,
414-
``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``.
414+
``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``,
415+
``__builtin_elementwise_sub_sat``.
415416

416417
New Compiler Flags
417418
------------------

clang/include/clang/Basic/Builtins.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,7 @@ def ElementwiseAddSat : Builtin {
14561456

14571457
def ElementwiseSubSat : Builtin {
14581458
let Spellings = ["__builtin_elementwise_sub_sat"];
1459-
let Attributes = [NoThrow, Const, CustomTypeChecking];
1459+
let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
14601460
let Prototype = "void(...)";
14611461
}
14621462

clang/lib/AST/ExprConstant.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11339,7 +11339,8 @@ 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: {
11342+
case Builtin::BI__builtin_elementwise_add_sat:
11343+
case Builtin::BI__builtin_elementwise_sub_sat: {
1134311344
APValue SourceLHS, SourceRHS;
1134411345
if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) ||
1134511346
!EvaluateAsRValue(Info, E->getArg(1), SourceRHS))
@@ -11359,6 +11360,11 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1135911360
APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : RHS.uadd_sat(RHS),
1136011361
DestEltTy->isUnsignedIntegerOrEnumerationType())));
1136111362
break;
11363+
case Builtin::BI__builtin_elementwise_sub_sat:
11364+
ResultElements.push_back(APValue(
11365+
APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : RHS.usub_sat(RHS),
11366+
DestEltTy->isUnsignedIntegerOrEnumerationType())));
11367+
break;
1136211368
}
1136311369
}
1136411370

@@ -13238,6 +13244,15 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1323813244
APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
1323913245
return Success(APSInt(Result, !LHS.isSigned()), E);
1324013246
}
13247+
case Builtin::BI__builtin_elementwise_sub_sat: {
13248+
APSInt LHS, RHS;
13249+
if (!EvaluateInteger(E->getArg(0), LHS, Info) ||
13250+
!EvaluateInteger(E->getArg(1), RHS, Info))
13251+
return false;
13252+
13253+
APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
13254+
return Success(APSInt(Result, !LHS.isSigned()), E);
13255+
}
1324113256

1324213257
case Builtin::BIstrlen:
1324313258
case Builtin::BIwcslen:

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ void test_builtin_elementwise_sub_sat(float f1, float f2, double d1, double d2,
165165
// CHECK-NEXT: call i32 @llvm.ssub.sat.i32(i32 [[IAS1]], i32 [[B]])
166166
int_as_one = __builtin_elementwise_sub_sat(int_as_one, b);
167167

168-
// CHECK: call i32 @llvm.ssub.sat.i32(i32 1, i32 97)
168+
// CHECK: store i64 -96, ptr %i1.addr, align 8
169169
i1 = __builtin_elementwise_sub_sat(1, 'a');
170170
}
171171

clang/test/Sema/constant_builtins_vector.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,3 +830,11 @@ static_assert(__builtin_elementwise_add_sat((1 << 31), -42) == (1 << 31));
830830
static_assert(__builtin_elementwise_add_sat(~0U, 1U) == ~0U);
831831
static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_add_sat((vector4char){1, 2, 3, 4}, (vector4char){4, 3, 2, 1})) == (LITTLE_END ? 0x05050505 : 0x05050505));
832832
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)));
833+
834+
static_assert(__builtin_elementwise_sub_sat(1, 2) == -1);
835+
static_assert(__builtin_elementwise_sub_sat(2U, 1U) == 1U);
836+
static_assert(__builtin_elementwise_sub_sat(~(1 << 31), -42) == ~(1 << 31));
837+
static_assert(__builtin_elementwise_sub_sat((1 << 31), 42) == (1 << 31));
838+
static_assert(__builtin_elementwise_sub_sat(0U, 1U) == 0U);
839+
static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_sub_sat((vector4char){5, 4, 3, 2}, (vector4char){4, 3, 2, 1})) == (LITTLE_END ? 0x01010101 : 0x01010101));
840+
static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_sub_sat((vector4short){(short)0x8000, (short)0x8001, (short)0x8002, (short)0x8003}, (vector4short){7, 8, 9, 10}) == (LITTLE_END ? 0x8000800080008000 : 0x8000800080008000)));

0 commit comments

Comments
 (0)