[llvm] [PowerPC] using milicode call for strlen instead of lib call (PR #153600)

zhijian lin via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 16 11:23:29 PDT 2025


https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/153600

>From 4ad1f1ef2efb5b9de8e6c56aae421a9723e0866b Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Wed, 13 Aug 2025 18:25:55 +0000
Subject: [PATCH 1/6] implement using milicode for strlen instead of libcall

---
 llvm/include/llvm/CodeGen/SelectionDAG.h      | 10 +++--
 .../llvm/CodeGen/SelectionDAGTargetInfo.h     |  2 +-
 llvm/include/llvm/IR/RuntimeLibcalls.td       |  3 ++
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 37 +++++++++++++++++++
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  5 +--
 .../Target/PowerPC/PPCSelectionDAGInfo.cpp    |  8 ++++
 llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h |  3 ++
 .../SystemZ/SystemZSelectionDAGInfo.cpp       |  2 +-
 .../Target/SystemZ/SystemZSelectionDAGInfo.h  |  3 +-
 llvm/test/CodeGen/PowerPC/milicode32.ll       |  2 +-
 llvm/test/CodeGen/PowerPC/milicode64.ll       |  3 +-
 11 files changed, 66 insertions(+), 12 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index 8a834315646a1..f04f40c42bb0f 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1256,9 +1256,13 @@ class SelectionDAG {
   /// stack arguments from being clobbered.
   LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain);
 
-  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> 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. */
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h b/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
index fd00f813bc9c3..fbfb240cae449 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
@@ -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());
   }
 
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index fd0ea3a2332c9..6183a7e2b04db 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -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 {
@@ -2272,6 +2273,7 @@ defset list<RuntimeLibcallImpl> PPC64AIXCallList = {
   def ___memmove64 : RuntimeLibcallImpl<MEMCPY>;
   def ___memset64 : RuntimeLibcallImpl<MEMSET>;
   def ___bzero64 : RuntimeLibcallImpl<BZERO>;
+  def ___strlen64 : RuntimeLibcallImpl<STRLEN>;
 }
 
 defset list<RuntimeLibcallImpl> PPC32AIXCallList = {
@@ -2279,6 +2281,7 @@ defset list<RuntimeLibcallImpl> PPC32AIXCallList = {
   def ___memmove : RuntimeLibcallImpl<MEMMOVE>;
   def ___memset : RuntimeLibcallImpl<MEMSET>;
   def ___bzero : RuntimeLibcallImpl<BZERO>;
+  def ___strlen : RuntimeLibcallImpl<STRLEN>;
 }
 
 defvar PPCOverrides = !foreach(entry, PPCRuntimeLibcalls, entry.Provides);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 029eb025ff1de..b0c362e0b2177 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -9094,6 +9094,43 @@ 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);
+  bool IsTailCall = false;
+  bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
+  IsTailCall = CI && CI->isTailCall() &&
+               isInTailCallPosition(*CI, getTarget(), ReturnsFirstArg);
+
+  CLI.setDebugLoc(dl)
+      .setChain(Chain)
+      .setLibCallee(
+          TLI->getLibcallCallingConv(RTLIB::STRLEN),
+          Type::getInt32Ty(*getContext()),
+          getExternalSymbol(LibCallName, TLI->getPointerTy(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,
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 430e47451fd49..1d57d6ed754d4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -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);
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
index 4039fedd0cb5c..e15b5b0bea2fc 100644
--- a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
@@ -28,3 +28,11 @@ 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 {
+  EVT PtrVT = Src.getValueType();
+  return DAG.getStrlen(Chain, DL, Src, CI);
+}
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
index 1537851a1b610..f962a7a5321aa 100644
--- a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.h
@@ -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
diff --git a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
index afe838ac973e6..eb00d484af693 100644
--- a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
@@ -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));
 }
diff --git a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
index 5a1e0cd108e77..200566f9646c1 100644
--- a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
+++ b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
@@ -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,
diff --git a/llvm/test/CodeGen/PowerPC/milicode32.ll b/llvm/test/CodeGen/PowerPC/milicode32.ll
index a2af6d413b4bf..78d036202fe4e 100644
--- a/llvm/test/CodeGen/PowerPC/milicode32.ll
+++ b/llvm/test/CodeGen/PowerPC/milicode32.ll
@@ -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)
diff --git a/llvm/test/CodeGen/PowerPC/milicode64.ll b/llvm/test/CodeGen/PowerPC/milicode64.ll
index 0f0585d9028a9..31d8704b7974c 100644
--- a/llvm/test/CodeGen/PowerPC/milicode64.ll
+++ b/llvm/test/CodeGen/PowerPC/milicode64.ll
@@ -85,8 +85,9 @@ 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:    clrldi r3, r3, 32
 ; CHECK-AIX-64-P9-NEXT:    addi r1, r1, 128
 ; CHECK-AIX-64-P9-NEXT:    ld r0, 16(r1)
 ; CHECK-AIX-64-P9-NEXT:    mtlr r0

