1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00
llvm-mirror/test/DebugInfo/X86/dw_op_minus.ll
Adrian Prantl f625c157a1 PR32382: Fix emitting complex DWARF expressions.
The DWARF specification knows 3 kinds of non-empty simple location
descriptions:
1. Register location descriptions
  - describe a variable in a register
  - consist of only a DW_OP_reg
2. Memory location descriptions
  - describe the address of a variable
3. Implicit location descriptions
  - describe the value of a variable
  - end with DW_OP_stack_value & friends

The existing DwarfExpression code is pretty much ignorant of these
restrictions. This used to not matter because we only emitted very
short expressions that we happened to get right by accident.  This
patch makes DwarfExpression aware of the rules defined by the DWARF
standard and now chooses the right kind of location description for
each expression being emitted.

This would have been an NFC commit (for the existing testsuite) if not
for the way that clang describes captured block variables. Based on
how the previous code in LLVM emitted locations, DW_OP_deref
operations that should have come at the end of the expression are put
at its beginning. Fixing this means changing the semantics of
DIExpression, so this patch bumps the version number of DIExpression
and implements a bitcode upgrade.

There are two major changes in this patch:

I had to fix the semantics of dbg.declare for describing function
arguments. After this patch a dbg.declare always takes the *address*
of a variable as the first argument, even if the argument is not an
alloca.

When lowering a DBG_VALUE, the decision of whether to emit a register
location description or a memory location description depends on the
MachineLocation — register machine locations may get promoted to
memory locations based on their DIExpression. (Future) optimization
passes that want to salvage implicit debug location for variables may
do so by appending a DW_OP_stack_value. For example:
  DBG_VALUE, [RBP-8]                        --> DW_OP_fbreg -8
  DBG_VALUE, RAX                            --> DW_OP_reg0 +0
  DBG_VALUE, RAX, DIExpression(DW_OP_deref) --> DW_OP_reg0 +0

All testcases that were modified were regenerated from clang. I also
added source-based testcases for each of these to the debuginfo-tests
repository over the last week to make sure that no synchronized bugs
slip in. The debuginfo-tests compile from source and run the debugger.

https://bugs.llvm.org/show_bug.cgi?id=32382
<rdar://problem/31205000>

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

llvm-svn: 300522
2017-04-18 01:21:53 +00:00

81 lines
3.4 KiB
LLVM

; Test dwarf codegen of DW_OP_minus.
; RUN: llc -O0 -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
; This was built by compiling the following source with SafeStack and
; simplifying the result a little.
; extern "C" {
; void Capture(int *);
; void f() {
; int buf[100];
; Capture(buf);
; }
; }
; The interesting part is !DIExpression(DW_OP_minus, 400)
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@__safestack_unsafe_stack_ptr = external thread_local(initialexec) global i8*
define void @f() !dbg !4 {
entry:
%unsafe_stack_ptr = load i8*, i8** @__safestack_unsafe_stack_ptr
%unsafe_stack_static_top = getelementptr i8, i8* %unsafe_stack_ptr, i32 -400
store i8* %unsafe_stack_static_top, i8** @__safestack_unsafe_stack_ptr
%0 = getelementptr i8, i8* %unsafe_stack_ptr, i32 -400
%buf = bitcast i8* %0 to [100 x i32]*
%1 = bitcast [100 x i32]* %buf to i8*, !dbg !16
call void @llvm.dbg.declare(metadata i8* %unsafe_stack_ptr, metadata !8, metadata !17), !dbg !18
%arraydecay = getelementptr inbounds [100 x i32], [100 x i32]* %buf, i64 0, i64 0, !dbg !19
call void @Capture(i32* %arraydecay), !dbg !20
store i8* %unsafe_stack_ptr, i8** @__safestack_unsafe_stack_ptr, !dbg !21
ret void, !dbg !21
}
; Function Attrs: nounwind readnone
declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
declare void @Capture(i32*)
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!13, !14}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 248518) (llvm/trunk 248512)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "1.cc", directory: "/tmp")
!2 = !{}
!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 4, type: !5, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !7)
!5 = !DISubroutineType(types: !6)
!6 = !{null}
!7 = !{!8}
!8 = !DILocalVariable(name: "buf", scope: !4, file: !1, line: 5, type: !9)
!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 3200, align: 32, elements: !11)
!10 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!11 = !{!12}
!12 = !DISubrange(count: 100)
!13 = !{i32 2, !"Dwarf Version", i32 4}
!14 = !{i32 2, !"Debug Info Version", i32 3}
!15 = !{!"clang version 3.8.0 (trunk 248518) (llvm/trunk 248512)"}
!16 = !DILocation(line: 5, column: 3, scope: !4)
!17 = !DIExpression(DW_OP_minus, 400)
!18 = !DILocation(line: 5, column: 7, scope: !4)
!19 = !DILocation(line: 6, column: 11, scope: !4)
!20 = !DILocation(line: 6, column: 3, scope: !4)
!21 = !DILocation(line: 7, column: 1, scope: !4)
; RCX - 400
; CHECK: .short 3 # Loc expr size
; CHECK-NEXT: .byte 114 # DW_OP_breg2
; CHECK-NEXT: .byte 240 # -400
; CHECK-NEXT: .byte 124
; RCX is clobbered in call @Capture, but there is a spilled copy.
; *(RSP + 8) - 400
; CHECK: .short 7 # Loc expr size
; CHECK-NEXT: .byte 119 # DW_OP_breg7
; CHECK-NEXT: .byte 8 # 8
; CHECK-NEXT: .byte 6 # DW_OP_deref
; CHECK-NEXT: .byte 16 # DW_OP_constu
; CHECK-NEXT: .byte 144 # 400
; CHECK-NEXT: .byte 3 # DW_OP_minus
; CHECK-NEXT: .byte 28