[llvm] ef2dc7e - [Analysis] Attribute alignment should not prevent tail call optimization

Dávid Bolvanský via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 24 10:58:04 PDT 2021


Author: Dávid Bolvanský
Date: 2021-04-24T19:57:42+02:00
New Revision: ef2dc7ed9f76e3ae52eaa4def98d4dd11ac527c0

URL: https://github.com/llvm/llvm-project/commit/ef2dc7ed9f76e3ae52eaa4def98d4dd11ac527c0
DIFF: https://github.com/llvm/llvm-project/commit/ef2dc7ed9f76e3ae52eaa4def98d4dd11ac527c0.diff

LOG: [Analysis] Attribute alignment should not prevent tail call optimization
Fixes tail folding issue mentioned in D100879.
Reviewed By: dmgreen
Differential Revision: https://reviews.llvm.org/D101230

Added: 
    llvm/test/CodeGen/X86/tail-calls-compatible-attrs.ll

Modified: 
    llvm/lib/CodeGen/Analysis.cpp
    llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
    llvm/test/CodeGen/ARM/tail-call.ll

Removed: 
    llvm/test/CodeGen/X86/tail-call-deref.ll


################################################################################
diff  --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp
index 5d1b00463dc82..f3e46bc0e9438 100644
--- a/llvm/lib/CodeGen/Analysis.cpp
+++ b/llvm/lib/CodeGen/Analysis.cpp
@@ -560,14 +560,12 @@ bool llvm::attributesPermitTailCall(const Function *F, const Instruction *I,
 
   // Following attributes 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);
-  CallerAttrs.removeAttribute(Attribute::Dereferenceable);
-  CalleeAttrs.removeAttribute(Attribute::Dereferenceable);
-  CallerAttrs.removeAttribute(Attribute::DereferenceableOrNull);
-  CalleeAttrs.removeAttribute(Attribute::DereferenceableOrNull);
+  for (const auto &Attr : {Attribute::Alignment, Attribute::Dereferenceable,
+                           Attribute::DereferenceableOrNull, Attribute::NoAlias,
+                           Attribute::NonNull}) {
+    CallerAttrs.removeAttribute(Attr);
+    CalleeAttrs.removeAttribute(Attr);
+  }
 
   if (CallerAttrs.contains(Attribute::ZExt)) {
     if (!CalleeAttrs.contains(Attribute::ZExt))

diff  --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index c6cf2827fb695..339985abdf50a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -57,18 +57,20 @@ bool TargetLowering::isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
     return false;
 
   // Conservatively require the attributes of the call to match those of
-  // the return. Ignore NoAlias and NonNull because they don't affect the
+  // the return. Ignore following attributes because they don't affect the
   // call sequence.
-  AttributeList CallerAttrs = F.getAttributes();
-  if (AttrBuilder(CallerAttrs, AttributeList::ReturnIndex)
-          .removeAttribute(Attribute::NoAlias)
-          .removeAttribute(Attribute::NonNull)
-          .hasAttributes())
+  AttrBuilder CallerAttrs(F.getAttributes(), AttributeList::ReturnIndex);
+  for (const auto &Attr : {Attribute::Alignment, Attribute::Dereferenceable,
+                           Attribute::DereferenceableOrNull, Attribute::NoAlias,
+                           Attribute::NonNull})
+    CallerAttrs.removeAttribute(Attr);
+
+  if (CallerAttrs.hasAttributes())
     return false;
 
   // It's not safe to eliminate the sign / zero extension of the return value.
-  if (CallerAttrs.hasAttribute(AttributeList::ReturnIndex, Attribute::ZExt) ||
-      CallerAttrs.hasAttribute(AttributeList::ReturnIndex, Attribute::SExt))
+  if (CallerAttrs.contains(Attribute::ZExt) ||
+      CallerAttrs.contains(Attribute::SExt))
     return false;
 
   // Check if the only use is a function return node.

diff  --git a/llvm/test/CodeGen/ARM/tail-call.ll b/llvm/test/CodeGen/ARM/tail-call.ll
index abf0c988c9ecd..e320a6870789d 100644
--- a/llvm/test/CodeGen/ARM/tail-call.ll
+++ b/llvm/test/CodeGen/ARM/tail-call.ll
@@ -99,7 +99,7 @@ entry:
   ret void
 }
 
-; Check that NonNull attributes don't inhibit tailcalls.
+; 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) {
@@ -110,3 +110,28 @@ entry:
   %call = tail call i8* @nonnull_callee(i8* %p, i32 %val)
   ret i8* %call
 }
+
+; Check that noalias attributes don't inhibit tailcalls.
+
+declare noalias i8* @noalias_callee(i8* %p, i32 %val)
+define i8* @noalias_caller(i8* %p, i32 %val) {
+; CHECK-LABEL: noalias_caller:
+; CHECK-TAIL: b noalias_callee
+; CHECK-NO-TAIL: bl noalias_callee
+entry:
+  %call = tail call i8* @noalias_callee(i8* %p, i32 %val)
+  ret i8* %call
+}
+
+
+; Check that alignment attributes don't inhibit tailcalls.
+
+declare align 8 i8* @align8_callee(i8* %p, i32 %val)
+define i8* @align8_caller(i8* %p, i32 %val) {
+; CHECK-LABEL: align8_caller:
+; CHECK-TAIL: b align8_callee
+; CHECK-NO-TAIL: bl align8_callee
+entry:
+  %call = tail call i8* @align8_callee(i8* %p, i32 %val)
+  ret i8* %call
+}

diff  --git a/llvm/test/CodeGen/X86/tail-call-deref.ll b/llvm/test/CodeGen/X86/tail-calls-compatible-attrs.ll
similarity index 72%
rename from llvm/test/CodeGen/X86/tail-call-deref.ll
rename to llvm/test/CodeGen/X86/tail-calls-compatible-attrs.ll
index 9a48adac187a8..e7f38a7f8563d 100644
--- a/llvm/test/CodeGen/X86/tail-call-deref.ll
+++ b/llvm/test/CodeGen/X86/tail-calls-compatible-attrs.ll
@@ -34,3 +34,19 @@ define i8* @test4() nounwind {
   %ret = tail call dereferenceable_or_null(8) i8* @foo()
   ret i8* %ret
 }
+
+define align 8 i8* @test5() nounwind {
+; CHECK-LABEL: test5:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    jmp foo # TAILCALL
+  %ret = tail call i8* @foo()
+  ret i8* %ret
+}
+
+define i8* @test6() nounwind {
+; CHECK-LABEL: test6:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    jmp foo # TAILCALL
+  %ret = tail call align 8 i8* @foo()
+  ret i8* %ret
+}


        


More information about the llvm-commits mailing list