Skip to content

Commit ff05dc4

Browse files
authored
[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.
1 parent 2155f17 commit ff05dc4

File tree

1 file changed

+39
-62
lines changed

1 file changed

+39
-62
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 39 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ static APSInt popToAPSInt(InterpStack &Stk, PrimType T) {
4949
INT_TYPE_SWITCH(T, return Stk.pop<T>().toAPSInt());
5050
}
5151

52+
static APSInt popToAPSInt(InterpState &S, const Expr *E) {
53+
return popToAPSInt(S.Stk, *S.getContext().classify(E->getType()));
54+
}
55+
static APSInt popToAPSInt(InterpState &S, QualType T) {
56+
return popToAPSInt(S.Stk, *S.getContext().classify(T));
57+
}
58+
5259
/// Pushes \p Val on the stack as the type given by \p QT.
5360
static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) {
5461
assert(QT->isSignedIntegerOrEnumerationType() ||
@@ -1350,11 +1357,8 @@ static bool interp__builtin_ia32_bzhi(InterpState &S, CodePtr OpPC,
13501357
!CallType->isIntegerType())
13511358
return false;
13521359

1353-
PrimType ValT = *S.Ctx.classify(Call->getArg(0));
1354-
PrimType IndexT = *S.Ctx.classify(Call->getArg(1));
1355-
1356-
APSInt Idx = popToAPSInt(S.Stk, IndexT);
1357-
APSInt Val = popToAPSInt(S.Stk, ValT);
1360+
APSInt Idx = popToAPSInt(S, Call->getArg(1));
1361+
APSInt Val = popToAPSInt(S, Call->getArg(0));
13581362

13591363
unsigned BitWidth = Val.getBitWidth();
13601364
uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);
@@ -1374,7 +1378,7 @@ static bool interp__builtin_ia32_lzcnt(InterpState &S, CodePtr OpPC,
13741378
!Call->getArg(0)->getType()->isIntegerType())
13751379
return false;
13761380

1377-
APSInt Val = popToAPSInt(S.Stk, *S.Ctx.classify(Call->getArg(0)));
1381+
APSInt Val = popToAPSInt(S, Call->getArg(0));
13781382
pushInteger(S, Val.countLeadingZeros(), CallType);
13791383
return true;
13801384
}
@@ -1387,7 +1391,7 @@ static bool interp__builtin_ia32_tzcnt(InterpState &S, CodePtr OpPC,
13871391
!Call->getArg(0)->getType()->isIntegerType())
13881392
return false;
13891393

1390-
APSInt Val = popToAPSInt(S.Stk, *S.Ctx.classify(Call->getArg(0)));
1394+
APSInt Val = popToAPSInt(S, Call->getArg(0));
13911395
pushInteger(S, Val.countTrailingZeros(), CallType);
13921396
return true;
13931397
}
@@ -1399,11 +1403,8 @@ static bool interp__builtin_ia32_pdep(InterpState &S, CodePtr OpPC,
13991403
!Call->getArg(1)->getType()->isIntegerType())
14001404
return false;
14011405

1402-
PrimType ValT = *S.Ctx.classify(Call->getArg(0));
1403-
PrimType MaskT = *S.Ctx.classify(Call->getArg(1));
1404-
1405-
APSInt Mask = popToAPSInt(S.Stk, MaskT);
1406-
APSInt Val = popToAPSInt(S.Stk, ValT);
1406+
APSInt Mask = popToAPSInt(S, Call->getArg(1));
1407+
APSInt Val = popToAPSInt(S, Call->getArg(0));
14071408

14081409
unsigned BitWidth = Val.getBitWidth();
14091410
APInt Result = APInt::getZero(BitWidth);
@@ -1422,11 +1423,8 @@ static bool interp__builtin_ia32_pext(InterpState &S, CodePtr OpPC,
14221423
!Call->getArg(1)->getType()->isIntegerType())
14231424
return false;
14241425

