[llvm] [llubi] Implement memory manipulation intrinsics (PR #204932)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 24 00:22:30 PDT 2026
================
@@ -698,6 +700,118 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
return V.asInteger();
}
+ AnyValue callMemTransferIntrinsic(CallBase &CB, ArrayRef<AnyValue> Args,
+ Intrinsic::ID IID) {
+ const AnyValue &Dest = Args[0];
+ const AnyValue &Src = Args[1];
+ const AnyValue &Length = Args[2];
+ // TODO: Handle isvolatile argument.
+ if (Length.isPoison()) {
+ reportImmediateUB() << "Memory transfer intrinsic with poison length.";
+ return AnyValue();
+ }
+
+ const APInt &LengthInt = Args[2].asInteger();
+ if (LengthInt.getActiveBits() > 64) {
+ reportImmediateUB()
+ << "Memory transfer intrinsic length overflows uint64_t.";
+ return AnyValue();
+ }
+
+ const uint64_t Len = LengthInt.getZExtValue();
+ if (Len == 0)
+ return AnyValue();
+
+ if (Dest.isPoison()) {
+ reportImmediateUB()
+ << "Memory transfer intrinsic with poison destination pointer.";
+ return AnyValue();
+ }
+
+ if (Src.isPoison()) {
+ reportImmediateUB()
+ << "Memory transfer intrinsic with poison source pointer.";
+ return AnyValue();
+ }
+
+ const Pointer &DstPtr = Dest.asPointer();
+ const Pointer &SrcPtr = Src.asPointer();
+
+ Align DstAlign = CB.getParamAlign(0).valueOrOne();
+ Align SrcAlign = CB.getParamAlign(1).valueOrOne();
+
+ auto [SrcMO, SrcOffset] =
+ verifyMemAccess(SrcPtr, Len, SrcAlign, /*IsStore=*/false);
+ if (!SrcMO)
+ return AnyValue();
+
+ auto [DstMO, DstOffset] =
+ verifyMemAccess(DstPtr, Len, DstAlign, /*IsStore=*/true);
+ if (!DstMO)
+ return AnyValue();
+
+ 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();
+ }
+ }
+ }
+
+ MutableArrayRef<Byte> DstBytes = DstMO->getBytes().slice(DstOffset, Len);
+ if (SrcMO->getState() == MemoryObjectState::Dead) {
----------------
nikic wrote:
Why does this case require special handling?
https://github.com/llvm/llvm-project/pull/204932
More information about the llvm-commits
mailing list