[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