[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