[llvm] PowerPC: Stop reporting memcpy as an alias of memmove on AIX (PR #143836)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 11 22:49:59 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-powerpc
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
Instead of reporting ___memmove as an implementation of memcpy,
make it unavailable and let the lowering logic consider memmove as
a fallback path.
This avoids a special case 1:N mapping for libcall implementations.
---
Full diff: https://github.com/llvm/llvm-project/pull/143836.diff
6 Files Affected:
- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+2)
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.h (+10)
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+5-1)
- (modified) llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp (+9-2)
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+8-7)
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+1-1)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 04bc0e9353101..f196f8d89917b 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3572,6 +3572,8 @@ class LLVM_ABI TargetLoweringBase {
return Libcalls.getLibcallName(Call);
}
+ const char *getMemcpyName() const { return Libcalls.getMemcpyName(); }
+
/// Override the default CondCode to be used to test the result of the
/// comparison libcall against zero.
/// FIXME: This can't be merged with 'RuntimeLibcallsInfo' because of the ISD.
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index 051bcc147cb71..b1a4e63245928 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -86,6 +86,16 @@ struct RuntimeLibcallsInfo {
return ArrayRef(LibcallRoutineNames).drop_back();
}
+ /// Return a function name compatible with RTLIB::MEMCPY, or nullptr if fully
+ /// unsupported.
+ const char *getMemcpyName() const {
+ if (const char *Memcpy = getLibcallName(RTLIB::MEMCPY))
+ return Memcpy;
+
+ // Fallback to memmove if memcpy isn't available.
+ return getLibcallName(RTLIB::MEMMOVE);
+ }
+
private:
/// Stores the name each libcall.
const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1];
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 83ba71e4c9d49..d3ce781617645 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -672,26 +672,30 @@ llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
RTLIB::Libcall RTLibcall;
unsigned Opc = MI.getOpcode();
+ const char *Name;
switch (Opc) {
case TargetOpcode::G_BZERO:
RTLibcall = RTLIB::BZERO;
+ Name = TLI.getLibcallName(RTLibcall);
break;
case TargetOpcode::G_MEMCPY:
RTLibcall = RTLIB::MEMCPY;
+ Name = TLI.getMemcpyName();
Args[0].Flags[0].setReturned();
break;
case TargetOpcode::G_MEMMOVE:
RTLibcall = RTLIB::MEMMOVE;
+ Name = TLI.getLibcallName(RTLibcall);
Args[0].Flags[0].setReturned();
break;
case TargetOpcode::G_MEMSET:
RTLibcall = RTLIB::MEMSET;
+ Name = TLI.getLibcallName(RTLibcall);
Args[0].Flags[0].setReturned();
break;
default:
llvm_unreachable("unsupported opcode");
}
- const char *Name = TLI.getLibcallName(RTLibcall);
// Unsupported libcall on the target.
if (!Name) {
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index 6f52b7cac1d46..9d1d70b1cb234 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -231,6 +231,14 @@ static bool canEmitLibcall(const TargetMachine *TM, Function *F,
return TLI->getLibcallName(LC) != nullptr;
}
+static bool canEmitMemcpy(const TargetMachine *TM, Function *F) {
+ // TODO: Should this consider the address space of the memcpy?
+ if (!TM)
+ return true;
+ const TargetLowering *TLI = TM->getSubtargetImpl(*F)->getTargetLowering();
+ return TLI->getMemcpyName() != nullptr;
+}
+
// Return a value appropriate for use with the memset_pattern16 libcall, if
// possible and if we know how. (Adapted from equivalent helper in
// LoopIdiomRecognize).
@@ -300,8 +308,7 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const {
Function *ParentFunc = Memcpy->getFunction();
const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
if (shouldExpandMemIntrinsicWithSize(Memcpy->getLength(), TTI)) {
- if (UseMemIntrinsicLibFunc &&
- canEmitLibcall(TM, ParentFunc, RTLIB::MEMCPY))
+ if (UseMemIntrinsicLibFunc && canEmitMemcpy(TM, ParentFunc))
break;
// TODO: For optsize, emit the loop into a separate function
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 45a37622a531b..0f6366f448c83 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -8765,11 +8765,12 @@ SDValue SelectionDAG::getMemcpy(
// FIXME: pass in SDLoc
TargetLowering::CallLoweringInfo CLI(*this);
bool IsTailCall = false;
+ const char *MemCpyName = TLI->getMemcpyName();
+
if (OverrideTailCall.has_value()) {
IsTailCall = *OverrideTailCall;
} else {
- bool LowersToMemcpy =
- TLI->getLibcallName(RTLIB::MEMCPY) == StringRef("memcpy");
+ bool LowersToMemcpy = StringRef(MemCpyName) == StringRef("memcpy");
bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
IsTailCall = CI && CI->isTailCall() &&
isInTailCallPosition(*CI, getTarget(),
@@ -8778,11 +8779,11 @@ SDValue SelectionDAG::getMemcpy(
CLI.setDebugLoc(dl)
.setChain(Chain)
- .setLibCallee(TLI->getLibcallCallingConv(RTLIB::MEMCPY),
- Dst.getValueType().getTypeForEVT(*getContext()),
- getExternalSymbol(TLI->getLibcallName(RTLIB::MEMCPY),
- TLI->getPointerTy(getDataLayout())),
- std::move(Args))
+ .setLibCallee(
+ TLI->getLibcallCallingConv(RTLIB::MEMCPY),
+ Dst.getValueType().getTypeForEVT(*getContext()),
+ getExternalSymbol(MemCpyName, TLI->getPointerTy(getDataLayout())),
+ std::move(Args))
.setDiscardResult()
.setTailCall(IsTailCall);
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 31013310a746d..0bc771c42102e 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -325,7 +325,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
if (TT.isOSAIX()) {
bool isPPC64 = TT.isPPC64();
- setLibcallName(RTLIB::MEMCPY, isPPC64 ? "___memmove64" : "___memmove");
+ setLibcallName(RTLIB::MEMCPY, nullptr);
setLibcallName(RTLIB::MEMMOVE, isPPC64 ? "___memmove64" : "___memmove");
setLibcallName(RTLIB::MEMSET, isPPC64 ? "___memset64" : "___memset");
setLibcallName(RTLIB::BZERO, isPPC64 ? "___bzero64" : "___bzero");
``````````
</details>
https://github.com/llvm/llvm-project/pull/143836
More information about the llvm-commits
mailing list