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:
parent
58987d2e34
commit
a65e0edd6a
@ -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
|
||||
|
@ -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};
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user