ARM: correct Dwarf output for non-contiguous VFP saves.
authorTim Northover <tnorthover@apple.com>
Wed, 12 Mar 2014 11:29:23 +0000 (11:29 +0000)
committerTim Northover <tnorthover@apple.com>
Wed, 12 Mar 2014 11:29:23 +0000 (11:29 +0000)
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
test/CodeGen/ARM/2010-12-07-PEIBug.ll
test/CodeGen/ARM/vfp-regs-dwarf.ll [new file with mode: 0644]

index c35cd23b91cbc019115691d6e5e00b72cc355175..dcae66bc858fbf3e6d966adaca668373d94d8529 100644 (file)
@@ -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;
   }
 }
 
index eef6abd96451e8f95f83fdbb802cc4d3289a9285..4baee64962c83228b5d5e663b49e06480f1b91ed 100644 (file)
@@ -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 (file)
index 0000000..4976729
--- /dev/null
@@ -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}
+