1425-
PrimType ValT = *S.Ctx.classify(Call->getArg(0));
1426-
PrimType MaskT = *S.Ctx.classify(Call->getArg(1));
1427-
1428-
APSInt Mask = popToAPSInt(S.Stk, MaskT);
1429-
APSInt Val = popToAPSInt(S.Stk, ValT);
1426+
APSInt Mask = popToAPSInt(S, Call->getArg(1));
1427+
APSInt Val = popToAPSInt(S, Call->getArg(0));
14301428

14311429
unsigned BitWidth = Val.getBitWidth();
14321430
APInt Result = APInt::getZero(BitWidth);
@@ -1451,12 +1449,9 @@ static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S,
14511449

14521450
const Pointer &CarryOutPtr = S.Stk.pop<Pointer>();
14531451

1454-
PrimType CarryInT = *S.getContext().classify(Call->getArg(0));
1455-
PrimType LHST = *S.getContext().classify(Call->getArg(1));
1456-
PrimType RHST = *S.getContext().classify(Call->getArg(2));
1457-
APSInt RHS = popToAPSInt(S.Stk, RHST);
1458-
APSInt LHS = popToAPSInt(S.Stk, LHST);
1459-
APSInt CarryIn = popToAPSInt(S.Stk, CarryInT);
1452+
APSInt RHS = popToAPSInt(S, Call->getArg(2));
1453+
APSInt LHS = popToAPSInt(S, Call->getArg(1));
1454+
APSInt CarryIn = popToAPSInt(S, Call->getArg(0));
14601455

14611456
bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
14621457
BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
@@ -1546,7 +1541,7 @@ static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC,
15461541
discard(S.Stk, *S.getContext().classify(Arg));
15471542
}
15481543

