diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-09-17 09:45:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-17 09:45:24 +0200 |
commit | ff05dc4526dce68f10450d77a1da2b8061e80dc2 (patch) | |
tree | d3fd6311d8f3dc1ed102c73d71e672188863ea33 /clang/lib/AST/ByteCode/InterpBuiltin.cpp | |
parent | 2155f17d39f3969ef841c85ef1102a214ab22b30 (diff) | |
download | llvm-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.cpp | 101 |
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>(); |