Skip to content

Commit 612a105

Browse files
authored
[clang][byte] Add callback mechanism to handle constexpr for unary integer ops (#160280)
Add interp__builtin_elementwise_int_unaryop - similar to what we already have with interp__builtin_elementwise_int_binop to handle binops Update x86 lzcnt/tzcnt intrinsics to use with a suitable callback I'll add vector handling in a future patch when we add x86 vector intrinsics that can use it
1 parent 004e462 commit 612a105

File tree

1 file changed

+26
-28
lines changed

1 file changed

+26
-28
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,32 +1380,6 @@ static bool interp__builtin_ia32_bzhi(InterpState &S, CodePtr OpPC,
13801380
return true;
13811381
}
13821382

1383-
static bool interp__builtin_ia32_lzcnt(InterpState &S, CodePtr OpPC,
1384-
const InterpFrame *Frame,
1385-
const CallExpr *Call) {
1386-
QualType CallType = Call->getType();
1387-
if (!CallType->isIntegerType() ||
1388-
!Call->getArg(0)->getType()->isIntegerType())
1389-
return false;
1390-
1391-
APSInt Val = popToAPSInt(S, Call->getArg(0));
1392-
pushInteger(S, Val.countLeadingZeros(), CallType);
1393-
return true;
1394-
}
1395-
1396-
static bool interp__builtin_ia32_tzcnt(InterpState &S, CodePtr OpPC,
1397-
const InterpFrame *Frame,
1398-
const CallExpr *Call) {
1399-
QualType CallType = Call->getType();
1400-
if (!CallType->isIntegerType() ||
1401-
!Call->getArg(0)->getType()->isIntegerType())
1402-
return false;
1403-
1404-
APSInt Val = popToAPSInt(S, Call->getArg(0));
1405-
pushInteger(S, Val.countTrailingZeros(), CallType);
1406-
return true;
1407-
}
1408-
14091383
static bool interp__builtin_ia32_pdep(InterpState &S, CodePtr OpPC,
14101384
const InterpFrame *Frame,
14111385
const CallExpr *Call) {
@@ -2551,6 +2525,24 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
25512525
return true;
25522526
}
25532527

2528+
static bool interp__builtin_elementwise_int_unaryop(
2529+
InterpState &S, CodePtr OpPC, const CallExpr *Call,
2530+
llvm::function_ref<APInt(const APSInt &)> Fn) {
2531+
assert(Call->getNumArgs() == 1);
2532+
assert(Call->getType()->isIntegerType());
2533+
2534+
// Single integer case.
2535+
if (!Call->getArg(0)->getType()->isVectorType()) {
2536+
APSInt Src = popToAPSInt(S, Call->getArg(0));
2537+
APInt Result = Fn(Src);
2538+
pushInteger(S, APSInt(std::move(Result), !Src.isSigned()), Call->getType());
2539+
return true;
2540+
}
2541+
2542+
// TODO: Add vector integer handling.
2543+
return false;
2544+
}
2545+
25542546
static bool interp__builtin_elementwise_int_binop(
25552547
InterpState &S, CodePtr OpPC, const CallExpr *Call,
25562548
llvm::function_ref<APInt(const APSInt &, const APSInt &)> Fn) {
@@ -3283,12 +3275,18 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
32833275
case clang::X86::BI__builtin_ia32_lzcnt_u16:
32843276
case clang::X86::BI__builtin_ia32_lzcnt_u32:
32853277
case clang::X86::BI__builtin_ia32_lzcnt_u64:
3286-
return interp__builtin_ia32_lzcnt(S, OpPC, Frame, Call);
3278+
return interp__builtin_elementwise_int_unaryop(
3279+
S, OpPC, Call, [](const APSInt &Src) {
3280+
return APInt(Src.getBitWidth(), Src.countLeadingZeros());
3281+
});
32873282

32883283
case clang::X86::BI__builtin_ia32_tzcnt_u16:
32893284
case clang::X86::BI__builtin_ia32_tzcnt_u32:
32903285
case clang::X86::BI__builtin_ia32_tzcnt_u64:
3291-
return interp__builtin_ia32_tzcnt(S, OpPC, Frame, Call);
3286+
return interp__builtin_elementwise_int_unaryop(
3287+
S, OpPC, Call, [](const APSInt &Src) {
3288+
return APInt(Src.getBitWidth(), Src.countTrailingZeros());
3289+
});
32923290

32933291
case clang::X86::BI__builtin_ia32_pdep_si:
32943292
case clang::X86::BI__builtin_ia32_pdep_di:

0 commit comments

Comments
 (0)