1549-
APSInt Bytes = popToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(0)));
1544+
APSInt Bytes = popToAPSInt(S, Call->getArg(0));
15501545
CharUnits ElemSize = S.getASTContext().getTypeSizeInChars(ElemType);
15511546
assert(!ElemSize.isZero());
15521547
// 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,
17401735
assert(Call->getNumArgs() == 1);
17411736
QualType Ty = Call->getArg(0)->getType();
17421737
if (Ty->isIntegerType()) {
1743-
PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
1744-
APSInt Val = popToAPSInt(S.Stk, ArgT);
1745-
1738+
APSInt Val = popToAPSInt(S, Call->getArg(0));
17461739
pushInteger(S, Val.abs(), Call->getType());
17471740
return true;
17481741
}
@@ -1791,8 +1784,7 @@ static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC,
17911784
unsigned BuiltinID) {
17921785
assert(Call->getNumArgs() == 1);
17931786
if (Call->getArg(0)->getType()->isIntegerType()) {
1794-
PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
1795-
APSInt Val = popToAPSInt(S.Stk, ArgT);
1787+
APSInt Val = popToAPSInt(S, Call->getArg(0));
17961788

17971789
if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
17981790
pushInteger(S, Val.popcount(), Call->getType());
@@ -1923,8 +1915,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
19231915
const CallExpr *Call, unsigned ID) {
19241916
assert(Call->getNumArgs() == 3);
19251917
const ASTContext &ASTCtx = S.getASTContext();
1926-
PrimType SizeT = *S.getContext().classify(Call->getArg(2));
1927-
APSInt Size = popToAPSInt(S.Stk, SizeT);
1918+
APSInt Size = popToAPSInt(S, Call->getArg(2));
19281919
const Pointer SrcPtr = S.Stk.pop<Pointer>();
19291920
const Pointer DestPtr = S.Stk.pop<Pointer>();
19301921

@@ -2090,8 +2081,7 @@ static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC,
20902081
const InterpFrame *Frame,
20912082
const CallExpr *Call, unsigned ID) {
20922083
assert(Call->getNumArgs() == 3);
2093-
PrimType SizeT = *S.getContext().classify(Call->getArg(2));
2094-
const APSInt &Size = popToAPSInt(S.Stk, SizeT);
2084+
const APSInt &Size = popToAPSInt(S, Call->getArg(2));
20952085
const Pointer &PtrB = S.Stk.pop<Pointer>();
20962086
const Pointer &PtrA = S.Stk.pop<Pointer>();
20972087

@@ -2206,12 +2196,10 @@ static bool interp__builtin_memchr(InterpState &S, CodePtr OpPC,
22062196
diagnoseNonConstexprBuiltin(S, OpPC, ID);
22072197

22082198
std::optional<APSInt> MaxLength;
2209-
PrimType DesiredT = *S.getContext().classify(Call->getArg(1));
2210-
if (Call->getNumArgs() == 3) {
2211-
PrimType MaxT = *S.getContext().classify(Call->getArg(2));
2212-
MaxLength = popToAPSInt(S.Stk, MaxT);
2213-
}
2214-
APSInt Desired = popToAPSInt(S.Stk, DesiredT);
2199+
if (Call->getNumArgs() == 3)
2200+
MaxLength = popToAPSInt(S, Call->getArg(2));
2201+
2202+
APSInt Desired = popToAPSInt(S, Call->getArg(1));
22152203
const Pointer &Ptr = S.Stk.pop<Pointer>();
22162204

22172205
if (MaxLength && MaxLength->isZero()) {
@@ -2428,13 +2416,12 @@ static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC,
24282416
const InterpFrame *Frame,
24292417
const CallExpr *Call) {
24302418
const ASTContext &ASTCtx = S.getASTContext();
2431-
PrimType KindT = *S.getContext().classify(Call->getArg(1));
24322419
// From the GCC docs:
24332420
// Kind is an integer constant from 0 to 3. If the least significant bit is
24342421
// clear, objects are whole variables. If it is set, a closest surrounding
24352422
// subobject is considered the object a pointer points to. The second bit
24362423
// determines if maximum or minimum of remaining bytes is computed.
2437-
unsigned Kind = popToAPSInt(S.Stk, KindT).getZExtValue();
2424+
unsigned Kind = popToAPSInt(S, Call->getArg(1)).getZExtValue();
24382425
assert(Kind <= 3 && "unexpected kind");
24392426
bool UseFieldDesc = (Kind & 1u);
24402427
bool ReportMinimum = (Kind & 2u);
@@ -2562,10 +2549,8 @@ static bool interp__builtin_elementwise_int_binop(
25622549
// Single integer case.
25632550
if (!Call->getArg(0)->getType()->isVectorType()) {
25642551
assert(!Call->getArg(1)->getType()->isVectorType());
2565-
APSInt RHS = popToAPSInt(
2566-
S.Stk, *S.getContext().classify(Call->getArg(1)->getType()));
2567-
APSInt LHS = popToAPSInt(
2568-
S.Stk, *S.getContext().classify(Call->getArg(0)->getType()));
2552+
APSInt RHS = popToAPSInt(S, Call->getArg(1));
2553+
APSInt LHS = popToAPSInt(S, Call->getArg(0));
25692554
APInt Result = Fn(LHS, RHS);
25702555
pushInteger(S, APSInt(std::move(Result), !LHS.isSigned()), Call->getType());
25712556
return true;
@@ -2581,8 +2566,7 @@ static bool interp__builtin_elementwise_int_binop(
25812566
if (!Call->getArg(1)->getType()->isVectorType()) {
25822567
assert(Call->getArg(1)->getType()->isIntegralOrEnumerationType());
25832568

2584-
APSInt RHS = popToAPSInt(
2585-
S.Stk, *S.getContext().classify(Call->getArg(1)->getType()));
2569+
APSInt RHS = popToAPSInt(S, Call->getArg(1));
25862570
const Pointer &LHS = S.Stk.pop<Pointer>();
25872571
const Pointer &Dst = S.Stk.peek<Pointer>();
25882572

@@ -2635,10 +2619,8 @@ static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC,
26352619

26362620
if (!Arg0Type->isVectorType()) {
26372621
assert(!Call->getArg(1)->getType()->isVectorType());
2638-
APSInt RHS = popToAPSInt(
2639-
S.Stk, *S.getContext().classify(Call->getArg(1)->getType()));
2640-
APSInt LHS = popToAPSInt(
2641-
S.Stk, *S.getContext().classify(Call->getArg(0)->getType()));
2622+
APSInt RHS = popToAPSInt(S, Call->getArg(1));
2623+
APSInt LHS = popToAPSInt(S, Arg0Type);
26422624
APInt Result;
26432625
if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
26442626
Result = std::max(LHS, RHS);
@@ -2808,8 +2790,7 @@ static bool interp__builtin_select(InterpState &S, CodePtr OpPC,
28082790
const CallExpr *Call) {
28092791
const Pointer &RHS = S.Stk.pop<Pointer>();
28102792
const Pointer &LHS = S.Stk.pop<Pointer>();
2811-
PrimType MaskT = *S.getContext().classify(Call->getArg(0));
2812-
APSInt Mask = popToAPSInt(S.Stk, MaskT);
2793+
APSInt Mask = popToAPSInt(S, Call->getArg(0));
28132794
const Pointer &Dst = S.Stk.peek<Pointer>();
28142795

28152796
assert(LHS.getNumElems() == RHS.getNumElems());
@@ -2839,8 +2820,7 @@ static bool interp__builtin_select(InterpState &S, CodePtr OpPC,
28392820

28402821
static bool interp__builtin_blend(InterpState &S, CodePtr OpPC,
28412822
const CallExpr *Call) {
2842-
PrimType MaskT = *S.getContext().classify(Call->getArg(2));
2843-
APSInt Mask = popToAPSInt(S.Stk, MaskT);
2823+
APSInt Mask = popToAPSInt(S, Call->getArg(2));
28442824
const Pointer &TrueVec = S.Stk.pop<Pointer>();
28452825
const Pointer &FalseVec = S.Stk.pop<Pointer>();
28462826
const Pointer &Dst = S.Stk.peek<Pointer>();
@@ -2878,14 +2858,12 @@ static bool interp__builtin_elementwise_triop(
28782858
assert(Call->getNumArgs() == 3);
28792859

28802860
QualType Arg0Type = Call->getArg(0)->getType();
2881-
QualType Arg1Type = Call->getArg(1)->getType();
28822861
QualType Arg2Type = Call->getArg(2)->getType();
2883-
28842862
// Non-vector integer types.
28852863
if (!Arg0Type->isVectorType()) {
2886-
const APSInt &Op2 = popToAPSInt(S.Stk, *S.getContext().classify(Arg2Type));
2887-
const APSInt &Op1 = popToAPSInt(S.Stk, *S.getContext().classify(Arg1Type));
2888-
const APSInt &Op0 = popToAPSInt(S.Stk, *S.getContext().classify(Arg0Type));
2864+
const APSInt &Op2 = popToAPSInt(S, Arg2Type);
2865+
const APSInt &Op1 = popToAPSInt(S, Call->getArg(1));
2866+
const APSInt &Op0 = popToAPSInt(S, Arg0Type);
28892867
APSInt Result = APSInt(Fn(Op0, Op1, Op2), Op0.isUnsigned());
28902868
pushInteger(S, Result, Call->getType());
28912869
return true;
@@ -2898,8 +2876,7 @@ static bool interp__builtin_elementwise_triop(
28982876

28992877
// Vector + Vector + Scalar case.
29002878
if (!Arg2Type->isVectorType()) {
2901-
APSInt Op2 = popToAPSInt(
2902-
S.Stk, *S.getContext().classify(Call->getArg(2)->getType()));
2879+
APSInt Op2 = popToAPSInt(S, Arg2Type);
29032880

29042881
const Pointer &Op1 = S.Stk.pop<Pointer>();
29052882
const Pointer &Op0 = S.Stk.pop<Pointer>();

0 commit comments

Comments
 (0)