-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[clang][bytecode] Add callback mechanism to handle constexpr for unary integer ops #160280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][bytecode] Add callback mechanism to handle constexpr for unary integer ops #160280
Conversation
…teger ops 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
|
@llvm/pr-subscribers-clang Author: Simon Pilgrim (RKSimon) ChangesAdd 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 Full diff: https://github.com/llvm/llvm-project/pull/160280.diff 1 Files Affected:
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 4b259dab000b1..54b34ae1ca315 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1380,32 +1380,6 @@ static bool interp__builtin_ia32_bzhi(InterpState &S, CodePtr OpPC,
return true;
}
-static bool interp__builtin_ia32_lzcnt(InterpState &S, CodePtr OpPC,
- const InterpFrame *Frame,
- const CallExpr *Call) {
- QualType CallType = Call->getType();
- if (!CallType->isIntegerType() ||
- !Call->getArg(0)->getType()->isIntegerType())
- return false;
-
- APSInt Val = popToAPSInt(S, Call->getArg(0));
- pushInteger(S, Val.countLeadingZeros(), CallType);
- return true;
-}
-
-static bool interp__builtin_ia32_tzcnt(InterpState &S, CodePtr OpPC,
- const InterpFrame *Frame,
- const CallExpr *Call) {
- QualType CallType = Call->getType();
- if (!CallType->isIntegerType() ||
- !Call->getArg(0)->getType()->isIntegerType())
- return false;
-
- APSInt Val = popToAPSInt(S, Call->getArg(0));
- pushInteger(S, Val.countTrailingZeros(), CallType);
- return true;
-}
-
static bool interp__builtin_ia32_pdep(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
@@ -2551,6 +2525,23 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
return true;
}
+static bool interp__builtin_elementwise_int_unaryop(
+ InterpState &S, CodePtr OpPC, const CallExpr *Call,
+ llvm::function_ref<APInt(const APSInt &)> Fn) {
+ assert(Call->getType()->isIntegerType() && Call->getNumArgs() == 1);
+
+ // Single integer case.
+ if (!Call->getArg(0)->getType()->isVectorType()) {
+ APSInt Src = popToAPSInt(S, Call->getArg(0));
+ APInt Result = Fn(Src);
+ pushInteger(S, APSInt(std::move(Result), !Src.isSigned()), Call->getType());
+ return true;
+ }
+
+ // TODO: Add vector integer handling.
+ return false;
+}
+
static bool interp__builtin_elementwise_int_binop(
InterpState &S, CodePtr OpPC, const CallExpr *Call,
llvm::function_ref<APInt(const APSInt &, const APSInt &)> Fn) {
@@ -3283,12 +3274,18 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
case clang::X86::BI__builtin_ia32_lzcnt_u16:
case clang::X86::BI__builtin_ia32_lzcnt_u32:
case clang::X86::BI__builtin_ia32_lzcnt_u64:
- return interp__builtin_ia32_lzcnt(S, OpPC, Frame, Call);
+ return interp__builtin_elementwise_int_unaryop(
+ S, OpPC, Call, [](const APSInt &Src) {
+ return APInt(Src.getBitWidth(), Src.countLeadingZeros());
+ });
case clang::X86::BI__builtin_ia32_tzcnt_u16:
case clang::X86::BI__builtin_ia32_tzcnt_u32:
case clang::X86::BI__builtin_ia32_tzcnt_u64:
- return interp__builtin_ia32_tzcnt(S, OpPC, Frame, Call);
+ return interp__builtin_elementwise_int_unaryop(
+ S, OpPC, Call, [](const APSInt &Src) {
+ return APInt(Src.getBitWidth(), Src.countTrailingZeros());
+ });
case clang::X86::BI__builtin_ia32_pdep_si:
case clang::X86::BI__builtin_ia32_pdep_di:
|
| static bool interp__builtin_elementwise_int_unaryop( | ||
| InterpState &S, CodePtr OpPC, const CallExpr *Call, | ||
| llvm::function_ref<APInt(const APSInt &)> Fn) { | ||
| assert(Call->getType()->isIntegerType() && Call->getNumArgs() == 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be two separate asserts so we know what the problem is if it fails
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