llvm.org GIT mirror llvm / 07c8da8
Make PrologEpilogInserter save/restore all callee saved registers in functions which call __builtin_unwind_init() __builtin_unwind_init() is an undocumented gcc intrinsic which has this effect, and is used in libgcc_eh. Goes part of the way toward fixing PR8541. Merged from r183984 Author: Derek Schuff <dschuff@google.com> Date: Fri Jun 14 16:15:29 2013 +0000 git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_33@190578 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 7 years ago
4 changed file(s) with 60 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
346346 def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>;
347347 def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>;
348348
349 // __builtin_unwind_init is an undocumented GCC intrinsic that causes all
350 // callee-saved registers to be saved and restored (regardless of whether they
351 // are used) in the calling function. It is used by libgcc_eh.
349352 def int_eh_unwind_init: Intrinsic<[]>,
350353 GCCBuiltin<"__builtin_unwind_init">;
351354
2828 #include "llvm/CodeGen/MachineFrameInfo.h"
2929 #include "llvm/CodeGen/MachineInstr.h"
3030 #include "llvm/CodeGen/MachineLoopInfo.h"
31 #include "llvm/CodeGen/MachineModuleInfo.h"
3132 #include "llvm/CodeGen/MachineRegisterInfo.h"
3233 #include "llvm/CodeGen/RegisterScavenging.h"
3334 #include "llvm/IR/InlineAsm.h"
213214 std::vector CSI;
214215 for (unsigned i = 0; CSRegs[i]; ++i) {
215216 unsigned Reg = CSRegs[i];
216 if (F.getRegInfo().isPhysRegUsed(Reg)) {
217 // Functions which call __builtin_unwind_init get all their registers saved.
218 if (F.getRegInfo().isPhysRegUsed(Reg) || F.getMMI().callsUnwindInit()) {
217219 // If the reg is modified, save it!
218220 CSI.push_back(CalleeSavedInfo(Reg));
219221 }
0 ; RUN: llc -mtriple=armv7-unknown-linux-gnueabi < %s | FileCheck %s
1 ; Check that all callee-saved registers are saved and restored in functions
2 ; that call __builtin_unwind_init(). This is its undocumented behavior in gcc,
3 ; and it is used in compiling libgcc_eh.
4 ; See also PR8541
5
6 declare void @llvm.eh.unwind.init()
7
8 define void @calls_unwind_init() {
9 call void @llvm.eh.unwind.init()
10 ret void
11 }
12
13 ; CHECK: calls_unwind_init:
14 ; CHECK: push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
15 ; CHECK: vpush {d8, d9, d10, d11, d12, d13, d14, d15}
16 ; CHECK: vpop {d8, d9, d10, d11, d12, d13, d14, d15}
17 ; CHECK: pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
0 ; RUN: llc -mtriple=x86_64-unknown-linux < %s | FileCheck -check-prefix X8664 %s
1 ; RUN: llc -mtriple=i686-unknown-linux < %s | FileCheck -check-prefix X8632 %s
2 ; Check that all callee-saved registers are saved and restored in functions
3 ; that call __builtin_unwind_init(). This is its undocumented behavior in gcc,
4 ; and it is used in compiling libgcc_eh.
5 ; See also PR8541
6
7 declare void @llvm.eh.unwind.init()
8
9 define void @calls_unwind_init() {
10 call void @llvm.eh.unwind.init()
11 ret void
12 }
13
14 ; X8664: calls_unwind_init:
15 ; X8664: pushq %rbp
16 ; X8664: pushq %r15
17 ; X8664: pushq %r14
18 ; X8664: pushq %r13
19 ; X8664: pushq %r12
20 ; X8664: pushq %rbx
21 ; X8664: popq %rbx
22 ; X8664: popq %r12
23 ; X8664: popq %r13
24 ; X8664: popq %r14
25 ; X8664: popq %r15
26
27 ; X8632: calls_unwind_init:
28 ; X8632: pushl %ebp
29 ; X8632: pushl %ebx
30 ; X8632: pushl %edi
31 ; X8632: pushl %esi
32 ; X8632: popl %esi
33 ; X8632: popl %edi
34 ; X8632: popl %ebx
35 ; X8632: popl %ebp