[llvm] [llubi] Implement memory manipulation intrinsics (PR #204932)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 20 08:05:09 PDT 2026
================
@@ -698,6 +699,120 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
return V.asInteger();
}
+ AnyValue callMemTransferIntrinsic(ArrayRef<AnyValue> Args,
+ Intrinsic::ID IID) {
+ if (Args[2].isPoison()) {
+ reportImmediateUB() << "Memory transfer intrinsic with poison length.";
+ return AnyValue::poison();
+ }
+
+ const APInt &Length = Args[2].asInteger();
+ if (Length.getActiveBits() > 64) {
+ reportImmediateUB()
+ << "Memory transfer intrinsic length overflows uint64_t.";
+ return AnyValue::poison();
+ }
+
+ const uint64_t Len = Length.getZExtValue();
+ if (Len == 0)
+ return AnyValue();
+
+ if (Args[0].isPoison()) {
+ reportImmediateUB()
+ << "Memory transfer intrinsic with poison destination pointer.";
+ return AnyValue::poison();
+ }
+
+ if (Args[1].isPoison()) {
+ reportImmediateUB()
+ << "Memory copy intrinsic with poison source pointer.";
+ return AnyValue::poison();
+ }
+
+ const Pointer &DstPtr = Args[0].asPointer();
+ const Pointer &SrcPtr = Args[1].asPointer();
+
+ auto [SrcMO, SrcOffset] =
+ verifyMemAccess(SrcPtr, Len, Align(1), /*IsStore=*/false);
+ if (!SrcMO)
+ return AnyValue();
+
+ auto [DstMO, DstOffset] =
+ verifyMemAccess(DstPtr, Len, Align(1), /*IsStore=*/true);
+ if (!DstMO)
+ return AnyValue();
+
+ if (DstMO->isConstant()) {
+ reportImmediateUB() << "Try to write to a constant memory object: "
+ << DstPtr << ".";
+ return AnyValue::poison();
+ }
+
+ if (IID == Intrinsic::memcpy || IID == Intrinsic::memcpy_inline) {
+ if (SrcMO == DstMO && SrcOffset != DstOffset) {
+ const uint64_t SrcEnd = SrcOffset + Len;
+ const uint64_t DstEnd = DstOffset + Len;
+ if (SrcOffset < DstEnd && DstOffset < SrcEnd) {
+ reportImmediateUB()
+ << "memcpy with overlapping source and destination.";
+ return AnyValue::poison();
+ }
+ }
+ }
+
+ SmallVector<Byte, 16> Tmp;
+ if (SrcMO->getState() == MemoryObjectState::Dead) {
+ Tmp.assign(Len, Byte::poison());
+ } else {
+ ArrayRef<Byte> SrcBytes = SrcMO->getBytes().slice(SrcOffset, Len);
+ Tmp.assign(SrcBytes);
+ }
+ MutableArrayRef<Byte> DstBytes = DstMO->getBytes().slice(DstOffset, Len);
+ copy(Tmp, DstBytes.begin());
----------------
dtcxzyw wrote:
I guess memmove will handle the overlapping case, so we don't need a copy here, no?
https://github.com/llvm/llvm-project/pull/204932
More information about the llvm-commits
mailing list