Skip to content
Merged
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>
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: can we add some doc on what this function does?
What is the difference between returing LLVM_ABI std::pair<SDValue, SDValue> vs just std::pair<SDValue, SDValue>? I see that getMemcmp() doesn't use LLVM_ABI

Copy link
Contributor Author

@diggerlin diggerlin Sep 19, 2025

Choose a reason for hiding this comment

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

All the member functions of SelectionDAG has LLVM_ABI, when I worked on the patch #147093, I forgot to add the LLVM_ABI for getMemcmp(), I added it in the patch before, but Roland suggested a NFC patch for it(#153600 (comment)) . I will create a NFC patch to add LLVM_ABI for getMemcmp() later.

Copy link
Contributor Author

@diggerlin diggerlin Sep 19, 2025

Choose a reason for hiding this comment

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

nit: can we add some doc on what this function does?

Sorry to miss your comment , I will add doc the getMemcp and getStrlen in the same NFC patch of adding LLVM_ABI for getMemcmp().

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 @@ -297,6 +297,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 @@ -2272,13 +2273,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
27 changes: 27 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9094,6 +9094,33 @@ 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.
TargetLowering::ArgListTy Args = {
{Src, PointerType::getUnqual(*getContext())}};

TargetLowering::CallLoweringInfo CLI(*this);
bool IsTailCall =
isInTailCallPositionWrapper(CI, this, /*AllowReturnsFirstArg*/ true);

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

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 @@ -9335,9 +9335,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