From d4517fa24da8d678e2541ec9b4def40b5b99753a Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Wed, 12 Mar 2014 11:29:23 +0000 Subject: [PATCH] ARM: correct Dwarf output for non-contiguous VFP saves. When the list of VFP registers to be saved was non-contiguous (so multiple vpush/vpop instructions were needed) these were being ordered oddly, as in: vpush {d8, d9} vpush {d11} This led to the layout in memory being [d11, d8, d9] which is ugly and doesn't match the CFI_INSTRUCTIONs we're generating either (so Dwarf info would be broken). This switches the order of vpush/vpop (in both prologue and epilogue, obviously) so that the Dwarf locations are correct again. rdar://problem/16264856 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203655 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFrameLowering.cpp | 9 ++++++ test/CodeGen/ARM/2010-12-07-PEIBug.ll | 6 ++-- test/CodeGen/ARM/vfp-regs-dwarf.ll | 44 +++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/ARM/vfp-regs-dwarf.ll diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp index c35cd23b91c..dcae66bc858 100644 --- a/lib/Target/ARM/ARMFrameLowering.cpp +++ b/lib/Target/ARM/ARMFrameLowering.cpp @@ -803,6 +803,11 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, AddDefaultPred(MIB); } Regs.clear(); + + // Put any subsequent vpush instructions before this one: they will refer to + // higher register numbers so need to be pushed first in order to preserve + // monotonicity. + --MI; } } @@ -886,6 +891,10 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, AddDefaultPred(MIB); } Regs.clear(); + + // Put any subsequent vpop instructions after this one: they will refer to + // higher register numbers so need to be popped afterwards. + ++MI; } } diff --git a/test/CodeGen/ARM/2010-12-07-PEIBug.ll b/test/CodeGen/ARM/2010-12-07-PEIBug.ll index eef6abd9645..4baee64962c 100644 --- a/test/CodeGen/ARM/2010-12-07-PEIBug.ll +++ b/test/CodeGen/ARM/2010-12-07-PEIBug.ll @@ -5,11 +5,11 @@ define hidden void @foo() nounwind ssp { entry: ; CHECK-LABEL: foo: ; CHECK: mov r7, sp -; CHECK-NEXT: vpush {d8} ; CHECK-NEXT: vpush {d10, d11} +; CHECK-NEXT: vpush {d8} tail call void asm sideeffect "","~{d8},~{d10},~{d11}"() nounwind -; CHECK: vpop {d10, d11} -; CHECK-NEXT: vpop {d8} +; CHECK: vpop {d8} +; CHECK-NEXT: vpop {d10, d11} ret void } diff --git a/test/CodeGen/ARM/vfp-regs-dwarf.ll b/test/CodeGen/ARM/vfp-regs-dwarf.ll new file mode 100644 index 00000000000..49767294ad2 --- /dev/null +++ b/test/CodeGen/ARM/vfp-regs-dwarf.ll @@ -0,0 +1,44 @@ +; RUN: llc -mtriple=armv7-linux-gnueabihf %s -o - | FileCheck %s + +; Generated from: +; void stack_offsets() { +; asm("" ::: "d8", "d9", "d11", "d13"); +; } +; Compiled with: "clang -target armv7-linux-gnueabihf -O3" + +; The important point we're checking here is that the .cfi directives describe +; the layout of the VFP registers correctly. The fact that the numbers are +; monotonic in memory is also a nice property to have. + +define void @stack_offsets() { +; CHECK-LABEL: stack_offsets: +; CHECK: vpush {d13} +; CHECK: vpush {d11} +; CHECK: vpush {d8, d9} + +; CHECK: .cfi_offset {{269|d13}}, -8 +; CHECK: .cfi_offset {{267|d11}}, -16 +; CHECK: .cfi_offset {{265|d9}}, -24 +; CHECK: .cfi_offset {{264|d8}}, -32 + +; CHECK: vpop {d8, d9} +; CHECK: vpop {d11} +; CHECK: vpop {d13} + call void asm sideeffect "", "~{d8},~{d9},~{d11},~{d13}"() #1 + ret void +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9} + +!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5.0 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !"", i32 1} ; [ DW_TAG_compile_unit ] [/Users/tim/llvm/build/tmp.c] [DW_LANG_C99] +!1 = metadata !{metadata !"tmp.c", metadata !"/Users/tim/llvm/build"} +!2 = metadata !{} +!3 = metadata !{metadata !4} +!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"bar", metadata !"bar", metadata !"", i32 1, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, void ()* @stack_offsets, null, null, metadata !2, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [bar] +!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/Users/tim/llvm/build/tmp.c] +!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!7 = metadata !{null} +!8 = metadata !{i32 2, metadata !"Dwarf Version", i32 4} +!9 = metadata !{i32 1, metadata !"Debug Info Version", i32 1} + -- 2.34.1