[clang] 0611fdd - [clang][bytecode] Add simple __builtin_memcpy implementation (#118278)

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 2 04:11:26 PST 2024


Author: Timm Baeder
Date: 2024-12-02T13:11:22+01:00
New Revision: 0611fdd32046c41647a7719252166033f7bce2f2

URL: https://github.com/llvm/llvm-project/commit/0611fdd32046c41647a7719252166033f7bce2f2
DIFF: https://github.com/llvm/llvm-project/commit/0611fdd32046c41647a7719252166033f7bce2f2.diff

LOG: [clang][bytecode] Add simple __builtin_memcpy implementation (#118278)

Not handling all the special- and error cases yet. Just making sure the
bitcast code can be used for this as well.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/InterpBuiltin.cpp
    clang/test/AST/ByteCode/builtin-functions.cpp

Removed: 
    


################################################################################
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