xref: /llvm-project/clang/test/CodeGen/assignment-tracking/memcpy-fragment.cpp (revision 4b6b2b1a425a2eabb3a4b995bb05f4f53e313afa)
1 // RUN: %clang_cc1 -triple x86_64-none-linux-gnu -debug-info-kind=standalone -O0 \
2 // RUN:     -emit-llvm  -fexperimental-assignment-tracking %s -o -               \
3 // RUN: | FileCheck %s
4 
5 // Check that the (debug) codegen looks right with assignment tracking
6 // enabled. Each fragment that is written to should have a dbg.assign that has
7 // the DIAssignID of the write as an argument. The fragment offset and size
8 // should match the offset into the base storage and size of the store. Each of
9 // the scenarios below results in slightly different arguments generated for
10 // the memcpy.
11 
12 // Test write a complete struct field only.
13 void fragmentWhole()
14 {
15  struct Record {
16    int num;
17    char ch;
18  };
19 
20  Record dest;
21  char src = '\0';
22  __builtin_memcpy(&dest.ch, &src, sizeof(char));
23 }
24 // CHECK: call void @llvm.memcpy{{.+}}, !DIAssignID ![[memberID:[0-9]+]]
25 // CHECK-NEXT: call void @llvm.dbg.assign(metadata{{.*}}undef, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 8), metadata ![[memberID]], metadata ptr %ch, metadata !DIExpression())
26 
27 // Write starting at a field and overlapping part of another.
28 void fragmentWholeToPartial()
29 {
30  struct Record {
31    int num1;
32    int num2;
33  };
34 
35  Record dest;
36  char src[5]="\0\0\0\0";
37  __builtin_memcpy(&dest.num1, &src, 5);
38 }
39 // CHECK: call void @llvm.memcpy{{.+}}, !DIAssignID ![[exceed:[0-9]+]]
40 // CHECK-NEXT: call void @llvm.dbg.assign(metadata{{.*}}undef, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 40), metadata ![[exceed]], metadata ptr %num1, metadata !DIExpression())
41 
42 // Write starting between fields.
43 void fragmentPartialToWhole()
44 {
45  struct record {
46    int num1;
47    int num2;
48    int num3;
49 };
50 
51  record dest;
52  char src[5]="\0\0\0\0";
53  __builtin_memcpy((char*)&(dest.num2) + 3, &src, 5);
54 }
55 // CHECK: call void @llvm.memcpy{{.+}}, !DIAssignID ![[addendID:[0-9]+]]
56 // CHECK-NEXT: call void @llvm.dbg.assign(metadata{{.*}}undef, metadata !{{.*}}, metadata !DIExpression(DW_OP_LLVM_fragment, 56, 40), metadata ![[addendID]], metadata ptr %add.ptr, metadata !DIExpression())
57