xref: /llvm-project/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/frag-2.ll (revision 094572701dce4aaf36f4521d6cf750420d39f206)
1; RUN: opt -passes=sroa -S %s -o - | FileCheck %s
2; RUN: opt --try-experimental-debuginfo-iterators -passes=sroa -S %s -o - | FileCheck %s
3
4;; $ cat test.cpp
5;; class a {
6;; public:
7;;   float b[4];
8;;   void c();
9;; };
10;; class B {
11;; public:
12;;   B(a d) : e(d) {}
13;;   a &f() { return e; }
14;;   B operator*(const B &)const;
15;;   int g;
16;;   a e;
17;; };
18;; B B::operator*(const B &)const { return e; }
19;; class h {
20;; public:
21;;   B i();
22;; };
23;; void j() {
24;;   h convexbody, k;
25;;   B l = k.i(), m = convexbody.i(), n = l * m;
26;;   a o = n.f(); // Looking at this store, o[0, 128] <- n[32, 160].
27;;   o.c();
28;; }
29;; Generated by grabbing IR before sroa in:
30;; $ clang++ -O2 -g -c test.cpp -Xclang -fexperimental-assignment-tracking
31
32;; Check that the store 4xfloat split into 2x store 2xfloat has correct debug
33;; info when the source (n, 160 bits of int+5*float) is split beforehand (see
34;; comment in test.cpp above). Ensure that only the value-expression gets
35;; fragment info; that the address-expression remains untouched.
36
37;; Check nearby instructions to make sure we're looking in the right place.
38; CHECK: define dso_local void @_Z1jv()
39; CHECK: call void @_ZN1h1iEv(ptr nonnull sret(%class.B) align 4 %m,
40
41; CHECK: store <2 x float> %agg.tmp.sroa.0.0.copyload.i, ptr %4, align 4,{{.+}}!DIAssignID ![[id1:[0-9]+]]
42; CHECK: store <2 x float> %agg.tmp.sroa.2.0.copyload.i, ptr %n.sroa.2.4..sroa_idx, align 4,{{.+}}!DIAssignID ![[id2:[0-9]+]]
43; CHECK-NEXT: #dbg_assign(<2 x float> %agg.tmp.sroa.0.0.copyload.i, ![[var:[0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 64), ![[id1]], ptr %4, !DIExpression(),
44; CHECK-NEXT: #dbg_assign(<2 x float> %agg.tmp.sroa.2.0.copyload.i, ![[var]], !DIExpression(DW_OP_LLVM_fragment, 64, 64), ![[id2]], ptr %n.sroa.2.4..sroa_idx, !DIExpression(),
45
46; CHECK: ret
47
48%class.B = type { i32, %class.a }
49%class.a = type { [4 x float] }
50%class.h = type { i8 }
51
52$_ZN1BC2E1a = comdat any
53
54$_ZN1B1fEv = comdat any
55
56; Function Attrs: nofree norecurse nounwind uwtable
57define dso_local void @_ZNK1BmlERKS_(ptr noalias nocapture sret(%class.B) align 4 %agg.result, ptr nocapture readonly %this, ptr nocapture nonnull readnone align 4 dereferenceable(20) %0) local_unnamed_addr #0 align 2 !dbg !7 {
58entry:
59  %agg.tmp.sroa.0.0..sroa_idx = getelementptr inbounds %class.B, ptr %this, i64 0, i32 1, !dbg !42
60  %agg.tmp.sroa.0.0..sroa_cast = bitcast ptr %agg.tmp.sroa.0.0..sroa_idx to ptr, !dbg !42
61  %agg.tmp.sroa.0.0.copyload = load <2 x float>, ptr %agg.tmp.sroa.0.0..sroa_cast, align 4, !dbg !42
62  %agg.tmp.sroa.2.0..sroa_idx2 = getelementptr inbounds %class.B, ptr %this, i64 0, i32 1, i32 0, i64 2, !dbg !42
63  %agg.tmp.sroa.2.0..sroa_cast = bitcast ptr %agg.tmp.sroa.2.0..sroa_idx2 to ptr, !dbg !42
64  %agg.tmp.sroa.2.0.copyload = load <2 x float>, ptr %agg.tmp.sroa.2.0..sroa_cast, align 4, !dbg !42
65  %d.sroa.0.0..sroa_idx.i = getelementptr inbounds %class.B, ptr %agg.result, i64 0, i32 1, !dbg !47
66  %d.sroa.0.0..sroa_cast.i = bitcast ptr %d.sroa.0.0..sroa_idx.i to ptr, !dbg !47
67  store <2 x float> %agg.tmp.sroa.0.0.copyload, ptr %d.sroa.0.0..sroa_cast.i, align 4, !dbg !47
68  %d.sroa.2.0..sroa_idx2.i = getelementptr inbounds %class.B, ptr %agg.result, i64 0, i32 1, i32 0, i64 2, !dbg !47
69  %d.sroa.2.0..sroa_cast.i = bitcast ptr %d.sroa.2.0..sroa_idx2.i to ptr, !dbg !47
70  store <2 x float> %agg.tmp.sroa.2.0.copyload, ptr %d.sroa.2.0..sroa_cast.i, align 4, !dbg !47
71  ret void, !dbg !54
72}
73
74; Function Attrs: argmemonly nofree nosync nounwind willreturn
75declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1
76
77; Function Attrs: nounwind uwtable
78define linkonce_odr dso_local void @_ZN1BC2E1a(ptr %this, <2 x float> %d.coerce0, <2 x float> %d.coerce1) unnamed_addr #2 comdat align 2 !dbg !48 {
79entry:
80  %d.sroa.0.0..sroa_idx = getelementptr inbounds %class.B, ptr %this, i64 0, i32 1, !dbg !55
81  %d.sroa.0.0..sroa_cast = bitcast ptr %d.sroa.0.0..sroa_idx to ptr, !dbg !55
82  store <2 x float> %d.coerce0, ptr %d.sroa.0.0..sroa_cast, align 4, !dbg !55
83  %d.sroa.2.0..sroa_idx2 = getelementptr inbounds %class.B, ptr %this, i64 0, i32 1, i32 0, i64 2, !dbg !55
84  %d.sroa.2.0..sroa_cast = bitcast ptr %d.sroa.2.0..sroa_idx2 to ptr, !dbg !55
85  store <2 x float> %d.coerce1, ptr %d.sroa.2.0..sroa_cast, align 4, !dbg !55
86  ret void, !dbg !56
87}
88
89; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
90declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) #3
91
92; Function Attrs: uwtable
93define dso_local void @_Z1jv() local_unnamed_addr #4 !dbg !57 {
94entry:
95  %convexbody = alloca %class.h, align 1, !DIAssignID !73
96  call void @llvm.dbg.assign(metadata i1 undef, metadata !61, metadata !DIExpression(), metadata !73, metadata ptr %convexbody, metadata !DIExpression()), !dbg !74
97  %k = alloca %class.h, align 1, !DIAssignID !75
98  call void @llvm.dbg.assign(metadata i1 undef, metadata !68, metadata !DIExpression(), metadata !75, metadata ptr %k, metadata !DIExpression()), !dbg !74
99  %l = alloca %class.B, align 4, !DIAssignID !76
100  call void @llvm.dbg.assign(metadata i1 undef, metadata !69, metadata !DIExpression(), metadata !76, metadata ptr %l, metadata !DIExpression()), !dbg !74
101  %m = alloca %class.B, align 4, !DIAssignID !77
102  call void @llvm.dbg.assign(metadata i1 undef, metadata !70, metadata !DIExpression(), metadata !77, metadata ptr %m, metadata !DIExpression()), !dbg !74
103  %n = alloca %class.B, align 4, !DIAssignID !78
104  call void @llvm.dbg.assign(metadata i1 undef, metadata !71, metadata !DIExpression(), metadata !78, metadata ptr %n, metadata !DIExpression()), !dbg !74
105  %o = alloca %class.a, align 4, !DIAssignID !79
106  call void @llvm.dbg.assign(metadata i1 undef, metadata !72, metadata !DIExpression(), metadata !79, metadata ptr %o, metadata !DIExpression()), !dbg !74
107  %0 = getelementptr inbounds %class.h, ptr %convexbody, i64 0, i32 0, !dbg !80
108  %1 = getelementptr inbounds %class.h, ptr %k, i64 0, i32 0, !dbg !80
109  %2 = bitcast ptr %l to ptr, !dbg !81
110  call void @_ZN1h1iEv(ptr nonnull sret(%class.B) align 4 %l, ptr nonnull %k), !dbg !82
111  %3 = bitcast ptr %m to ptr, !dbg !81
112  call void @_ZN1h1iEv(ptr nonnull sret(%class.B) align 4 %m, ptr nonnull %convexbody), !dbg !83
113  %4 = bitcast ptr %n to ptr, !dbg !81
114  %agg.tmp.sroa.0.0..sroa_idx.i = getelementptr inbounds %class.B, ptr %l, i64 0, i32 1, !dbg !84
115  %agg.tmp.sroa.0.0..sroa_cast.i = bitcast ptr %agg.tmp.sroa.0.0..sroa_idx.i to ptr, !dbg !84
116  %agg.tmp.sroa.0.0.copyload.i = load <2 x float>, ptr %agg.tmp.sroa.0.0..sroa_cast.i, align 4, !dbg !84
117  %agg.tmp.sroa.2.0..sroa_idx2.i = getelementptr inbounds %class.B, ptr %l, i64 0, i32 1, i32 0, i64 2, !dbg !84
118  %agg.tmp.sroa.2.0..sroa_cast.i = bitcast ptr %agg.tmp.sroa.2.0..sroa_idx2.i to ptr, !dbg !84
119  %agg.tmp.sroa.2.0.copyload.i = load <2 x float>, ptr %agg.tmp.sroa.2.0..sroa_cast.i, align 4, !dbg !84
120  %d.sroa.0.0..sroa_idx.i.i = getelementptr inbounds %class.B, ptr %n, i64 0, i32 1, !dbg !89
121  %d.sroa.0.0..sroa_cast.i.i = bitcast ptr %d.sroa.0.0..sroa_idx.i.i to ptr, !dbg !89
122  store <2 x float> %agg.tmp.sroa.0.0.copyload.i, ptr %d.sroa.0.0..sroa_cast.i.i, align 4, !dbg !89
123  %d.sroa.2.0..sroa_idx2.i.i = getelementptr inbounds %class.B, ptr %n, i64 0, i32 1, i32 0, i64 2, !dbg !89
124  %d.sroa.2.0..sroa_cast.i.i = bitcast ptr %d.sroa.2.0..sroa_idx2.i.i to ptr, !dbg !89
125  store <2 x float> %agg.tmp.sroa.2.0.copyload.i, ptr %d.sroa.2.0..sroa_cast.i.i, align 4, !dbg !89
126  %5 = bitcast ptr %o to ptr, !dbg !91
127  %e.i = getelementptr inbounds %class.B, ptr %n, i64 0, i32 1, !dbg !92
128  %6 = bitcast ptr %e.i to ptr, !dbg !97
129  call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 4 dereferenceable(16) %5, ptr nonnull align 4 dereferenceable(16) %6, i64 16, i1 false), !dbg !97, !DIAssignID !98
130  call void @llvm.dbg.assign(metadata i1 undef, metadata !72, metadata !DIExpression(), metadata !98, metadata ptr %5, metadata !DIExpression()), !dbg !74
131  call void @_ZN1a1cEv(ptr nonnull %o), !dbg !99
132  ret void, !dbg !100
133}
134
135declare dso_local void @_ZN1h1iEv(ptr sret(%class.B) align 4, ptr) local_unnamed_addr #5
136
137; Function Attrs: nounwind uwtable
138define linkonce_odr dso_local nonnull align 4 dereferenceable(16) ptr @_ZN1B1fEv(ptr %this) local_unnamed_addr #6 comdat align 2 !dbg !93 {
139entry:
140  %e = getelementptr inbounds %class.B, ptr %this, i64 0, i32 1, !dbg !101
141  ret ptr %e, !dbg !102
142}
143
144declare dso_local void @_ZN1a1cEv(ptr) local_unnamed_addr #5
145
146!llvm.dbg.cu = !{!0}
147!llvm.module.flags = !{!3, !4, !5, !1000}
148!llvm.ident = !{!6}
149
150!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 12.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
151!1 = !DIFile(filename: "reduce.cpp", directory: "/")
152!2 = !{}
153!3 = !{i32 7, !"Dwarf Version", i32 4}
154!4 = !{i32 2, !"Debug Info Version", i32 3}
155!5 = !{i32 1, !"wchar_size", i32 4}
156!6 = !{!"clang version 12.0.0"}
157!7 = distinct !DISubprogram(name: "operator*", linkageName: "_ZNK1BmlERKS_", scope: !8, file: !1, line: 14, type: !33, scopeLine: 14, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !32, retainedNodes: !38)
158!8 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "B", file: !1, line: 6, size: 160, flags: DIFlagTypePassByValue | DIFlagNonTrivial, elements: !9, identifier: "_ZTS1B")
159!9 = !{!10, !12, !24, !28, !32}
160!10 = !DIDerivedType(tag: DW_TAG_member, name: "g", scope: !8, file: !1, line: 11, baseType: !11, size: 32, flags: DIFlagPublic)
161!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
162!12 = !DIDerivedType(tag: DW_TAG_member, name: "e", scope: !8, file: !1, line: 12, baseType: !13, size: 128, offset: 32, flags: DIFlagPublic)
163!13 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "a", file: !1, line: 1, size: 128, flags: DIFlagTypePassByValue, elements: !14, identifier: "_ZTS1a")
164!14 = !{!15, !20}
165!15 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !13, file: !1, line: 3, baseType: !16, size: 128, flags: DIFlagPublic)
166!16 = !DICompositeType(tag: DW_TAG_array_type, baseType: !17, size: 128, elements: !18)
167!17 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
168!18 = !{!19}
169!19 = !DISubrange(count: 4)
170!20 = !DISubprogram(name: "c", linkageName: "_ZN1a1cEv", scope: !13, file: !1, line: 4, type: !21, scopeLine: 4, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
171!21 = !DISubroutineType(types: !22)
172!22 = !{null, !23}
173!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
174!24 = !DISubprogram(name: "B", scope: !8, file: !1, line: 8, type: !25, scopeLine: 8, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
175!25 = !DISubroutineType(types: !26)
176!26 = !{null, !27, !13}
177!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
178!28 = !DISubprogram(name: "f", linkageName: "_ZN1B1fEv", scope: !8, file: !1, line: 9, type: !29, scopeLine: 9, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
179!29 = !DISubroutineType(types: !30)
180!30 = !{!31, !27}
181!31 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !13, size: 64)
182!32 = !DISubprogram(name: "operator*", linkageName: "_ZNK1BmlERKS_", scope: !8, file: !1, line: 10, type: !33, scopeLine: 10, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
183!33 = !DISubroutineType(types: !34)
184!34 = !{!8, !35, !37}
185!35 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !36, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
186!36 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !8)
187!37 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !36, size: 64)
188!38 = !{!39, !41}
189!39 = !DILocalVariable(name: "this", arg: 1, scope: !7, type: !40, flags: DIFlagArtificial | DIFlagObjectPointer)
190!40 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !36, size: 64)
191!41 = !DILocalVariable(arg: 2, scope: !7, file: !1, line: 14, type: !37)
192!42 = !DILocation(line: 14, column: 41, scope: !7)
193!47 = !DILocation(line: 8, column: 12, scope: !48, inlinedAt: !53)
194!48 = distinct !DISubprogram(name: "B", linkageName: "_ZN1BC2E1a", scope: !8, file: !1, line: 8, type: !25, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !24, retainedNodes: !49)
195!49 = !{!50, !52}
196!50 = !DILocalVariable(name: "this", arg: 1, scope: !48, type: !51, flags: DIFlagArtificial | DIFlagObjectPointer)
197!51 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64)
198!52 = !DILocalVariable(name: "d", arg: 2, scope: !48, file: !1, line: 8, type: !13)
199!53 = distinct !DILocation(line: 14, column: 41, scope: !7)
200!54 = !DILocation(line: 14, column: 34, scope: !7)
201!55 = !DILocation(line: 8, column: 12, scope: !48)
202!56 = !DILocation(line: 8, column: 18, scope: !48)
203!57 = distinct !DISubprogram(name: "j", linkageName: "_Z1jv", scope: !1, file: !1, line: 19, type: !58, scopeLine: 19, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !60)
204!58 = !DISubroutineType(types: !59)
205!59 = !{null}
206!60 = !{!61, !68, !69, !70, !71, !72}
207!61 = !DILocalVariable(name: "convexbody", scope: !57, file: !1, line: 20, type: !62)
208!62 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "h", file: !1, line: 15, size: 8, flags: DIFlagTypePassByValue, elements: !63, identifier: "_ZTS1h")
209!63 = !{!64}
210!64 = !DISubprogram(name: "i", linkageName: "_ZN1h1iEv", scope: !62, file: !1, line: 17, type: !65, scopeLine: 17, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
211!65 = !DISubroutineType(types: !66)
212!66 = !{!8, !67}
213!67 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !62, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
214!68 = !DILocalVariable(name: "k", scope: !57, file: !1, line: 20, type: !62)
215!69 = !DILocalVariable(name: "l", scope: !57, file: !1, line: 21, type: !8)
216!70 = !DILocalVariable(name: "m", scope: !57, file: !1, line: 21, type: !8)
217!71 = !DILocalVariable(name: "n", scope: !57, file: !1, line: 21, type: !8)
218!72 = !DILocalVariable(name: "o", scope: !57, file: !1, line: 22, type: !13)
219!73 = distinct !DIAssignID()
220!74 = !DILocation(line: 0, scope: !57)
221!75 = distinct !DIAssignID()
222!76 = distinct !DIAssignID()
223!77 = distinct !DIAssignID()
224!78 = distinct !DIAssignID()
225!79 = distinct !DIAssignID()
226!80 = !DILocation(line: 20, column: 3, scope: !57)
227!81 = !DILocation(line: 21, column: 3, scope: !57)
228!82 = !DILocation(line: 21, column: 11, scope: !57)
229!83 = !DILocation(line: 21, column: 31, scope: !57)
230!84 = !DILocation(line: 14, column: 41, scope: !7, inlinedAt: !85)
231!85 = distinct !DILocation(line: 21, column: 42, scope: !57)
232!89 = !DILocation(line: 8, column: 12, scope: !48, inlinedAt: !90)
233!90 = distinct !DILocation(line: 14, column: 41, scope: !7, inlinedAt: !85)
234!91 = !DILocation(line: 22, column: 3, scope: !57)
235!92 = !DILocation(line: 9, column: 19, scope: !93, inlinedAt: !96)
236!93 = distinct !DISubprogram(name: "f", linkageName: "_ZN1B1fEv", scope: !8, file: !1, line: 9, type: !29, scopeLine: 9, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !28, retainedNodes: !94)
237!94 = !{!95}
238!95 = !DILocalVariable(name: "this", arg: 1, scope: !93, type: !51, flags: DIFlagArtificial | DIFlagObjectPointer)
239!96 = distinct !DILocation(line: 22, column: 11, scope: !57)
240!97 = !DILocation(line: 22, column: 9, scope: !57)
241!98 = distinct !DIAssignID()
242!99 = !DILocation(line: 23, column: 5, scope: !57)
243!100 = !DILocation(line: 24, column: 1, scope: !57)
244!101 = !DILocation(line: 9, column: 19, scope: !93)
245!102 = !DILocation(line: 9, column: 12, scope: !93)
246!1000 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
247