[clang] [clang][bytecode] Add simple __builtin_memcpy implementation (PR #118278)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 2 03:13:23 PST 2024
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/118278
>From bcb316bd8f2b6a143cb303f1e67c6bbc04c8c986 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 2 Dec 2024 10:45:52 +0100
Subject: [PATCH] [clang][bytecode] Add simple __builtin_memcpy implementation
Not handling all the special- and error cases yet. Just making sure the
bitcast code can be used for this as well.
---
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 31 +++++++++++++++++++
clang/test/AST/ByteCode/builtin-functions.cpp | 11 ++++++-
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 080fa891e641e3..8ede6717db0463 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1723,6 +1723,32 @@ static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC,
llvm_unreachable("Unsupported vector reduce builtin");
}
+static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const Function *Func, const CallExpr *Call) {
+ assert(Call->getNumArgs() == 3);
+ Pointer DestPtr = getParam<Pointer>(Frame, 0);
+ const Pointer &SrcPtr = getParam<Pointer>(Frame, 1);
+ const APSInt &Size =
+ peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2)));
+ assert(!Size.isSigned() && "memcpy and friends take an unsigned size");
+
+ if (DestPtr.isDummy() || SrcPtr.isDummy())
+ return false;
+
+ // If the size is zero, we treat this as always being a valid no-op.
+ if (Size.isZero()) {
+ S.Stk.push<Pointer>(DestPtr);
+ return true;
+ }
+
+ if (!DoBitCastPtr(S, OpPC, SrcPtr, DestPtr))
+ return false;
+
+ S.Stk.push<Pointer>(DestPtr);
+ return true;
+}
+
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
const CallExpr *Call, uint32_t BuiltinID) {
const InterpFrame *Frame = S.Current;
@@ -2173,6 +2199,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
return false;
break;
+ case Builtin::BI__builtin_memcpy:
+ if (!interp__builtin_memcpy(S, OpPC, Frame, F, Call))
+ return false;
+ break;
+
default:
S.FFDiag(S.Current->getLocation(OpPC),
diag::note_invalid_subexpr_in_const_expr)
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index 972d39ca509615..78b692b819a0ab 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -991,7 +991,6 @@ namespace BuiltinInImplicitCtor {
static_assert(Foo.a == 0, "");
}
-
typedef double vector4double __attribute__((__vector_size__(32)));
typedef float vector4float __attribute__((__vector_size__(16)));
typedef long long vector4long __attribute__((__vector_size__(32)));
@@ -1035,3 +1034,13 @@ namespace RecuceAdd {
static_assert(reduceAddInt3 == 0);
#endif
}
+
+namespace BuiltinMemcpy {
+ constexpr int simple() {
+ int a = 12;
+ int b = 0;
+ __builtin_memcpy(&b, &a, sizeof(a));
+ return b;
+ }
+ static_assert(simple() == 12);
+}
More information about the cfe-commits
mailing list