[llvm] r343091 - [CodeGen] Enable tail calls for functions with NonNull attributes.

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 26 03:46:18 PDT 2018


Author: dmgreen
Date: Wed Sep 26 03:46:18 2018
New Revision: 343091

URL: http://llvm.org/viewvc/llvm-project?rev=343091&view=rev
Log:
[CodeGen] Enable tail calls for functions with NonNull attributes.

Adding NonNull as attributes to returned pointers has the unfortunate side
effect of disabling tail calls. This patch ignores the NonNull attribute when
we decide whether to tail merge, in the same way that we ignore the NoAlias
attribute, as it has no affect on the call sequence.

Differential Revision: https://reviews.llvm.org/D52238

Added:
    llvm/trunk/test/Transforms/CodeGenPrepare/ARM/tailcall-dup.ll
Modified:
    llvm/trunk/lib/CodeGen/Analysis.cpp
    llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
    llvm/trunk/test/CodeGen/ARM/tail-call.ll

Modified: llvm/trunk/lib/CodeGen/Analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Analysis.cpp?rev=343091&r1=343090&r2=343091&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/Analysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/Analysis.cpp Wed Sep 26 03:46:18 2018
@@ -519,10 +519,12 @@ bool llvm::attributesPermitTailCall(cons
   AttrBuilder CalleeAttrs(cast<CallInst>(I)->getAttributes(),
                           AttributeList::ReturnIndex);
 
-  // Noalias is completely benign as far as calling convention goes, it
-  // shouldn't affect whether the call is a tail call.
+  // NoAlias and NonNull are completely benign as far as calling convention
+  // goes, they shouldn't affect whether the call is a tail call.
   CallerAttrs.removeAttribute(Attribute::NoAlias);
   CalleeAttrs.removeAttribute(Attribute::NoAlias);
+  CallerAttrs.removeAttribute(Attribute::NonNull);
+  CalleeAttrs.removeAttribute(Attribute::NonNull);
 
   if (CallerAttrs.contains(Attribute::ZExt)) {
     if (!CalleeAttrs.contains(Attribute::ZExt))

Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=343091&r1=343090&r2=343091&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Wed Sep 26 03:46:18 2018
@@ -1871,15 +1871,6 @@ bool CodeGenPrepare::dupRetToEnableTailC
     CallInst *CI = TailCalls[i];
     CallSite CS(CI);
 
-    // Conservatively require the attributes of the call to match those of the
-    // return. Ignore noalias because it doesn't affect the call sequence.
-    AttributeList CalleeAttrs = CS.getAttributes();
-    if (AttrBuilder(CalleeAttrs, AttributeList::ReturnIndex)
-            .removeAttribute(Attribute::NoAlias) !=
-        AttrBuilder(CalleeAttrs, AttributeList::ReturnIndex)
-            .removeAttribute(Attribute::NoAlias))
-      continue;
-
     // Make sure the call instruction is followed by an unconditional branch to
     // the return block.
     BasicBlock *CallBB = CI->getParent();

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=343091&r1=343090&r2=343091&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Wed Sep 26 03:46:18 2018
@@ -55,10 +55,12 @@ bool TargetLowering::isInTailCallPositio
   const Function &F = DAG.getMachineFunction().getFunction();
 
   // Conservatively require the attributes of the call to match those of
-  // the return. Ignore noalias because it doesn't affect the call sequence.
+  // the return. Ignore NoAlias and NonNull because they don't affect the
+  // call sequence.
   AttributeList CallerAttrs = F.getAttributes();
   if (AttrBuilder(CallerAttrs, AttributeList::ReturnIndex)
           .removeAttribute(Attribute::NoAlias)
+          .removeAttribute(Attribute::NonNull)
           .hasAttributes())
     return false;
 

Modified: llvm/trunk/test/CodeGen/ARM/tail-call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/tail-call.ll?rev=343091&r1=343090&r2=343091&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/tail-call.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/tail-call.ll Wed Sep 26 03:46:18 2018
@@ -98,3 +98,15 @@ entry:
   %call = tail call i32 (i32, ...) @variadic(i32 %y, i64 %z, i64 %z)
   ret void
 }
+
+; Check that NonNull attributes don't inhibit tailcalls.
+
+declare nonnull i8* @nonnull_callee(i8* %p, i32 %val)
+define i8* @nonnull_caller(i8* %p, i32 %val) {
+; CHECK-LABEL: nonnull_caller:
+; CHECK-TAIL: b nonnull_callee
+; CHECK-NO-TAIL: bl nonnull_callee
+entry:
+  %call = tail call i8* @nonnull_callee(i8* %p, i32 %val)
+  ret i8* %call
+}

Added: llvm/trunk/test/Transforms/CodeGenPrepare/ARM/tailcall-dup.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/ARM/tailcall-dup.ll?rev=343091&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/ARM/tailcall-dup.ll (added)
+++ llvm/trunk/test/Transforms/CodeGenPrepare/ARM/tailcall-dup.ll Wed Sep 26 03:46:18 2018
@@ -0,0 +1,77 @@
+; RUN: opt -codegenprepare -S < %s | FileCheck %s
+
+target triple = "armv8m.main-none-eabi"
+
+declare i8* @f0()
+declare i8* @f1()
+
+define i8* @tail_dup() {
+; CHECK-LABEL: tail_dup
+; CHECK: tail call i8* @f0()
+; CHECK-NEXT: ret i8*
+; CHECK: tail call i8* @f1()
+; CHECK-NEXT: ret i8*
+bb0:
+  %tmp0 = tail call i8* @f0()
+  br label %return
+bb1:
+  %tmp1 = tail call i8* @f1()
+  br label %return
+return:
+  %retval = phi i8* [ %tmp0, %bb0 ], [ %tmp1, %bb1 ]
+  ret i8* %retval
+}
+
+define nonnull i8* @nonnull_dup() {
+; CHECK-LABEL: nonnull_dup
+; CHECK: tail call i8* @f0()
+; CHECK-NEXT: ret i8*
+; CHECK: tail call i8* @f1()
+; CHECK-NEXT: ret i8*
+bb0:
+  %tmp0 = tail call i8* @f0()
+  br label %return
+bb1:
+  %tmp1 = tail call i8* @f1()
+  br label %return
+return:
+  %retval = phi i8* [ %tmp0, %bb0 ], [ %tmp1, %bb1 ]
+  ret i8* %retval
+}
+
+define i8* @noalias_dup() {
+; CHECK-LABEL: noalias_dup
+; CHECK: tail call noalias i8* @f0()
+; CHECK-NEXT: ret i8*
+; CHECK: tail call noalias i8* @f1()
+; CHECK-NEXT: ret i8*
+bb0:
+  %tmp0 = tail call noalias i8* @f0()
+  br label %return
+bb1:
+  %tmp1 = tail call noalias i8* @f1()
+  br label %return
+return:
+  %retval = phi i8* [ %tmp0, %bb0 ], [ %tmp1, %bb1 ]
+  ret i8* %retval
+}
+
+; Use inreg as a way of testing that attributes (other than nonnull and
+; noalias) disable the tailcall duplication in cgp.
+
+define inreg i8* @inreg_nodup() {
+; CHECK-LABEL: inreg_nodup
+; CHECK: tail call i8* @f0()
+; CHECK-NEXT: br label %return
+; CHECK: tail call i8* @f1()
+; CHECK-NEXT: br label %return
+bb0:
+  %tmp0 = tail call i8* @f0()
+  br label %return
+bb1:
+  %tmp1 = tail call i8* @f1()
+  br label %return
+return:
+  %retval = phi i8* [ %tmp0, %bb0 ], [ %tmp1, %bb1 ]
+  ret i8* %retval
+}




More information about the llvm-commits mailing list