xref: /llvm-project/clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp (revision 094572701dce4aaf36f4521d6cf750420d39f206)
1 // RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone -O0 \
2 // RUN:     -emit-llvm  -fexperimental-assignment-tracking=forced %s -o -        \
3 // RUN:     -disable-O0-optnone                                                  \
4 // RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
5 
6 // Based on llvm/test/DebugInfo/Generic/track-assignments.ll - check that using
7 // -Xclang -fexperimental-assignment-tracking results in emitting (or, as it is
8 // set up currently, telling llvm to create) assignment tracking metadata.
9 //
10 // See the original test for more info.
11 
12 struct Inner { int A, B; };
13 struct Outer { Inner A, B; };
14 struct Large { int A[10]; };
15 struct LCopyCtor { int A[4]; LCopyCtor(); LCopyCtor(LCopyCtor const &); };
16 int Value, Index, Cond;
17 Inner InnerA, InnerB;
18 Large L;
19 
zeroInit()20 void zeroInit() { int Z[3] = {0, 0, 0}; }
21 // CHECK-LABEL: define dso_local void @_Z8zeroInitv
22 // CHECK:       %Z = alloca [3 x i32], align 4, !DIAssignID ![[ID_0:[0-9]+]]
23 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_0:[0-9]+]], !DIExpression(), ![[ID_0]], ptr %Z, !DIExpression(),
24 // CHECK:        @llvm.memset{{.*}}, !DIAssignID ![[ID_1:[0-9]+]]
25 // CHECK-NEXT:   #dbg_assign(i8 0, ![[VAR_0]], !DIExpression(), ![[ID_1]], ptr %Z, !DIExpression(),
26 
memcpyInit()27 void memcpyInit() { int A[4] = {0, 1, 2, 3}; }
28 // CHECK-LABEL: define dso_local void @_Z10memcpyInitv
29 // CHECK:       %A = alloca [4 x i32], align 16, !DIAssignID ![[ID_2:[0-9]+]]
30 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_1:[0-9]+]], !DIExpression(), ![[ID_2]], ptr %A, !DIExpression(),
31 // CHECK:        @llvm.memcpy{{.*}}, !DIAssignID ![[ID_3:[0-9]+]]
32 // CHECK-NEXT:   #dbg_assign(i1 undef, ![[VAR_1]], !DIExpression(), ![[ID_3]], ptr %A, !DIExpression(),
33 
setField()34 void setField() {
35   Outer O;
36   O.A.B = Value;
37 }
38 // CHECK-LABEL: define dso_local void @_Z8setFieldv
39 // CHECK:       %O = alloca %struct.Outer, align 4, !DIAssignID ![[ID_4:[0-9]+]]
40 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_2:[0-9]+]], !DIExpression(), ![[ID_4]], ptr %O, !DIExpression(),
41 // CHECK:       store i32 %0, ptr %B, align 4,{{.*}}!DIAssignID ![[ID_5:[0-9]+]]
42 // CHECK-NEXT:  #dbg_assign(i32 %0, ![[VAR_2]], !DIExpression(DW_OP_LLVM_fragment, 32, 32), ![[ID_5]], ptr %B, !DIExpression(),
43 
unknownOffset()44 void unknownOffset() {
45   int A[2];
46   A[Index] = Value;
47 }
48 // CHECK-LABEL: define dso_local void @_Z13unknownOffsetv
49 // CHECK:       %A = alloca [2 x i32], align 4, !DIAssignID ![[ID_6:[0-9]+]]
50 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_3:[0-9]+]], !DIExpression(), ![[ID_6]], ptr %A, !DIExpression(),
51 
sharedAlloca()52 Inner sharedAlloca() {
53   if (Cond) {
54     Inner A = InnerA;
55     return A;
56   } else {
57     Inner B = InnerB;
58     return B;
59   }
60 }
61 // CHECK-LABEL: define dso_local i64 @_Z12sharedAllocav
62 // CHECK:       %retval = alloca %struct.Inner, align 4, !DIAssignID ![[ID_7:[0-9]+]]
63 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_4:[0-9]+]], !DIExpression(), ![[ID_7]], ptr %retval, !DIExpression(),
64 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_5:[0-9]+]], !DIExpression(), ![[ID_7]], ptr %retval, !DIExpression(),
65 // CHECK:     if.then:
66 // CHECK:       call void @llvm.memcpy{{.*}}, !DIAssignID ![[ID_8:[0-9]+]]
67 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_4]], !DIExpression(), ![[ID_8]], ptr %retval, !DIExpression(),
68 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_5]], !DIExpression(), ![[ID_8]], ptr %retval, !DIExpression(),
69 // CHECK:     if.else:
70 // CHECK:       call void @llvm.memcpy{{.*}}, !DIAssignID ![[ID_9:[0-9]+]]
71 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_4]], !DIExpression(), ![[ID_9]], ptr %retval, !DIExpression(),
72 // CHECK-NEXT:  #dbg_assign(i1 undef, ![[VAR_5]], !DIExpression(), ![[ID_9]], ptr %retval, !DIExpression(),
73 
sret()74 Large sret() {
75   Large X = L;
76   return X;
77 }
78 // CHECK-LABEL: define dso_local void @_Z4sretv
79 // CHECK:       #dbg_declare
80 
byval(Large X)81 void byval(Large X) {}
82 // CHECK-LABEL: define dso_local void @_Z5byval5Large
83 // CHECK:       #dbg_declare
84 
indirectReturn()85 LCopyCtor indirectReturn() {
86   LCopyCtor R;
87   return R;
88 }
89 // CHECK-LABEL: define dso_local void @_Z14indirectReturnv
90 // CHECK:       #dbg_declare
91 
92 // CHECK-DAG: ![[VAR_0]] = !DILocalVariable(name: "Z",
93 // CHECK-DAG: ![[VAR_1]] = !DILocalVariable(name: "A",
94 // CHECK-DAG: ![[VAR_2]] = !DILocalVariable(name: "O",
95 // CHECK-DAG: ![[VAR_3]] = !DILocalVariable(name: "A",
96 // CHECK-DAG: ![[VAR_4]] = !DILocalVariable(name: "B",
97 // CHECK-DAG: ![[VAR_5]] = !DILocalVariable(name: "A",
98