[PATCH] D60837: [CGP] Look through bitcasts when duplicating returns for tail calls

Francis Visoiu Mistrih via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 17 14:48:17 PDT 2019


thegameg created this revision.
thegameg added reviewers: tejohnson, spatel, fhahn.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

The simple case of:

  int *callee();
  void *caller(void *a) {
    if (a == NULL)
      return callee();
    return a;
  }

would generate a regular call instead of a tail call because we don't
look through the bitcast of the call to `callee` when duplicating the
return blocks.


https://reviews.llvm.org/D60837

Files:
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/test/CodeGen/X86/tailcall-cgp-dup.ll


Index: llvm/test/CodeGen/X86/tailcall-cgp-dup.ll
===================================================================
--- llvm/test/CodeGen/X86/tailcall-cgp-dup.ll
+++ llvm/test/CodeGen/X86/tailcall-cgp-dup.ll
@@ -105,3 +105,23 @@
   ret i1 %0
 }
 
+; We need to look through bitcasts when looking for tail calls in phi incoming
+; values.
+; CHECK-LABEL: f_ret8:
+; CHECK: jmp {{.*}}g_ret32
+; CHECK-NOT: call
+declare i32* @g_ret32()
+define i8* @f_ret8(i8* %obj) {
+entry:
+  %cmp = icmp eq i8* %obj, null
+  br i1 %cmp, label %return, label %if.then
+
+if.then:
+  %ptr = tail call i32* @g_ret32()
+  %casted = bitcast i32* %ptr to i8*
+  br label %return
+
+return:
+  %retval = phi i8* [ %casted, %if.then ], [ %obj, %entry ]
+  ret i8* %retval
+}
Index: llvm/lib/CodeGen/CodeGenPrepare.cpp
===================================================================
--- llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -2031,7 +2031,11 @@
   SmallVector<CallInst*, 4> TailCalls;
   if (PN) {
     for (unsigned I = 0, E = PN->getNumIncomingValues(); I != E; ++I) {
-      CallInst *CI = dyn_cast<CallInst>(PN->getIncomingValue(I));
+      Value *IncomingVal = PN->getIncomingValue(I);
+      // Look through bitcasts.
+      if (BitCastInst *BCI = dyn_cast<BitCastInst>(IncomingVal))
+        IncomingVal = BCI->getOperand(0);
+      CallInst *CI = dyn_cast<CallInst>(IncomingVal);
       // Make sure the phi value is indeed produced by the tail call.
       if (CI && CI->hasOneUse() && CI->getParent() == PN->getIncomingBlock(I) &&
           TLI->mayBeEmittedAsTailCall(CI) &&


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60837.195631.patch
Type: text/x-patch
Size: 1609 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190417/57145c7c/attachment.bin>


More information about the llvm-commits mailing list