[llvm] [ARM] Explicitly specify i32 as ideal memcpy size type on ARM (NFC) (PR #194990)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 29 18:24:41 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: LumioseSil (LumioseSil)

<details>
<summary>Changes</summary>

No change but saves a lot of lookups in target independent logic. Also refactored to be more clear in intent.

---
Full diff: https://github.com/llvm/llvm-project/pull/194990.diff


2 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+1-1) 
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+18-13) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index b23bbd7234177..c9b4d8166b4df 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -18927,7 +18927,7 @@ EVT AArch64TargetLowering::getOptimalMemOpType(
   // taken one instruction to materialize the v2i64 zero and one store (with
   // restrictive addressing mode). Just do i64 stores.
   // For non-zero memset, use NEON even for smaller sizes as dup is efficient.
-  bool IsSmallZeroMemset = Op.isMemset() && Op.size() < 32 && Op.isZeroMemset();
+  bool IsSmallZeroMemset = Op.size() < 32 && Op.isZeroMemset();
   auto AlignmentIsAcceptable = [&](EVT VT, Align AlignCheck) {
     if (Op.isAligned(AlignCheck))
       return true;
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 71cc6cf8e1f82..9a2207b90bac4 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -19250,24 +19250,29 @@ EVT ARMTargetLowering::getOptimalMemOpType(
     LLVMContext &Context, const MemOp &Op,
     const AttributeList &FuncAttributes) const {
   // See if we can use NEON instructions for this...
-  if ((Op.isMemcpy() || Op.isZeroMemset()) && Subtarget->hasNEON() &&
-      !FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat)) {
+  bool CanImplicitFloat = !FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat);
+  bool CanUseNEON = Subtarget->hasNEON() && CanImplicitFloat;
+
+  auto AlignmentIsAcceptable = [&](EVT VT, Align AlignCheck) {
+    if (Op.isAligned(AlignCheck))
+      return true;
     unsigned Fast;
-    if (Op.size() >= 16 &&
-        (Op.isAligned(Align(16)) ||
-         (allowsMisalignedMemoryAccesses(MVT::v2f64, 0, Align(1),
-                                         MachineMemOperand::MONone, &Fast) &&
-          Fast))) {
+    return allowsMisalignedMemoryAccesses(VT, 0, Align(1),
+                                          MachineMemOperand::MONone, &Fast) &&
+           Fast;
+  };
+
+  // NEON vld1/vst1 as v2f64 (16-byte) or f64 (8-byte) for memcpy / zero memset.
+  if ((Op.isMemcpy() || Op.isZeroMemset()) && CanUseNEON) {
+    if (Op.size() >= 16 && AlignmentIsAcceptable(MVT::v2f64, Align(16)))
       return MVT::v2f64;
-    } else if (Op.size() >= 8 &&
-               (Op.isAligned(Align(8)) ||
-                (allowsMisalignedMemoryAccesses(
-                     MVT::f64, 0, Align(1), MachineMemOperand::MONone, &Fast) &&
-                 Fast))) {
+    if (Op.size() >= 8 && AlignmentIsAcceptable(MVT::f64, Align(8)))
       return MVT::f64;
-    }
   }
 
+  if (Op.size() >= 4 && AlignmentIsAcceptable(MVT::i32, Align(4)))
+    return MVT::i32;
+
   // Let the target-independent logic figure it out.
   return MVT::Other;
 }

``````````

</details>


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


More information about the llvm-commits mailing list