summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLogan Chien <tzuhsiang.chien@gmail.com>2014-02-25 16:57:28 +0000
committerLogan Chien <tzuhsiang.chien@gmail.com>2014-02-25 16:57:28 +0000
commit18583d71e83525cf58787ab5b5e96e999a8f9e1c (patch)
tree9b5f612aaea9e582950c2ae156296d7b581b41cf
parent84e30a7346caaf78e97b1cd80f5ab6c2da55c365 (diff)
downloadbcm5719-llvm-18583d71e83525cf58787ab5b5e96e999a8f9e1c.tar.gz
bcm5719-llvm-18583d71e83525cf58787ab5b5e96e999a8f9e1c.zip
Keep the link register for uwtable.
The function with uwtable attribute might be visited by the stack unwinder, thus the link register should be considered as clobbered after the execution of the branch and link instruction (i.e. the definition of the machine instruction can't be ignored) even when the callee function are marked with noreturn. llvm-svn: 202165
-rw-r--r--llvm/lib/CodeGen/VirtRegMap.cpp15
-rw-r--r--llvm/test/CodeGen/ARM/noreturn.ll17
2 files changed, 29 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp
index 47772e7c02f..29ed30cb51a 100644
--- a/llvm/lib/CodeGen/VirtRegMap.cpp
+++ b/llvm/lib/CodeGen/VirtRegMap.cpp
@@ -278,6 +278,11 @@ void VirtRegRewriter::rewrite() {
PhysRegs.clear();
PhysRegs.setUniverse(TRI->getNumRegs());
+ // The function with uwtable should guarantee that the stack unwinder
+ // can unwind the stack to the previous frame. Thus, we can't apply the
+ // noreturn optimization if the caller function has uwtable attribute.
+ bool HasUWTable = MF->getFunction()->hasFnAttribute(Attribute::UWTable);
+
for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
MBBI != MBBE; ++MBBI) {
DEBUG(MBBI->print(dbgs(), Indexes));
@@ -287,9 +292,12 @@ void VirtRegRewriter::rewrite() {
MachineInstr *MI = MII;
++MII;
- // Check if this instruction is a call to a noreturn function.
- // If so, all the definitions set by this instruction can be ignored.
- if (IsExitBB && MI->isCall())
+ // Check if this instruction is a call to a noreturn function. If this
+ // is a call to noreturn function and we don't need the stack unwinding
+ // functionality (i.e. this function does not have uwtable attribute and
+ // the callee function has the nounwind attribute), then we can ignore
+ // the definitions set by this instruction.
+ if (!HasUWTable && IsExitBB && MI->isCall()) {
for (MachineInstr::mop_iterator MOI = MI->operands_begin(),
MOE = MI->operands_end(); MOI != MOE; ++MOI) {
MachineOperand &MO = *MOI;
@@ -305,6 +313,7 @@ void VirtRegRewriter::rewrite() {
NoReturnInsts.insert(MI);
break;
}
+ }
for (MachineInstr::mop_iterator MOI = MI->operands_begin(),
MOE = MI->operands_end(); MOI != MOE; ++MOI) {
diff --git a/llvm/test/CodeGen/ARM/noreturn.ll b/llvm/test/CodeGen/ARM/noreturn.ll
index 4c876cec9c1..edc3333455d 100644
--- a/llvm/test/CodeGen/ARM/noreturn.ll
+++ b/llvm/test/CodeGen/ARM/noreturn.ll
@@ -43,6 +43,23 @@ entry:
unreachable
}
+; Test case for uwtable
+define i32 @test4() uwtable {
+; CHECK-LABEL: @test4
+; CHECK: push
+entry:
+ tail call void @overflow() #0
+ unreachable
+}
+
+define i32 @test5() uwtable {
+; CHECK-LABEL: @test5
+; CHECK: push
+entry:
+ tail call void @overflow_with_unwind() #1
+ unreachable
+}
+
; Function Attrs: noreturn
declare void @overflow_with_unwind() #1
OpenPOWER on IntegriCloud