From 12993dd916d4b1bbe7eb60e4a4b031f3dc760424 Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Mon, 18 Aug 2014 12:42:15 +0000 Subject: [ARM,AArch64] Do not tail-call to an externally-defined function with weak linkage 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. llvm-svn: 215890 --- llvm/test/CodeGen/ARM/tail-call.ll | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'llvm/test/CodeGen/ARM/tail-call.ll') diff --git a/llvm/test/CodeGen/ARM/tail-call.ll b/llvm/test/CodeGen/ARM/tail-call.ll index 771158632ec..c3e79652c03 100644 --- a/llvm/test/CodeGen/ARM/tail-call.ll +++ b/llvm/test/CodeGen/ARM/tail-call.ll @@ -3,6 +3,7 @@ ; RUN: | FileCheck %s -check-prefix CHECK-NO-TAIL declare i32 @callee(i32 %i) +declare extern_weak fastcc void @callee_weak() define i32 @caller(i32 %i) { entry: @@ -19,3 +20,12 @@ entry: ; CHECK-NO-TAIL: pop {lr} ; CHECK-NO-TAIL: bx lr + +; Weakly-referenced extern functions cannot be tail-called, as AAELF does +; not define the behaviour of branch instructions to undefined weak symbols. +define fastcc void @caller_weak() { +; CHECK-LABEL: caller_weak: +; CHECK: bl callee_weak + tail call void @callee_weak() + ret void +} -- cgit v1.2.3