https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/160280
>From aa0089b03b31e0c0750471a10e21ff9c07122e85 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <[email protected]> Date: Tue, 23 Sep 2025 12:36:21 +0100 Subject: [PATCH 1/2] [clang][byte] Add callback mechanism to handle constexpr for unary integer 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 --- clang/lib/AST/ByteCode/InterpBuiltin.cpp | 53 +++++++++++------------- 1 file changed, 25 insertions(+), 28 deletions(-) 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: >From b587ab68e8327838f5dc174318816499f14b4915 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim <[email protected]> Date: Tue, 23 Sep 2025 13:09:47 +0100 Subject: [PATCH 2/2] Split asserts --- clang/lib/AST/ByteCode/InterpBuiltin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 54b34ae1ca315..aaab8ade0ae01 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2528,7 +2528,8 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC, 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); + assert(Call->getNumArgs() == 1); + assert(Call->getType()->isIntegerType()); // Single integer case. if (!Call->getArg(0)->getType()->isVectorType()) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
