1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
; RUN: llc %s -stop-before finalize-isel -o - \
; RUN: -experimental-debug-variable-locations=false \
; RUN: -debug-ata-coalesce-frags=true \
; RUN: | FileCheck %s --implicit-check-not=DBG_
; RUN: llc --try-experimental-debuginfo-iterators %s -stop-before finalize-isel -o - \
; RUN: -experimental-debug-variable-locations=false \
; RUN: -debug-ata-coalesce-frags=true \
; RUN: | FileCheck %s --implicit-check-not=DBG_
; RUN: llc %s -stop-before finalize-isel -o - \
; RUN: -experimental-debug-variable-locations=true \
; RUN: | FileCheck %s --implicit-check-not=DBG_
; RUN: llc --try-experimental-debuginfo-iterators %s -stop-before finalize-isel -o - \
; RUN: -experimental-debug-variable-locations=true \
; RUN: | FileCheck %s --implicit-check-not=DBG_
;; Check that the mem-loc-frag-fill analysis works on a simple case; ensure
;; that location definitions are added to preserve memory locations of
;; fragments of variables at subsequent location definitions for other
;; fragments of the variable are not currently in memory.
;; Test generated from:
;; $ cat test.cpp
;; struct Nums { int a, b, c; };
;; void esc(struct Nums*);
;; void step();
;; int main() {
;; struct Nums nums = { 1, 2, 1 }; //< Store to .c is elided.
;; step();
;; nums.c = 2; //< Killing store.
;; step();
;; esc(&nums);
;; return 0;
;; }
;; $ clang++ test.cpp -O2 -g -Xclang -fexperimental-assignmment-tracking -emit-llvm -S -o -
;; Most check lines are inline in main.
; CHECK: ![[nums:[0-9]+]] = !DILocalVariable(name: "nums",
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%struct.Nums = type { i32, i32, i32 }
; Function Attrs: mustprogress norecurse uwtable
define dso_local noundef i32 @main() local_unnamed_addr #0 !dbg !7 {
entry:
%nums = alloca %struct.Nums, align 8, !DIAssignID !18
; CHECK: DBG_VALUE %stack.0.nums, $noreg, ![[nums]], !DIExpression(DW_OP_deref)
call void @llvm.dbg.assign(metadata i1 undef, metadata !12, metadata !DIExpression(), metadata !18, metadata ptr %nums, metadata !DIExpression()), !dbg !19
store i64 8589934593, ptr %nums, align 8, !dbg !21, !DIAssignID !22
; CHECK: MOV64mr %stack.0.nums, 1, $noreg, 0, $noreg, killed %0
call void @llvm.dbg.assign(metadata i1 undef, metadata !12, metadata !DIExpression(), metadata !22, metadata ptr %nums, metadata !DIExpression()), !dbg !19
call void @llvm.dbg.assign(metadata i1 undef, metadata !12, metadata !DIExpression(DW_OP_LLVM_fragment, 64, 32), metadata !22, metadata ptr undef, metadata !DIExpression()), !dbg !19
; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[nums]], !DIExpression(DW_OP_LLVM_fragment, 64, 32)
; CHECK-NEXT: DBG_VALUE %stack.0.nums, $noreg, ![[nums]], !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 64)
tail call void @_Z4stepv(), !dbg !23
%c = getelementptr inbounds %struct.Nums, ptr %nums, i64 0, i32 2, !dbg !24
store i32 2, ptr %c, align 8, !dbg !25, !DIAssignID !31
; CHECK: MOV32mi %stack.0.nums, 1, $noreg, 8, $noreg, 2
call void @llvm.dbg.assign(metadata i32 2, metadata !12, metadata !DIExpression(DW_OP_LLVM_fragment, 64, 32), metadata !31, metadata ptr %c, metadata !DIExpression()), !dbg !19
; CHECK-NEXT: DBG_VALUE %stack.0.nums, $noreg, ![[nums]], !DIExpression(DW_OP_deref)
tail call void @_Z4stepv(), !dbg !32
;; Next dbg.assign added by hand to test that the bits [64, 32) have been
;; correctly tracked as in memory - we know this has worked if
;; mem-loc-frag-fill reinstates the memory location after this kill-location
;; for bits [80, 96).
call void @llvm.dbg.assign(metadata i32 poison, metadata !12, metadata !DIExpression(DW_OP_LLVM_fragment, 80, 16), metadata !44, metadata ptr poison, metadata !DIExpression()), !dbg !19
; CHECK: CALL64pcrel32 @_Z4stepv
; CHECK-NEXT: ADJCALLSTACKUP64
; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[nums]], !DIExpression(DW_OP_LLVM_fragment, 80, 16)
; CHECK-NEXT: DBG_VALUE %stack.0.nums, $noreg, ![[nums]], !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 80)
tail call void @_Z4stepv(), !dbg !32
call void @_Z3escP4Nums(ptr noundef nonnull %nums), !dbg !33
ret i32 0, !dbg !35
}
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
declare !dbg !36 dso_local void @_Z4stepv() local_unnamed_addr #2
declare !dbg !40 dso_local void @_Z3escP4Nums(ptr noundef) local_unnamed_addr #2
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) #3
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3, !4, !5, !1000}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "test.cpp", directory: "/")
!2 = !{i32 7, !"Dwarf Version", i32 5}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = !{i32 7, !"uwtable", i32 1}
!6 = !{!"clang version 14.0.0"}
!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 4, type: !8, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
!8 = !DISubroutineType(types: !9)
!9 = !{!10}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = !{!12}
!12 = !DILocalVariable(name: "nums", scope: !7, file: !1, line: 5, type: !13)
!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Nums", file: !1, line: 1, size: 96, flags: DIFlagTypePassByValue, elements: !14, identifier: "_ZTS4Nums")
!14 = !{!15, !16, !17}
!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !1, line: 1, baseType: !10, size: 32)
!16 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !13, file: !1, line: 1, baseType: !10, size: 32, offset: 32)
!17 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !13, file: !1, line: 1, baseType: !10, size: 32, offset: 64)
!18 = distinct !DIAssignID()
!19 = !DILocation(line: 0, scope: !7)
!20 = !DILocation(line: 5, column: 3, scope: !7)
!21 = !DILocation(line: 5, column: 15, scope: !7)
!22 = distinct !DIAssignID()
!23 = !DILocation(line: 6, column: 3, scope: !7)
!24 = !DILocation(line: 7, column: 8, scope: !7)
!25 = !DILocation(line: 7, column: 10, scope: !7)
!31 = distinct !DIAssignID()
!32 = !DILocation(line: 8, column: 3, scope: !7)
!33 = !DILocation(line: 9, column: 3, scope: !7)
!34 = !DILocation(line: 11, column: 1, scope: !7)
!35 = !DILocation(line: 10, column: 3, scope: !7)
!36 = !DISubprogram(name: "step", linkageName: "_Z4stepv", scope: !1, file: !1, line: 3, type: !37, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !39)
!37 = !DISubroutineType(types: !38)
!38 = !{null}
!39 = !{}
!40 = !DISubprogram(name: "esc", linkageName: "_Z3escP4Nums", scope: !1, file: !1, line: 2, type: !41, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !39)
!41 = !DISubroutineType(types: !42)
!42 = !{null, !43}
!43 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
!44 = distinct !DIAssignID()
!1000 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
|