Skip to content

Commit 093439c

Browse files
authored
[PowerPC][AIX] Using milicode for memcmp instead of libcall (#147093)
AIX has "millicode" routines, which are functions loaded at boot time into fixed addresses in kernel memory. This allows them to be customized for the processor. The __memcmp routine is a millicode implementation; we use millicode for the memcmp function instead of a library call to improve performance.
1 parent d97f0e9 commit 093439c

File tree

11 files changed

+62
-9
lines changed

11 files changed

+62
-9
lines changed

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,9 @@ class SelectionDAG {
12601260
/// stack arguments from being clobbered.
12611261
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain);
12621262

1263+
std::pair<SDValue, SDValue> getMemcmp(SDValue Chain, const SDLoc &dl,
1264+
SDValue Dst, SDValue Src, SDValue Size,
1265+
const CallInst *CI);
12631266
/* \p CI if not null is the memset call being lowered.
12641267
* \p OverrideTailCall is an optional parameter that can be used to override
12651268
* the tail call optimization decision. */

llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
namespace llvm {
2525

26+
class CallInst;
2627
class SelectionDAG;
2728

2829
//===----------------------------------------------------------------------===//
@@ -118,8 +119,7 @@ class SelectionDAGTargetInfo {
118119
virtual std::pair<SDValue, SDValue>
119120
EmitTargetCodeForMemcmp(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain,
120121
SDValue Op1, SDValue Op2, SDValue Op3,
121-
MachinePointerInfo Op1PtrInfo,
122-
MachinePointerInfo Op2PtrInfo) const {
122+
const CallInst *CI) const {
123123
return std::make_pair(SDValue(), SDValue());
124124
}
125125

llvm/include/llvm/IR/RuntimeLibcalls.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ foreach FPTy = ["F32", "F64", "F128", "PPCF128"] in {
276276
}
277277

278278
// Memory
279+
def MEMCMP : RuntimeLibcall;
279280
def MEMCPY : RuntimeLibcall;
280281
def MEMMOVE : RuntimeLibcall;
281282
def MEMSET : RuntimeLibcall;
@@ -1990,12 +1991,14 @@ defset list<RuntimeLibcallImpl> PPCRuntimeLibcalls = {
19901991
}
19911992

19921993
defset list<RuntimeLibcallImpl> PPC64AIXCallList = {
1994+
def ___memcmp64 : RuntimeLibcallImpl<MEMCMP>;
19931995
def ___memmove64 : RuntimeLibcallImpl<MEMCPY>;
19941996
def ___memset64 : RuntimeLibcallImpl<MEMSET>;
19951997
def ___bzero64 : RuntimeLibcallImpl<BZERO>;
19961998
}
19971999

19982000
defset list<RuntimeLibcallImpl> PPC32AIXCallList = {
2001+
def ___memcmp : RuntimeLibcallImpl<MEMCMP>;
19992002
def ___memmove : RuntimeLibcallImpl<MEMMOVE>;
20002003
def ___memset : RuntimeLibcallImpl<MEMSET>;
20012004
def ___bzero : RuntimeLibcallImpl<BZERO>;

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8889,6 +8889,44 @@ static void checkAddrSpaceIsValidForLibcall(const TargetLowering *TLI,
88898889
}
88908890
}
88918891

8892+
std::pair<SDValue, SDValue>
8893+
SelectionDAG::getMemcmp(SDValue Chain, const SDLoc &dl, SDValue Mem0,
8894+
SDValue Mem1, SDValue Size, const CallInst *CI) {
8895+
const char *LibCallName = TLI->getLibcallName(RTLIB::MEMCMP);
8896+
if (!LibCallName)
8897+
return {};
8898+
8899+
// Emit a library call.
8900+
auto GetEntry = [](Type *Ty, SDValue &SDV) {
8901+
TargetLowering::ArgListEntry E;
8902+
E.Ty = Ty;
8903+
E.Node = SDV;
8904+
return E;
8905+
};
8906+
8907+
PointerType *PT = PointerType::getUnqual(*getContext());
8908+
TargetLowering::ArgListTy Args = {
8909+
GetEntry(PT, Mem0), GetEntry(PT, Mem1),
8910+
GetEntry(getDataLayout().getIntPtrType(*getContext()), Size)};
8911+
8912+
TargetLowering::CallLoweringInfo CLI(*this);
8913+
bool IsTailCall = false;
8914+
bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
8915+
IsTailCall = CI && CI->isTailCall() &&
8916+
isInTailCallPosition(*CI, getTarget(), ReturnsFirstArg);
8917+
8918+
CLI.setDebugLoc(dl)
8919+
.setChain(Chain)
8920+
.setLibCallee(
8921+
TLI->getLibcallCallingConv(RTLIB::MEMCMP),
8922+
Type::getInt32Ty(*getContext()),
8923+
getExternalSymbol(LibCallName, TLI->getPointerTy(getDataLayout())),
8924+
std::move(Args))
8925+
.setTailCall(IsTailCall);
8926+
8927+
return TLI->LowerCallTo(CLI);
8928+
}
8929+
88928930
SDValue SelectionDAG::getMemcpy(
88938931
SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size,
88948932
Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI,

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9090,7 +9090,7 @@ bool SelectionDAGBuilder::visitMemCmpBCmpCall(const CallInst &I) {
90909090
const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo();
90919091
std::pair<SDValue, SDValue> Res = TSI.EmitTargetCodeForMemcmp(
90929092
DAG, getCurSDLoc(), DAG.getRoot(), getValue(LHS), getValue(RHS),
9093-
getValue(Size), MachinePointerInfo(LHS), MachinePointerInfo(RHS));
9093+
getValue(Size), &I);
90949094
if (Res.first.getNode()) {
90959095
processIntegerCallValue(I, Res.first, true);
90969096
PendingLoads.push_back(Res.second);

llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ bool PPCSelectionDAGInfo::isTargetStrictFPOpcode(unsigned Opcode) const {
2222
return Opcode >= PPCISD::FIRST_STRICTFP_OPCODE &&
2323
Opcode <= PPCISD::LAST_STRICTFP_OPCODE;
2424
}
25+
26+
std::pair<SDValue, SDValue> PPCSelectionDAGInfo::EmitTargetCodeForMemcmp(
27+
SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2,
28+
SDValue Op3, const CallInst *CI) const {
29+
return DAG.getMemcmp(Chain, dl, Op1, Op2, Op3, CI);
30+
}

llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ class PPCSelectionDAGInfo : public SelectionDAGTargetInfo {
2020
bool isTargetMemoryOpcode(unsigned Opcode) const override;
2121

2222
bool isTargetStrictFPOpcode(unsigned Opcode) const override;
23+
24+
std::pair<SDValue, SDValue>
25+
EmitTargetCodeForMemcmp(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain,
26+
SDValue Op1, SDValue Op2, SDValue Op3,
27+
const CallInst *CI) const;
2328
};
2429

2530
} // namespace llvm

llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,7 @@ static SDValue addIPMSequence(const SDLoc &DL, SDValue CCReg,
181181

182182
std::pair<SDValue, SDValue> SystemZSelectionDAGInfo::EmitTargetCodeForMemcmp(
183183
SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Src1,
184-
SDValue Src2, SDValue Size, MachinePointerInfo Op1PtrInfo,
185-
MachinePointerInfo Op2PtrInfo) const {
184+
SDValue Src2, SDValue Size, const CallInst *CI) const {
186185
SDValue CCReg;
187186
// Swap operands to invert CC == 1 vs. CC == 2 cases.
188187
if (auto *CSize = dyn_cast<ConstantSDNode>(Size)) {

llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ class SystemZSelectionDAGInfo : public SelectionDAGTargetInfo {
4141
std::pair<SDValue, SDValue>
4242
EmitTargetCodeForMemcmp(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
4343
SDValue Src1, SDValue Src2, SDValue Size,
44-
MachinePointerInfo Op1PtrInfo,
45-
MachinePointerInfo Op2PtrInfo) const override;
44+
const CallInst *CI) const override;
4645

4746
std::pair<SDValue, SDValue>
4847
EmitTargetCodeForMemchr(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,

llvm/test/CodeGen/PowerPC/memintr32.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ define i32 @memcmp_test(ptr nocapture noundef readonly %ptr1, ptr nocapture noun
1111
; CHECK-AIX-32-P9-NEXT: mflr r0
1212
; CHECK-AIX-32-P9-NEXT: stwu r1, -64(r1)
1313
; CHECK-AIX-32-P9-NEXT: stw r0, 72(r1)
14-
; CHECK-AIX-32-P9-NEXT: bl .memcmp[PR]
14+
; CHECK-AIX-32-P9-NEXT: bl .___memcmp[PR]
1515
; CHECK-AIX-32-P9-NEXT: nop
1616
; CHECK-AIX-32-P9-NEXT: addi r1, r1, 64
1717
; CHECK-AIX-32-P9-NEXT: lwz r0, 8(r1)

0 commit comments

Comments
 (0)