Skip to content

Conversation

diggerlin
Copy link
Contributor

Based on comment of #153600 (comment), Add a helper function isTailCall for getting libcall in SelectionDAG.

@llvmbot llvmbot added the llvm:SelectionDAG SelectionDAGISel as well label Aug 25, 2025
@diggerlin diggerlin requested review from arsenm and RolandF77 August 25, 2025 15:08
@llvmbot
Copy link
Member

llvmbot commented Aug 25, 2025

@llvm/pr-subscribers-llvm-selectiondag

Author: zhijian lin (diggerlin)

Changes

Based on comment of #153600 (comment), Add a helper function isTailCall for getting libcall in SelectionDAG.


Full diff: https://github.com/llvm/llvm-project/pull/155256.diff

1 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+11-12)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 4b7fc45908119..cc9cd50e2c6f9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -9012,6 +9012,14 @@ static void checkAddrSpaceIsValidForLibcall(const TargetLowering *TLI,
   }
 }
 
+static bool isTailCall(const CallInst *CI, const SelectionDAG *SelDAG,
+                       bool IsLowerToLibCall) {
+  bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
+  return CI && CI->isTailCall() &&
+         isInTailCallPosition(*CI, SelDAG->getTarget(),
+                              ReturnsFirstArg && IsLowerToLibCall);
+}
+
 std::pair<SDValue, SDValue>
 SelectionDAG::getMemcmp(SDValue Chain, const SDLoc &dl, SDValue Mem0,
                         SDValue Mem1, SDValue Size, const CallInst *CI) {
@@ -9033,10 +9041,7 @@ SelectionDAG::getMemcmp(SDValue Chain, const SDLoc &dl, SDValue Mem0,
       GetEntry(getDataLayout().getIntPtrType(*getContext()), Size)};
 
   TargetLowering::CallLoweringInfo CLI(*this);
-  bool IsTailCall = false;
-  bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
-  IsTailCall = CI && CI->isTailCall() &&
-               isInTailCallPosition(*CI, getTarget(), ReturnsFirstArg);
+  bool IsTailCall = isTailCall(CI, this, /*LowerToLibCall*/ true);
 
   CLI.setDebugLoc(dl)
       .setChain(Chain)
@@ -9117,10 +9122,7 @@ SDValue SelectionDAG::getMemcpy(
     IsTailCall = *OverrideTailCall;
   } else {
     bool LowersToMemcpy = StringRef(MemCpyName) == StringRef("memcpy");
-    bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
-    IsTailCall = CI && CI->isTailCall() &&
-                 isInTailCallPosition(*CI, getTarget(),
-                                      ReturnsFirstArg && LowersToMemcpy);
+    IsTailCall = isTailCall(CI, this, LowersToMemcpy);
   }
 
   CLI.setDebugLoc(dl)
@@ -9234,10 +9236,7 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst,
   } else {
     bool LowersToMemmove =
         TLI->getLibcallName(RTLIB::MEMMOVE) == StringRef("memmove");
-    bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
-    IsTailCall = CI && CI->isTailCall() &&
-                 isInTailCallPosition(*CI, getTarget(),
-                                      ReturnsFirstArg && LowersToMemmove);
+    IsTailCall = isTailCall(CI, this, LowersToMemmove);
   }
 
   CLI.setDebugLoc(dl)

bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
return CI && CI->isTailCall() &&
isInTailCallPosition(*CI, SelDAG->getTarget(),
ReturnsFirstArg && IsLowerToLibCall);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This requires explanation. The arguments for the calls that are generated are not changed by this condition. Why would ReturnsFirstArg be different?

@@ -9012,6 +9012,14 @@ static void checkAddrSpaceIsValidForLibcall(const TargetLowering *TLI,
}
}

static bool isTailCall(const CallInst *CI, const SelectionDAG *SelDAG,
bool IsLowerToLibCall) {
bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
Copy link
Contributor

Choose a reason for hiding this comment

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

This will always return false for a null CallInst, but you have 2 null checks on it. Tail call should be possible even without the CallInst? I thought we handled tail call of new calls already?

At least turn into early exit or pull the null checks into the caller

@@ -9012,6 +9012,14 @@ static void checkAddrSpaceIsValidForLibcall(const TargetLowering *TLI,
}
}

static bool isTailCall(const CallInst *CI, const SelectionDAG *SelDAG,
Copy link
Contributor

Choose a reason for hiding this comment

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

Name isn't quite right. This is more like an extended version of isInTailCallPosition.

@@ -9012,6 +9012,14 @@ static void checkAddrSpaceIsValidForLibcall(const TargetLowering *TLI,
}
}

static bool isTailCall(const CallInst *CI, const SelectionDAG *SelDAG,
bool IsLowerToLibCall) {
bool ReturnsFirstArg = CI && funcReturnsFirstArgOfCall(*CI);
Copy link
Contributor

Choose a reason for hiding this comment

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

On second thought, why do you need the IR analysis for funcReturnsFirstArgOfCall? You know that based on the properties of the known libcall without looking at the IR

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's about what the caller returns, not what the library call returns, for tail call deliberations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants