[PATCH] ARM: Do not tail-call to an externally-defined function with weak linkage
Oliver Stannard
oliver.stannard at arm.com
Thu Aug 14 08:45:07 PDT 2014
Externally-defined functions with weak linkage should not be
tail-called on ARM or AArch64, as the AAELF spec requires normal calls
to undefined weak functions to be replaced with a NOP or jump to the
next instruction. The behaviour of branch instructions in this
situation (as used for tail calls) is implementation-defined, so we
cannot rely on the linker replacing the tail call with a return.
http://reviews.llvm.org/D4906
Files:
lib/Transforms/Scalar/TailRecursionElimination.cpp
test/Transforms/TailCallElim/AArch64/lit.local.cfg
test/Transforms/TailCallElim/AArch64/weak-linkage.ll
test/Transforms/TailCallElim/ARM/lit.local.cfg
test/Transforms/TailCallElim/ARM/weak-linkage.ll
Index: lib/Transforms/Scalar/TailRecursionElimination.cpp
===================================================================
--- lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -54,6 +54,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/InlineCost.h"
@@ -298,6 +299,20 @@
if (!CI || CI->isTailCall())
continue;
+ // Externally-defined functions with weak linkage should not be
+ // tail-called on ARM or AArch64, as the AAELF spec requires normal calls
+ // to undefined weak functions to be replaced with a NOP or jump to the
+ // next instruction. The behaviour of branch instructions in this
+ // situation (as used for tail calls) is implementation-defined, so we
+ // cannot rely on the linker replacing the tail call with a return.
+ GlobalValue *Callee = dyn_cast<GlobalValue>(CI->getCalledValue());
+ Triple T(F.getParent()->getTargetTriple());
+ if ((T.getArch() == Triple::arm || T.getArch() == Triple::armeb ||
+ T.getArch() == Triple::thumb || T.getArch() == Triple::thumbeb ||
+ T.getArch() == Triple::aarch64 || T.getArch() == Triple::aarch64_be)
+ && Callee && Callee->hasExternalWeakLinkage())
+ continue;
+
if (CI->doesNotAccessMemory()) {
// A call to a readnone function whose arguments are all things computed
// outside this function can be marked tail. Even if you stored the
Index: test/Transforms/TailCallElim/AArch64/lit.local.cfg
===================================================================
--- /dev/null
+++ test/Transforms/TailCallElim/AArch64/lit.local.cfg
@@ -0,0 +1,3 @@
+if not 'AArch64' in config.root.targets:
+ config.unsupported = True
+
Index: test/Transforms/TailCallElim/AArch64/weak-linkage.ll
===================================================================
--- /dev/null
+++ test/Transforms/TailCallElim/AArch64/weak-linkage.ll
@@ -0,0 +1,10 @@
+; RUN: opt -mtriple=aarch64--none-eabi < %s -tailcallelim -S | FileCheck %s
+
+declare extern_weak void @weak_function()
+
+; Don't tail call to a weak symbol
+define void @func1() {
+; CHECK-NOT: tail call
+ call void @weak_function()
+ ret void
+}
Index: test/Transforms/TailCallElim/ARM/lit.local.cfg
===================================================================
--- /dev/null
+++ test/Transforms/TailCallElim/ARM/lit.local.cfg
@@ -0,0 +1,3 @@
+if not 'ARM' in config.root.targets:
+ config.unsupported = True
+
Index: test/Transforms/TailCallElim/ARM/weak-linkage.ll
===================================================================
--- /dev/null
+++ test/Transforms/TailCallElim/ARM/weak-linkage.ll
@@ -0,0 +1,10 @@
+; RUN: opt -mtriple=armv7a--none-eabi < %s -tailcallelim -S | FileCheck %s
+
+declare extern_weak void @weak_function()
+
+; Don't tail call to a weak symbol
+define void @func1() {
+; CHECK-NOT: tail call
+ call void @weak_function()
+ ret void
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4906.12509.patch
Type: text/x-patch
Size: 3158 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140814/c1aa9584/attachment.bin>
More information about the llvm-commits
mailing list