]> granicus.if.org Git - llvm/commitdiff
[DebugInfo] LiveDebugValues: correctly discriminate kinds of variable locations
authorJeremy Morse <jeremy.morse.llvm@gmail.com>
Thu, 29 Aug 2019 11:20:54 +0000 (11:20 +0000)
committerJeremy Morse <jeremy.morse.llvm@gmail.com>
Thu, 29 Aug 2019 11:20:54 +0000 (11:20 +0000)
The missing line added by this patch ensures that only spilt variable
locations are candidates for being restored from the stack. Otherwise,
register or constant-value information can be interpreted as a spill
location, through a union.

The added regression test replicates a scenario where this occurs: the
stack load from [rsp] causes the register-location DBG_VALUE to be
"restored" to rsi, when it should be left alone. See PR43058 for details.

Un x-fail a test that was suffering from this from a previous patch.

Differential Revision: https://reviews.llvm.org/D66895

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370334 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/LiveDebugValues.cpp
test/CodeGen/ARM/debug-info-blocks.ll
test/DebugInfo/MIR/X86/live-debug-values-restore-collide.mir [new file with mode: 0644]

index cd39950e392e8a8ca800c5f360c9bd5d3e1e9c09..29d307845cfe1c81b393bccc13a49295016d8ea7 100644 (file)
@@ -875,6 +875,7 @@ void LiveDebugValues::transferSpillOrRestoreInst(MachineInstr &MI,
       LLVM_DEBUG(dbgs() << "Spilling Register " << printReg(Reg, TRI) << '('
                         << VarLocIDs[ID].Var.getVar()->getName() << ")\n");
     } else if (TKind == TransferKind::TransferRestore &&
+               VarLocIDs[ID].Kind == VarLoc::SpillLocKind &&
                VarLocIDs[ID].Loc.SpillLocation == *Loc) {
       LLVM_DEBUG(dbgs() << "Restoring Register " << printReg(Reg, TRI) << '('
                         << VarLocIDs[ID].Var.getVar()->getName() << ")\n");
index 4f80db4827976cbc0cc073950e6d9af59c55f354..cc1a45f23da0772c24a61c542c51a18cec57a866 100644 (file)
@@ -1,8 +1,5 @@
 ; RUN: llc -filetype=obj -O0 < %s | llvm-dwarfdump -v - | FileCheck %s
 
-; XFAIL: *
-; PR43058
-
 ; debug_info content
 ; CHECK: DW_AT_name {{.*}} "foobar_func_block_invoke_0"
 ; CHECK-NOT: DW_TAG_subprogram
diff --git a/test/DebugInfo/MIR/X86/live-debug-values-restore-collide.mir b/test/DebugInfo/MIR/X86/live-debug-values-restore-collide.mir
new file mode 100644 (file)
index 0000000..3d133d5
--- /dev/null
@@ -0,0 +1,85 @@
+# RUN: llc %s -o - -run-pass=livedebugvalues -mtriple=x86_64-unknown-unknown | FileCheck %s
+#
+# This is a regression test for register/stack variable locations being
+# interpreted as each other. We place a variable location on the stack, based
+# on $rsp. We later make a memory load from $rsp. On faulty versions of LLVM
+# this gets interpreted as a stack restore of the spilt value (it's not).
+#
+# Test that LiveDebugValues does not create any new variable locations.
+#
+# CHECK-LABEL: name: baaar
+# CHECK-LABEL: bb.0.entry:
+# CHECK:       DBG_VALUE $r9d, $noreg, !{{[0-9]*}}, !DIExpression()
+# CHECK:       DBG_VALUE $rsp, 0, !{{[0-9]*}}, !DIExpression(DW_OP_plus_uconst, 16)
+# CHECK-NOT:   DBG_VALUE
+--- |
+  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-unknown-linux-gnu"
+  
+  define void @baaar() !dbg !4 {
+  entry:
+    ret void
+  }
+  
+  !llvm.module.flags = !{!0, !1}
+  !llvm.dbg.cu = !{!2}
+  
+  !0 = !{i32 2, !"Debug Info Version", i32 3}
+  !1 = !{i32 2, !"Dwarf Version", i32 4}
+  !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+  !3 = !DIFile(filename: "sheep.cpp", directory: ".")
+  !4 = distinct !DISubprogram(name: "baaar", scope: !3, file: !3, line: 1, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
+  !5 = !DISubroutineType(types: !6)
+  !6 = !{!7}
+  !7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+  !8 = !{!9}
+  !9 = !DILocalVariable(name: "moo", scope: !4, file: !3, line: 1, type: !7)
+  !10 = !DILocation(line: 1, scope: !4)
+
+...
+---
+name:            baaar
+alignment:       4
+tracksRegLiveness: true
+liveins:
+  - { reg: '$rdi', virtual-reg: '' }
+  - { reg: '$rsi', virtual-reg: '' }
+  - { reg: '$rdx', virtual-reg: '' }
+  - { reg: '$rcx', virtual-reg: '' }
+  - { reg: '$r8', virtual-reg: '' }
+  - { reg: '$r9d', virtual-reg: '' }
+frameInfo:
+  stackSize:       24
+  offsetAdjustment: -24
+  maxAlignment:    8
+  adjustsStack:    true
+  hasCalls:        true
+fixedStack:
+stack:
+  - { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: spill-slot, offset: -32, size: 8, alignment: 8, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.0.entry:
+    liveins: $rcx, $rdi, $rdx, $rsi, $r8, $r9d, $rbp, $r15, $r14, $r13, $r12, $rbx
+  
+    ; Setup
+    DBG_VALUE $r9d, $noreg, !9, !DIExpression(), debug-location !10
+    $rsp = frame-setup SUB64ri8 $rsp, 24, implicit-def dead $eflags
+
+    ; Spill
+    MOV32mr $rsp, 1, $noreg, 16, $noreg, $r9d :: (store 4 into %stack.0)
+    DBG_VALUE $rsp, 0, !9, !DIExpression(DW_OP_plus_uconst, 16), debug-location !10
+
+    ; This load from the stack can be misinterpreted as a stack restore of
+    ; any DBG_VALUe pointing at $rsp.
+    $rsi = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load 8 from %stack.1)
+
+    ; Return faff
+    $eax = MOV32ri 0
+    $rsp = frame-destroy ADD64ri8 $rsp, 24, implicit-def dead $eflags
+    RETQ debug-location !10
+...