Skip to content

Commit ff3d550

Browse files
authored
[clang][bytecode][NFC] Add popToUInt64() to builtin evaluation (#170164)
We often don't need the APSInt at all, so add a version that pops the integral from the stack and just static_casts to uint64_t.
1 parent 867d353 commit ff3d550

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ static void discard(InterpStack &Stk, PrimType T) {
4848
TYPE_SWITCH(T, { Stk.discard<T>(); });
4949
}
5050

51+
static uint64_t popToUInt64(const InterpState &S, const Expr *E) {
52+
INT_TYPE_SWITCH(*S.getContext().classify(E->getType()),
53+
return static_cast<uint64_t>(S.Stk.pop<T>()));
54+
}
55+
5156
static APSInt popToAPSInt(InterpStack &Stk, PrimType T) {
5257
INT_TYPE_SWITCH(T, return Stk.pop<T>().toAPSInt());
5358
}
@@ -212,8 +217,7 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
212217
uint64_t Limit = ~static_cast<uint64_t>(0);
213218
if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp ||
214219
ID == Builtin::BIwcsncmp || ID == Builtin::BI__builtin_wcsncmp)
215-
Limit = popToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2)))
216-
.getZExtValue();
220+
Limit = popToUInt64(S, Call->getArg(2));
217221

218222
const Pointer &B = S.Stk.pop<Pointer>();
219223
const Pointer &A = S.Stk.pop<Pointer>();
@@ -991,7 +995,7 @@ static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC,
991995
};
992996

993997
const Pointer &Ptr = S.Stk.pop<Pointer>();
994-
const APSInt &SizeVal = popToAPSInt(S, Call->getArg(0));
998+
uint64_t SizeVal = popToUInt64(S, Call->getArg(0));
995999

9961000
// For __atomic_is_lock_free(sizeof(_Atomic(T))), if the size is a power
9971001
// of two less than or equal to the maximum inline atomic width, we know it
@@ -1003,7 +1007,7 @@ static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC,
10031007
// x86-64 processors.
10041008

