aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/InterpBuiltin.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-09-17 09:45:24 +0200
committerGitHub <noreply@github.com>2025-09-17 09:45:24 +0200
commitff05dc4526dce68f10450d77a1da2b8061e80dc2 (patch)
treed3fd6311d8f3dc1ed102c73d71e672188863ea33 /clang/lib/AST/ByteCode/InterpBuiltin.cpp
parent2155f17d39f3969ef841c85ef1102a214ab22b30 (diff)
downloadllvm-ff05dc4526dce68f10450d77a1da2b8061e80dc2.zip
llvm-ff05dc4526dce68f10450d77a1da2b8061e80dc2.tar.gz
llvm-ff05dc4526dce68f10450d77a1da2b8061e80dc2.tar.bz2
[clang][bytecode][NFC] Add some popToAPSInt convenience API (#159252)
Add a variant that takes a QualType and one that takes an expression. That way we don't have to repeat the clunky classify() calls all over the place.
Diffstat (limited to 'clang/lib/AST/ByteCode/InterpBuiltin.cpp')
-rw-r--r--clang/lib/AST/ByteCode/InterpBuiltin.cpp101
1 files changed, 39 insertions, 62 deletions
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 40b9e04..b7b6d65 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -49,6 +49,13 @@ static APSInt popToAPSInt(InterpStack &Stk, PrimType T) {
INT_TYPE_SWITCH(T, return Stk.pop<T>().toAPSInt());
}
+static APSInt popToAPSInt(InterpState &S, const Expr *E) {
+ return popToAPSInt(S.Stk, *S.getContext().classify(E->getType()));
+}
+static APSInt popToAPSInt(InterpState &S, QualType T) {
+ return popToAPSInt(S.Stk, *S.getContext().classify(T));
+}
+
/// Pushes \p Val on the stack as the type given by \p QT.
static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) {
assert(QT->isSignedIntegerOrEnumerationType() ||
@@ -1350,11 +1357,8 @@ static bool interp__builtin_ia32_bzhi(InterpState &S, CodePtr OpPC,
!CallType->isIntegerType())
return false;
- PrimType ValT = *S.Ctx.classify(Call->getArg(0));
- PrimType IndexT = *S.Ctx.classify(Call->getArg(1));
-
- APSInt Idx = popToAPSInt(S.Stk, IndexT);
- APSInt Val = popToAPSInt(S.Stk, ValT);
+ APSInt Idx = popToAPSInt(S, Call->getArg(1));
+ APSInt Val = popToAPSInt(S, Call->getArg(0));
unsigned BitWidth = Val.getBitWidth();
uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);
@@ -1374,7 +1378,7 @@ static bool interp__builtin_ia32_lzcnt(InterpState &S, CodePtr OpPC,
!Call->getArg(0)->getType()->isIntegerType())
return false;
- APSInt Val = popToAPSInt(S.Stk, *S.Ctx.classify(Call->getArg(0)));
+ APSInt Val = popToAPSInt(S, Call->getArg(0));
pushInteger(S, Val.countLeadingZeros(), CallType);
return true;
}
@@ -1387,7 +1391,7 @@ static bool interp__builtin_ia32_tzcnt(InterpState &S, CodePtr OpPC,
!Call->getArg(0)->getType()->isIntegerType())
return false;
- APSInt Val = popToAPSInt(S.Stk, *S.Ctx.classify(Call->getArg(0)));
+ APSInt Val = popToAPSInt(S, Call->getArg(0));
pushInteger(S, Val.countTrailingZeros(), CallType);
return true;
}
@@ -1399,11 +1403,8 @@ static bool interp__builtin_ia32_pdep(InterpState &S, CodePtr OpPC,
!Call->getArg(1)->getType()->isIntegerType())
return false;
- PrimType ValT = *S.Ctx.classify(Call->getArg(0));
- PrimType MaskT = *S.Ctx.classify(Call->getArg(1));
-
- APSInt Mask = popToAPSInt(S.Stk, MaskT);
- APSInt Val = popToAPSInt(S.Stk, ValT);
+ APSInt Mask = popToAPSInt(S, Call->getArg(1));
+ APSInt Val = popToAPSInt(S, Call->getArg(0));
unsigned BitWidth = Val.getBitWidth();
APInt Result = APInt::getZero(BitWidth);
@@ -1422,11 +1423,8 @@ static bool interp__builtin_ia32_pext(InterpState &S, CodePtr OpPC,
!Call->getArg(1)->getType()->isIntegerType())
return false;
- PrimType ValT = *S.Ctx.classify(Call->getArg(0));
- PrimType MaskT = *S.Ctx.classify(Call->getArg(1));
-
- APSInt Mask = popToAPSInt(S.Stk, MaskT);
- APSInt Val = popToAPSInt(S.Stk, ValT);
+ APSInt Mask = popToAPSInt(S, Call->getArg(1));
+ APSInt Val = popToAPSInt(S, Call->getArg(0));
unsigned BitWidth = Val.getBitWidth();
APInt Result = APInt::getZero(BitWidth);
@@ -1451,12 +1449,9 @@ static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S,
const Pointer &CarryOutPtr = S.Stk.pop<Pointer>();
- PrimType CarryInT = *S.getContext().classify(Call->getArg(0));
- PrimType LHST = *S.getContext().classify(Call->getArg(1));
- PrimType RHST = *S.getContext().classify(Call->getArg(2));
- APSInt RHS = popToAPSInt(S.Stk, RHST);
- APSInt LHS = popToAPSInt(S.Stk, LHST);
- APSInt CarryIn = popToAPSInt(S.Stk, CarryInT);
+ APSInt RHS = popToAPSInt(S, Call->getArg(2));
+ APSInt LHS = popToAPSInt(S, Call->getArg(1));
+ APSInt CarryIn = popToAPSInt(S, Call->getArg(0));
bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
@@ -1546,7 +1541,7 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
discard(S.Stk, *S.getContext().classify(Arg));
}
- APSInt Bytes = popToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(0)));
+ APSInt Bytes = popToAPSInt(S, Call->getArg(0));
CharUnits ElemSize = S.getASTContext().getTypeSizeInChars(ElemType);
assert(!ElemSize.isZero());
// Divide the number of bytes by sizeof(ElemType), so we get the number of
@@ -1740,9 +1735,7 @@ static bool interp__builtin_elementwise_abs(InterpState &S, CodePtr OpPC,
assert(Call->getNumArgs() == 1);
QualType Ty = Call->getArg(0)->getType();
if (Ty->isIntegerType()) {
- PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
- APSInt Val = popToAPSInt(S.Stk, ArgT);
-
+ APSInt Val = popToAPSInt(S, Call->getArg(0));
pushInteger(S, Val.abs(), Call->getType());
return true;
}
@@ -1791,8 +1784,7 @@ static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC,
unsigned BuiltinID) {
assert(Call->getNumArgs() == 1);
if (Call->getArg(0)->getType()->isIntegerType()) {
- PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
- APSInt Val = popToAPSInt(S.Stk, ArgT);
+ APSInt Val = popToAPSInt(S, Call->getArg(0));
if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
pushInteger(S, Val.popcount(), Call->getType());
@@ -1923,8 +1915,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
const CallExpr *Call, unsigned ID) {
assert(Call->getNumArgs() == 3);
const ASTContext &ASTCtx = S.getASTContext();
- PrimType SizeT = *S.getContext().classify(Call->getArg(2));
- APSInt Size = popToAPSInt(S.Stk, SizeT);
+ APSInt Size = popToAPSInt(S, Call->getArg(2));
const Pointer SrcPtr = S.Stk.pop<Pointer>();
const Pointer DestPtr = S.Stk.pop<Pointer>();
@@ -2090,8 +2081,7 @@ static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call, unsigned ID) {
assert(Call->getNumArgs() == 3);
- PrimType SizeT = *S.getContext().classify(Call->getArg(2));
- const APSInt &Size = popToAPSInt(S.Stk, SizeT);
+ const APSInt &Size = popToAPSInt(S, Call->getArg(2));
const Pointer &PtrB = S.Stk.pop<Pointer>();
const Pointer &PtrA = S.Stk.pop<Pointer>();
@@ -2206,12 +2196,10 @@ static bool interp__builtin_memchr(InterpState &S, CodePtr OpPC,
diagnoseNonConstexprBuiltin(S, OpPC, ID);
std::optional<APSInt> MaxLength;
- PrimType DesiredT = *S.getContext().classify(Call->getArg(1));
- if (Call->getNumArgs() == 3) {
- PrimType MaxT = *S.getContext().classify(Call->getArg(2));
- MaxLength = popToAPSInt(S.Stk, MaxT);
- }
- APSInt Desired = popToAPSInt(S.Stk, DesiredT);
+ if (Call->getNumArgs() == 3)
+ MaxLength = popToAPSInt(S, Call->getArg(2));
+
+ APSInt Desired = popToAPSInt(S, Call->getArg(1));
const Pointer &Ptr = S.Stk.pop<Pointer>();
if (MaxLength && MaxLength->isZero()) {
@@ -2428,13 +2416,12 @@ static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
const ASTContext &ASTCtx = S.getASTContext();
- PrimType KindT = *S.getContext().classify(Call->getArg(1));
// From the GCC docs:
// Kind is an integer constant from 0 to 3. If the least significant bit is
// clear, objects are whole variables. If it is set, a closest surrounding
// subobject is considered the object a pointer points to. The second bit
// determines if maximum or minimum of remaining bytes is computed.
- unsigned Kind = popToAPSInt(S.Stk, KindT).getZExtValue();
+ unsigned Kind = popToAPSInt(S, Call->getArg(1)).getZExtValue();
assert(Kind <= 3 && "unexpected kind");
bool UseFieldDesc = (Kind & 1u);
bool ReportMinimum = (Kind & 2u);
@@ -2562,10 +2549,8 @@ static bool interp__builtin_elementwise_int_binop(
// Single integer case.
if (!Call->getArg(0)->getType()->isVectorType()) {
assert(!Call->getArg(1)->getType()->isVectorType());
- APSInt RHS = popToAPSInt(
- S.Stk, *S.getContext().classify(Call->getArg(1)->getType()));
- APSInt LHS = popToAPSInt(
- S.Stk, *S.getContext().classify(Call->getArg(0)->getType()));
+ APSInt RHS = popToAPSInt(S, Call->getArg(1));
+ APSInt LHS = popToAPSInt(S, Call->getArg(0));
APInt Result = Fn(LHS, RHS);
pushInteger(S, APSInt(std::move(Result), !LHS.isSigned()), Call->getType());
return true;
@@ -2581,8 +2566,7 @@ static bool interp__builtin_elementwise_int_binop(
if (!Call->getArg(1)->getType()->isVectorType()) {
assert(Call->getArg(1)->getType()->isIntegralOrEnumerationType());
- APSInt RHS = popToAPSInt(
- S.Stk, *S.getContext().classify(Call->getArg(1)->getType()));
+ APSInt RHS = popToAPSInt(S, Call->getArg(1));
const Pointer &LHS = S.Stk.pop<Pointer>();
const Pointer &Dst = S.Stk.peek<Pointer>();
@@ -2635,10 +2619,8 @@ static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC,
if (!Arg0Type->isVectorType()) {
assert(!Call->getArg(1)->getType()->isVectorType());
- APSInt RHS = popToAPSInt(
- S.Stk, *S.getContext().classify(Call->getArg(1)->getType()));
- APSInt LHS = popToAPSInt(
- S.Stk, *S.getContext().classify(Call->getArg(0)->getType()));
+ APSInt RHS = popToAPSInt(S, Call->getArg(1));
+ APSInt LHS = popToAPSInt(S, Arg0Type);
APInt Result;
if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
Result = std::max(LHS, RHS);
@@ -2808,8 +2790,7 @@ static bool interp__builtin_select(InterpState &S, CodePtr OpPC,
const CallExpr *Call) {
const Pointer &RHS = S.Stk.pop<Pointer>();
const Pointer &LHS = S.Stk.pop<Pointer>();
- PrimType MaskT = *S.getContext().classify(Call->getArg(0));
- APSInt Mask = popToAPSInt(S.Stk, MaskT);
+ APSInt Mask = popToAPSInt(S, Call->getArg(0));
const Pointer &Dst = S.Stk.peek<Pointer>();
assert(LHS.getNumElems() == RHS.getNumElems());
@@ -2839,8 +2820,7 @@ static bool interp__builtin_select(InterpState &S, CodePtr OpPC,
static bool interp__builtin_blend(InterpState &S, CodePtr OpPC,
const CallExpr *Call) {
- PrimType MaskT = *S.getContext().classify(Call->getArg(2));
- APSInt Mask = popToAPSInt(S.Stk, MaskT);
+ APSInt Mask = popToAPSInt(S, Call->getArg(2));
const Pointer &TrueVec = S.Stk.pop<Pointer>();
const Pointer &FalseVec = S.Stk.pop<Pointer>();
const Pointer &Dst = S.Stk.peek<Pointer>();
@@ -2878,14 +2858,12 @@ static bool interp__builtin_elementwise_triop(
assert(Call->getNumArgs() == 3);
QualType Arg0Type = Call->getArg(0)->getType();
- QualType Arg1Type = Call->getArg(1)->getType();
QualType Arg2Type = Call->getArg(2)->getType();
-
// Non-vector integer types.
if (!Arg0Type->isVectorType()) {
- const APSInt &Op2 = popToAPSInt(S.Stk, *S.getContext().classify(Arg2Type));
- const APSInt &Op1 = popToAPSInt(S.Stk, *S.getContext().classify(Arg1Type));
- const APSInt &Op0 = popToAPSInt(S.Stk, *S.getContext().classify(Arg0Type));
+ const APSInt &Op2 = popToAPSInt(S, Arg2Type);
+ const APSInt &Op1 = popToAPSInt(S, Call->getArg(1));
+ const APSInt &Op0 = popToAPSInt(S, Arg0Type);
APSInt Result = APSInt(Fn(Op0, Op1, Op2), Op0.isUnsigned());
pushInteger(S, Result, Call->getType());
return true;
@@ -2898,8 +2876,7 @@ static bool interp__builtin_elementwise_triop(
// Vector + Vector + Scalar case.
if (!Arg2Type->isVectorType()) {
- APSInt Op2 = popToAPSInt(
- S.Stk, *S.getContext().classify(Call->getArg(2)->getType()));
+ APSInt Op2 = popToAPSInt(S, Arg2Type);
const Pointer &Op1 = S.Stk.pop<Pointer>();
const Pointer &Op0 = S.Stk.pop<Pointer>();