[clang] [clang][bytecode] Implement __builtin_ai32_addcarryx* (PR #111671)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 9 05:57:01 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/111671.diff
2 Files Affected:
- (modified) clang/lib/AST/ByteCode/Function.h (+4)
- (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+50)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Function.h b/clang/lib/AST/ByteCode/Function.h
index 640bfa65644f0f..7fe9aeb1101204 100644
--- a/clang/lib/AST/ByteCode/Function.h
+++ b/clang/lib/AST/ByteCode/Function.h
@@ -222,6 +222,10 @@ class Function final {
return ParamOffsets[ParamIndex];
}
+ PrimType getParamType(unsigned ParamIndex) const {
+ return ParamTypes[ParamIndex];
+ }
+
private:
/// Construct a function representing an actual function.
Function(Program &P, FunctionDeclTy Source, unsigned ArgSize,
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 98381254886e29..7d811b7baea7ce 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -38,6 +38,15 @@ static T getParam(const InterpFrame *Frame, unsigned Index) {
return Frame->getParam<T>(Offset);
}
+// static APSInt getAPSIntParam(InterpStack &Stk, size_t Offset = 0) {
+static APSInt getAPSIntParam(const InterpFrame *Frame, unsigned Index) {
+ APSInt R;
+ unsigned Offset = Frame->getFunction()->getParamOffset(Index);
+ INT_TYPE_SWITCH(Frame->getFunction()->getParamType(Index),
+ R = Frame->getParam<T>(Offset).toAPSInt());
+ return R;
+}
+
PrimType getIntPrimType(const InterpState &S) {
const TargetInfo &TI = S.getASTContext().getTargetInfo();
unsigned IntWidth = TI.getIntWidth();
@@ -1273,6 +1282,39 @@ static bool interp__builtin_ia32_pext(InterpState &S, CodePtr OpPC,
return true;
}
+static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S,
+ CodePtr OpPC,
+ const InterpFrame *Frame,
+ const Function *Func,
+ const CallExpr *Call) {
+ unsigned BuiltinOp = Func->getBuiltinID();
+ APSInt CarryIn = getAPSIntParam(Frame, 0);
+ APSInt LHS = getAPSIntParam(Frame, 1);
+ APSInt RHS = getAPSIntParam(Frame, 2);
+
+ bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
+ BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
+
+ unsigned BitWidth = LHS.getBitWidth();
+ unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
+ APInt ExResult =
+ IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
+ : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
+
+ APInt Result = ExResult.extractBits(BitWidth, 0);
+ APSInt CarryOut =
+ APSInt(ExResult.extractBits(1, BitWidth), /*IsUnsigned=*/true);
+
+ Pointer &CarryOutPtr = S.Stk.peek<Pointer>();
+ QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType();
+ PrimType CarryOutT = *S.getContext().classify(CarryOutType);
+ assignInteger(CarryOutPtr, CarryOutT, APSInt(Result, true));
+
+ pushInteger(S, CarryOut, Call->getType());
+
+ return true;
+}
+
static bool interp__builtin_os_log_format_buffer_size(InterpState &S,
CodePtr OpPC,
const InterpFrame *Frame,
@@ -1898,6 +1940,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
return false;
break;
+ case clang::X86::BI__builtin_ia32_addcarryx_u32:
+ case clang::X86::BI__builtin_ia32_addcarryx_u64:
+ case clang::X86::BI__builtin_ia32_subborrow_u32:
+ case clang::X86::BI__builtin_ia32_subborrow_u64:
+ if (!interp__builtin_ia32_addcarry_subborrow(S, OpPC, Frame, F, Call))
+ return false;
+ break;
+
case Builtin::BI__builtin_os_log_format_buffer_size:
if (!interp__builtin_os_log_format_buffer_size(S, OpPC, Frame, F, Call))
return false;
``````````
</details>
https://github.com/llvm/llvm-project/pull/111671
More information about the cfe-commits
mailing list