10051009
// Check power-of-two.
1006-
CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue());
1010+
CharUnits Size = CharUnits::fromQuantity(SizeVal);
10071011
if (Size.isPowerOfTwo()) {
10081012
// Check against inlining width.
10091013
unsigned InlineWidthBits =
@@ -1057,9 +1061,9 @@ static bool interp__builtin_c11_atomic_is_lock_free(InterpState &S,
10571061
CodePtr OpPC,
10581062
const InterpFrame *Frame,
10591063
const CallExpr *Call) {
1060-
const APSInt &SizeVal = popToAPSInt(S, Call->getArg(0));
1064+
uint64_t SizeVal = popToUInt64(S, Call->getArg(0));
10611065

1062-
CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue());
1066+
CharUnits Size = CharUnits::fromQuantity(SizeVal);
10631067
if (Size.isPowerOfTwo()) {
10641068
// Check against inlining width.
10651069
unsigned InlineWidthBits =
@@ -1719,12 +1723,10 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
17191723
const CallExpr *Call, unsigned ID) {
17201724
assert(Call->getNumArgs() == 3);
17211725
const ASTContext &ASTCtx = S.getASTContext();
1722-
APSInt Size = popToAPSInt(S, Call->getArg(2));
1726+
uint64_t Size = popToUInt64(S, Call->getArg(2));
17231727
Pointer SrcPtr = S.Stk.pop<Pointer>().expand();
17241728
Pointer DestPtr = S.Stk.pop<Pointer>().expand();
17251729

1726-
assert(!Size.isSigned() && "memcpy and friends take an unsigned size");
1727-
17281730
if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
17291731
diagnoseNonConstexprBuiltin(S, OpPC, ID);
17301732

@@ -1736,7 +1738,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
17361738
ID == Builtin::BI__builtin_wmemmove;
17371739

17381740
// If the size is zero, we treat this as always being a valid no-op.
1739-
if (Size.isZero()) {
1741+
if (Size == 0) {
17401742
S.Stk.push<Pointer>(DestPtr);
17411743
return true;
17421744
}
@@ -1798,11 +1800,10 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
17981800
if (WChar) {
17991801
uint64_t WCharSize =
18001802
ASTCtx.getTypeSizeInChars(ASTCtx.getWCharType()).getQuantity();
1801-
Size *= APSInt(APInt(Size.getBitWidth(), WCharSize, /*IsSigned=*/false),
1802-
/*IsUnsigend=*/true);
1803+
Size *= WCharSize;
18031804
}
18041805

1805-
if (Size.urem(DestElemSize) != 0) {
1806+
if (Size % DestElemSize != 0) {
18061807
S.FFDiag(S.Current->getSource(OpPC),
18071808
diag::note_constexpr_memcpy_unsupported)
18081809
<< Move << WChar << 0 << DestElemType << Size << DestElemSize;
@@ -1835,12 +1836,12 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18351836
// Check if we have enough elements to read from and write to.
18361837
size_t RemainingDestBytes = RemainingDestElems * DestElemSize;
18371838
size_t RemainingSrcBytes = RemainingSrcElems * SrcElemSize;
1838-
if (Size.ugt(RemainingDestBytes) || Size.ugt(RemainingSrcBytes)) {
1839-
APInt N = Size.udiv(DestElemSize);
1839+
if (Size > RemainingDestBytes || Size > RemainingSrcBytes) {
1840+
APInt N = APInt(64, Size / DestElemSize);
18401841
S.FFDiag(S.Current->getSource(OpPC),
18411842
diag::note_constexpr_memcpy_unsupported)
1842-
<< Move << WChar << (Size.ugt(RemainingSrcBytes) ? 1 : 2)
1843-
<< DestElemType << toString(N, 10, /*Signed=*/false);
1843+
<< Move << WChar << (Size > RemainingSrcBytes ? 1 : 2) << DestElemType
1844+
<< toString(N, 10, /*Signed=*/false);
18441845
return false;
18451846
}
18461847

@@ -1857,18 +1858,17 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18571858

18581859
unsigned SrcIndex = SrcP.expand().getIndex() * SrcP.elemSize();
18591860
unsigned DstIndex = DestP.expand().getIndex() * DestP.elemSize();
1860-
unsigned N = Size.getZExtValue();
18611861

1862-
if ((SrcIndex <= DstIndex && (SrcIndex + N) > DstIndex) ||
1863-
(DstIndex <= SrcIndex && (DstIndex + N) > SrcIndex)) {
1862+
if ((SrcIndex <= DstIndex && (SrcIndex + Size) > DstIndex) ||
1863+
(DstIndex <= SrcIndex && (DstIndex + Size) > SrcIndex)) {
18641864
S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_overlap)
18651865
<< /*IsWChar=*/false;
18661866
return false;
18671867
}
18681868
}
18691869

1870-
assert(Size.getZExtValue() % DestElemSize == 0);
1871-
if (!DoMemcpy(S, OpPC, SrcPtr, DestPtr, Bytes(Size.getZExtValue()).toBits()))
1870+
assert(Size % DestElemSize == 0);
1871+
if (!DoMemcpy(S, OpPC, SrcPtr, DestPtr, Bytes(Size).toBits()))
18721872
return false;
18731873

18741874
S.Stk.push<Pointer>(DestPtr);
@@ -1885,15 +1885,15 @@ static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC,
18851885
const InterpFrame *Frame,
18861886
const CallExpr *Call, unsigned ID) {
18871887
assert(Call->getNumArgs() == 3);
1888-
const APSInt &Size = popToAPSInt(S, Call->getArg(2));
1888+
uint64_t Size = popToUInt64(S, Call->getArg(2));
18891889
const Pointer &PtrB = S.Stk.pop<Pointer>();
18901890
const Pointer &PtrA = S.Stk.pop<Pointer>();
18911891

18921892
if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||
18931893
ID == Builtin::BIwmemcmp)
18941894
diagnoseNonConstexprBuiltin(S, OpPC, ID);
18951895

1896-
if (Size.isZero()) {
1896+
if (Size == 0) {
18971897
pushInteger(S, 0, Call->getType());
18981898
return true;
18991899
}
@@ -1950,7 +1950,7 @@ static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC,
19501950
ElemSize = ASTCtx.getTypeSizeInChars(ASTCtx.getWCharType()).getQuantity();
19511951
// The Size given for the wide variants is in wide-char units. Convert it
19521952
// to bytes.
1953-
size_t ByteSize = Size.getZExtValue() * ElemSize;
1953+
size_t ByteSize = Size * ElemSize;
19541954
size_t CmpSize = std::min(MinBufferSize, ByteSize);
19551955

19561956
for (size_t I = 0; I != CmpSize; I += ElemSize) {
@@ -2238,7 +2238,7 @@ static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC,
22382238
// clear, objects are whole variables. If it is set, a closest surrounding
22392239
// subobject is considered the object a pointer points to. The second bit
22402240
// determines if maximum or minimum of remaining bytes is computed.
2241-
unsigned Kind = popToAPSInt(S, Call->getArg(1)).getZExtValue();
2241+
unsigned Kind = popToUInt64(S, Call->getArg(1));
22422242
assert(Kind <= 3 && "unexpected kind");
22432243
bool UseFieldDesc = (Kind & 1u);
22442244
bool ReportMinimum = (Kind & 2u);

0 commit comments

Comments
 (0)