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

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 3 08:05:00 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())
----------------
JonPsson1 wrote:

I guess this is because MVC <= 16 bytes can't be used with memmove as the operands may overlap. Treating them the same here would result in libcalls for all those shorter lengths, but the idea was to use at most 2 stores (see memmove-01.ll), or?


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


More information about the llvm-commits mailing list