Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,9 @@ class SelectionDAG {
std::pair<SDValue, SDValue> getMemcmp(SDValue Chain, const SDLoc &dl,
SDValue Dst, SDValue Src, SDValue Size,
const CallInst *CI);
LLVM_ABI std::pair<SDValue, SDValue>
getStrlen(SDValue Chain, const SDLoc &dl, SDValue Src, const CallInst *CI);

/* \p CI if not null is the memset call being lowered.
* \p OverrideTailCall is an optional parameter that can be used to override
* the tail call optimization decision. */
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class SelectionDAGTargetInfo {

virtual std::pair<SDValue, SDValue>
EmitTargetCodeForStrlen(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
SDValue Src, MachinePointerInfo SrcPtrInfo) const {
SDValue Src, const CallInst *CI) const {
return std::make_pair(SDValue(), SDValue());
}

Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/RuntimeLibcalls.td
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ def MEMMOVE : RuntimeLibcall;
def MEMSET : RuntimeLibcall;
def CALLOC : RuntimeLibcall;
def BZERO : RuntimeLibcall;
def STRLEN : RuntimeLibcall;

// Element-wise unordered-atomic memory of different sizes
foreach MemSize = [1, 2, 4, 8, 16] in {
Expand Down Expand Up @@ -2115,13 +2116,15 @@ defset list<RuntimeLibcallImpl> PPC64AIXCallList = {
def ___memmove64 : RuntimeLibcallImpl<MEMCPY>;
def ___memset64 : RuntimeLibcallImpl<MEMSET>;
def ___bzero64 : RuntimeLibcallImpl<BZERO>;
def ___strlen64 : RuntimeLibcallImpl<STRLEN>;
}

defset list<RuntimeLibcallImpl> PPC32AIXCallList = {
def ___memcmp : RuntimeLibcallImpl<MEMCMP>;
def ___memmove : RuntimeLibcallImpl<MEMMOVE>;
def ___memset : RuntimeLibcallImpl<MEMSET>;
def ___bzero : RuntimeLibcallImpl<BZERO>;
def ___strlen : RuntimeLibcallImpl<STRLEN>;
}

defvar PPCOverrides = !foreach(entry, PPCRuntimeLibcalls, entry.Provides);
Expand Down
31 changes: 31 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9050,6 +9050,37 @@ SelectionDAG::getMemcmp(SDValue Chain, const SDLoc &dl, SDValue Mem0,
return TLI->LowerCallTo(CLI);
}

std::pair<SDValue, SDValue> SelectionDAG::getStrlen(SDValue Chain,
const SDLoc &dl,
SDValue Src,
const CallInst *CI) {
const char *LibCallName = TLI->getLibcallName(RTLIB::STRLEN);
if (!LibCallName)
return {};

// Emit a library call.
auto GetEntry = [](Type *Ty, SDValue &SDV) {
TargetLowering::ArgListEntry E;
E.Ty = Ty;
E.Node = SDV;
return E;
};

PointerType *PT = PointerType::getUnqual(*getContext());
TargetLowering::ArgListTy Args = {GetEntry(PT, Src)};

TargetLowering::CallLoweringInfo CLI(*this);

// TODO: propagate tail call flag for targets where that is safe. Note
// that it is not safe on AIX which is the only current target.
Comment on lines +9074 to +9075
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant can you just factor out the existing check into a helper function that all the cases use

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created an NFC patch [NFC ]Add a helper function isTailCall for getting libcall in SelectionDAG, After the NFC is approved, I will modify the patch accordingly.

CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
TLI->getLibcallCallingConv(RTLIB::STRLEN), CI->getType(),
getExternalSymbol(LibCallName, TLI->getProgramPointerTy(getDataLayout())),
std::move(Args));

return TLI->LowerCallTo(CLI);
}

SDValue SelectionDAG::getMemcpy(
SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size,
Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI,
Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9287,9 +9287,8 @@ bool SelectionDAGBuilder::visitStrLenCall(const CallInst &I) {
const Value *Arg0 = I.getArgOperand(0);

const SelectionDAGTargetInfo &TSI = DAG.getSelectionDAGInfo();
std::pair<SDValue, SDValue> Res =
TSI.EmitTargetCodeForStrlen(DAG, getCurSDLoc(), DAG.getRoot(),
getValue(Arg0), MachinePointerInfo(Arg0));
std::pair<SDValue, SDValue> Res = TSI.EmitTargetCodeForStrlen(
DAG, getCurSDLoc(), DAG.getRoot(), getValue(Arg0), &I);
if (Res.first.getNode()) {
processIntegerCallValue(I, Res.first, false);
PendingLoads.push_back(Res.second);
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,10 @@ std::pair<SDValue, SDValue> PPCSelectionDAGInfo::EmitTargetCodeForMemcmp(
SDValue Op3, const CallInst *CI) const {
return DAG.getMemcmp(Chain, dl, Op1, Op2, Op3, CI);
}

std::pair<SDValue, SDValue>
PPCSelectionDAGInfo::EmitTargetCodeForStrlen(SelectionDAG &DAG, const SDLoc &DL,
SDValue Chain, SDValue Src,
const CallInst *CI) const {
return DAG.getStrlen(Chain, DL, Src, CI);
}
3 changes: 3 additions & 0 deletions llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class PPCSelectionDAGInfo : public SelectionDAGTargetInfo {
EmitTargetCodeForMemcmp(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain,
SDValue Op1, SDValue Op2, SDValue Op3,
const CallInst *CI) const override;
std::pair<SDValue, SDValue>
EmitTargetCodeForStrlen(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
SDValue Src, const CallInst *CI) const override;
};

} // namespace llvm
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ static std::pair<SDValue, SDValue> getBoundedStrlen(SelectionDAG &DAG,

std::pair<SDValue, SDValue> SystemZSelectionDAGInfo::EmitTargetCodeForStrlen(
SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Src,
MachinePointerInfo SrcPtrInfo) const {
const CallInst *CI) const {
EVT PtrVT = Src.getValueType();
return getBoundedStrlen(DAG, DL, Chain, Src, DAG.getConstant(0, DL, PtrVT));
}
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ class SystemZSelectionDAGInfo : public SelectionDAGTargetInfo {

std::pair<SDValue, SDValue>
EmitTargetCodeForStrlen(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
SDValue Src,
MachinePointerInfo SrcPtrInfo) const override;
SDValue Src, const CallInst *CI) const override;

std::pair<SDValue, SDValue>
EmitTargetCodeForStrnlen(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/PowerPC/milicode32.ll
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ define i32 @strlen_test(ptr noundef %str) nounwind {
; CHECK-AIX-32-P9-NEXT: stwu r1, -64(r1)
; CHECK-AIX-32-P9-NEXT: stw r0, 72(r1)
; CHECK-AIX-32-P9-NEXT: stw r3, 60(r1)
; CHECK-AIX-32-P9-NEXT: bl .strlen[PR]
; CHECK-AIX-32-P9-NEXT: bl .___strlen[PR]
; CHECK-AIX-32-P9-NEXT: nop
; CHECK-AIX-32-P9-NEXT: addi r1, r1, 64
; CHECK-AIX-32-P9-NEXT: lwz r0, 8(r1)
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/PowerPC/milicode64.ll
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ define i64 @strlen_test(ptr noundef %str) nounwind {
; CHECK-AIX-64-P9-NEXT: stdu r1, -128(r1)
; CHECK-AIX-64-P9-NEXT: std r0, 144(r1)
; CHECK-AIX-64-P9-NEXT: std r3, 120(r1)
; CHECK-AIX-64-P9-NEXT: bl .strlen[PR]
; CHECK-AIX-64-P9-NEXT: bl .___strlen64[PR]
; CHECK-AIX-64-P9-NEXT: nop
; CHECK-AIX-64-P9-NEXT: addi r1, r1, 128
; CHECK-AIX-64-P9-NEXT: ld r0, 16(r1)
Expand Down
Loading