PowerPC: Stop reporting memcpy as an alias of memmove on AIX (#143836)

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.
This commit is contained in:
Matt Arsenault 2025-06-23 22:15:37 +09:00 committed by GitHub
parent 58987d2e34
commit a65e0edd6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 35 additions and 11 deletions

View File

@ -3572,6 +3572,8 @@ public:
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 should be removed

View File

@ -106,6 +106,16 @@ struct RuntimeLibcallsInfo {
SoftFloatCompareLibcallPredicates[Call] = Pred;
}
/// 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] = {nullptr};

View File

@ -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) {

View File

@ -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

View File

@ -8776,11 +8776,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(),
@ -8789,11 +8790,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);

View File

@ -416,7 +416,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");