>From d5016bcce14279ba94b774ffda58366b63938b4f Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Thu, 14 Aug 2025 14:06:05 +0000
Subject: [PATCH 2/6] fix an error

---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 3 +--
 llvm/test/CodeGen/PowerPC/milicode64.ll        | 1 -
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b0c362e0b2177..f98116cb5c00c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -9122,8 +9122,7 @@ std::pair<SDValue, SDValue> SelectionDAG::getStrlen(SDValue Chain,
   CLI.setDebugLoc(dl)
       .setChain(Chain)
       .setLibCallee(
-          TLI->getLibcallCallingConv(RTLIB::STRLEN),
-          Type::getInt32Ty(*getContext()),
+          TLI->getLibcallCallingConv(RTLIB::STRLEN), CI->getType(),
           getExternalSymbol(LibCallName, TLI->getPointerTy(getDataLayout())),
           std::move(Args))
       .setTailCall(IsTailCall);
diff --git a/llvm/test/CodeGen/PowerPC/milicode64.ll b/llvm/test/CodeGen/PowerPC/milicode64.ll
index 31d8704b7974c..8b87529d9a6d8 100644
--- a/llvm/test/CodeGen/PowerPC/milicode64.ll
+++ b/llvm/test/CodeGen/PowerPC/milicode64.ll
@@ -87,7 +87,6 @@ define i64 @strlen_test(ptr noundef %str) nounwind {
 ; CHECK-AIX-64-P9-NEXT:    std r3, 120(r1)
 ; CHECK-AIX-64-P9-NEXT:    bl .___strlen64[PR]
 ; CHECK-AIX-64-P9-NEXT:    nop
-; CHECK-AIX-64-P9-NEXT:    clrldi r3, r3, 32
 ; CHECK-AIX-64-P9-NEXT:    addi r1, r1, 128
 ; CHECK-AIX-64-P9-NEXT:    ld r0, 16(r1)
 ; CHECK-AIX-64-P9-NEXT:    mtlr r0

>From b3bf5916c6b0128c7142f2f2b6765ad072a5fb01 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Wed, 20 Aug 2025 17:47:46 +0000
Subject: [PATCH 3/6] address comment

---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 26 +++++++++++--------
 .../Target/PowerPC/PPCSelectionDAGInfo.cpp    |  1 -
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index f98116cb5c00c..bb27f99b0efeb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -9114,18 +9114,22 @@ std::pair<SDValue, SDValue> SelectionDAG::getStrlen(SDValue Chain,
   TargetLowering::ArgListTy Args = {GetEntry(PT, Src)};
 
   TargetLowering::CallLoweringInfo CLI(*this);
-  bool IsTailCall = false;
-  bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
-  IsTailCall = CI && CI->isTailCall() &&
-               isInTailCallPosition(*CI, getTarget(), ReturnsFirstArg);
 
-  CLI.setDebugLoc(dl)
-      .setChain(Chain)
-      .setLibCallee(
-          TLI->getLibcallCallingConv(RTLIB::STRLEN), CI->getType(),
-          getExternalSymbol(LibCallName, TLI->getPointerTy(getDataLayout())),
-          std::move(Args))
-      .setTailCall(IsTailCall);
+  // TODO: Intentionally not marking this libcall as a tail call.
+  //
+  // Why:
+  // - The only current in-tree user of SelectionDAG::getStrlen is the AIX path,
+  //   where generic tail-calling to libcalls is not safe due to ABI
+  //   constraints around r2 (TOC). We don¡¯t have a reliable way to validate a
+  //   tail call here.
+  //
+  // If another target starts using this and does support tail calls to
+  // libcalls, re-enable `.setTailCall(...)` under a target guard and add a
+  // test.
+  CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
+      TLI->getLibcallCallingConv(RTLIB::STRLEN), CI->getType(),
+      getExternalSymbol(LibCallName, TLI->getProgramPointerTy(getDataLayout())),
+      std::move(Args));
 
   return TLI->LowerCallTo(CLI);
 }
diff --git a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
index e15b5b0bea2fc..93a4693c50168 100644
--- a/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSelectionDAGInfo.cpp
@@ -33,6 +33,5 @@ std::pair<SDValue, SDValue>
 PPCSelectionDAGInfo::EmitTargetCodeForStrlen(SelectionDAG &DAG, const SDLoc &DL,
                                              SDValue Chain, SDValue Src,
                                              const CallInst *CI) const {
-  EVT PtrVT = Src.getValueType();
   return DAG.getStrlen(Chain, DL, Src, CI);
 }

>From a40474772383f0694780c90eb7a028477dea5a6d Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Fri, 22 Aug 2025 18:14:37 +0000
Subject: [PATCH 4/6] address comment

---
 llvm/include/llvm/CodeGen/SelectionDAG.h       |  7 +++----
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 ++-----------
 2 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index f04f40c42bb0f..d9d6f0bcdcb84 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1256,10 +1256,9 @@ class SelectionDAG {
   /// stack arguments from being clobbered.
   LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain);
 
-  LLVM_ABI std::pair<SDValue, SDValue> getMemcmp(SDValue Chain, const SDLoc &dl,
-                                                 SDValue Dst, SDValue Src,
-                                                 SDValue Size,
-                                                 const CallInst *CI);
+  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);
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index bb27f99b0efeb..bb5517bbeaf89 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -9115,17 +9115,8 @@ std::pair<SDValue, SDValue> SelectionDAG::getStrlen(SDValue Chain,
 
   TargetLowering::CallLoweringInfo CLI(*this);
 
-  // TODO: Intentionally not marking this libcall as a tail call.
-  //
-  // Why:
-  // - The only current in-tree user of SelectionDAG::getStrlen is the AIX path,
-  //   where generic tail-calling to libcalls is not safe due to ABI
-  //   constraints around r2 (TOC). We don¡¯t have a reliable way to validate a
-  //   tail call here.
-  //
-  // If another target starts using this and does support tail calls to
-  // libcalls, re-enable `.setTailCall(...)` under a target guard and add a
-  // test.
+  //  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.
   CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
       TLI->getLibcallCallingConv(RTLIB::STRLEN), CI->getType(),
       getExternalSymbol(LibCallName, TLI->getProgramPointerTy(getDataLayout())),

>From 904b92acfe8e081ef4b6a617531ccdb754ba7d27 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Tue, 16 Sep 2025 15:24:12 +0000
Subject: [PATCH 5/6] rebase the code after NFC patch landed

---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 21 +++++++++----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index bb5517bbeaf89..7a4875326e3c0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -9103,24 +9103,23 @@ std::pair<SDValue, SDValue> SelectionDAG::getStrlen(SDValue Chain,
     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::ArgListTy Args = {{Src, PT}};
 
   TargetLowering::CallLoweringInfo CLI(*this);
+  bool IsTailCall =
+      isInTailCallPositionWrapper(CI, this, /*AllowReturnsFirstArg*/ true);
 
   //  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.
-  CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
-      TLI->getLibcallCallingConv(RTLIB::STRLEN), CI->getType(),
-      getExternalSymbol(LibCallName, TLI->getProgramPointerTy(getDataLayout())),
-      std::move(Args));
+  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);
 }

>From c4364f8898f37a0e700de4c19304bf7531d38d5e Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Tue, 16 Sep 2025 18:29:14 +0000
Subject: [PATCH 6/6] nit change

---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 7a4875326e3c0..b18d96e79c636 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -9103,16 +9103,13 @@ std::pair<SDValue, SDValue> SelectionDAG::getStrlen(SDValue Chain,
     return {};
 
   // Emit a library call.
-
-  PointerType *PT = PointerType::getUnqual(*getContext());
-  TargetLowering::ArgListTy Args = {{Src, PT}};
+  TargetLowering::ArgListTy Args = {
+      {Src, PointerType::getUnqual(*getContext())}};
 
   TargetLowering::CallLoweringInfo CLI(*this);
   bool IsTailCall =
       isInTailCallPositionWrapper(CI, this, /*AllowReturnsFirstArg*/ true);
 
-  //  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.
   CLI.setDebugLoc(dl)
       .setChain(Chain)
       .setLibCallee(TLI->getLibcallCallingConv(RTLIB::STRLEN), CI->getType(),



More information about the llvm-commits mailing list