[llvm] [SystemZ] Avoid unaligned/overlapping accesses with memcpy/memset. (PR #187100)

Ulrich Weigand via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 31 08:22:40 PDT 2026


================
@@ -1458,20 +1462,34 @@ bool SystemZTargetLowering::findOptimalMemOpLowering(
     LLVMContext &Context, std::vector<EVT> &MemOps, unsigned Limit,
     const MemOp &Op, unsigned DstAS, unsigned SrcAS,
     const AttributeList &FuncAttributes, EVT *LargestVT) const {
-  const int MVCFastLen = 16;
 
-  if (Limit != ~unsigned(0)) {
-    // Don't expand Op into scalar loads/stores in these cases:
-    if (Op.isMemcpy() && Op.allowOverlap() && Op.size() <= MVCFastLen)
-      return false; // Small memcpy: Use MVC
-    if (Op.isMemset() && Op.size() - 1 <= MVCFastLen)
-      return false; // Small memset (first byte with STC/MVI): Use MVC
-    if (Op.isZeroMemset())
-      return false; // Memset zero: Use XC
-  }
+  assert(Limit != ~0U &&
+         "Expected EmitTargetCodeForMemXXX() to handle AlwaysInline cases.");
+
+  if (Op.isZeroMemset())
+    return false; // Memset zero: Use XC.
+
+  // Don't lower unaligned operations.
+  unsigned ReqAlign = Op.size() >= 8 ? 8 : (Op.size() >= 4 ? 4 : 2);
+  if (!Op.isFixedDstAlign() || !Op.isAligned(Align(ReqAlign)))
+    return false;
 
-  return TargetLowering::findOptimalMemOpLowering(
-      Context, MemOps, Limit, Op, DstAS, SrcAS, FuncAttributes, LargestVT);
+  // Try to lower Op with target instructions if those instructions will not
+  // be overlapping.
+  bool TryMemOpLowering = !Op.allowOverlap();
+  if (Op.allowOverlap())
----------------
uweigand wrote:

I'm not sure I understand the logic here.  Why do we even need to special-case memmove and have it always fall into the default `findOptimalMemOpLowering` logic?   It seems to be we should just treat memcpy and memmove the same here.

https://github.com/llvm/llvm-project/pull/187100


More information about the llvm-commits mailing list