14ece5073SOCHyams; RUN: opt -passes='declare-to-assign,verify' %s -S -o - \ 2913b561cSOCHyams; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg" 3d3a6a90aSStephen Tozer; RUN: opt --try-experimental-debuginfo-iterators -passes='declare-to-assign,verify' %s -S -o - \ 4d3a6a90aSStephen Tozer; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg" 5913b561cSOCHyams 6913b561cSOCHyams;; This test checks that `trackAssignments` is working correctly by using the 7913b561cSOCHyams;; pass-wrapper `declare-to-assign`. Each function checks some specific 8913b561cSOCHyams;; functionality and has its checks inline. 9913b561cSOCHyams 10913b561cSOCHyams;; $ cat test.cpp 11913b561cSOCHyams;; struct Inner { int A, B; }; 12913b561cSOCHyams;; struct Outer { Inner A, B; }; 13913b561cSOCHyams;; struct Large { int A[10]; }; 14913b561cSOCHyams;; struct LCopyCtor { int A[4]; LCopyCtor(); LCopyCtor(LCopyCtor const &); }; 15913b561cSOCHyams;; int Value, Index, Cond; 16913b561cSOCHyams;; Inner InnerA, InnerB; 17913b561cSOCHyams;; Large L; 18913b561cSOCHyams;; 19913b561cSOCHyams;; void zeroInit() { int Z[3] = {0, 0, 0}; } 20913b561cSOCHyams;; 21913b561cSOCHyams;; void memcpyInit() { int A[4] = {0, 1, 2, 3}; } 22913b561cSOCHyams;; 23913b561cSOCHyams;; void setField() { 24913b561cSOCHyams;; Outer O; 25913b561cSOCHyams;; O.A.B = Value; 26913b561cSOCHyams;; } 27913b561cSOCHyams;; 28913b561cSOCHyams;; void unknownOffset() { 29913b561cSOCHyams;; int A[2]; 30913b561cSOCHyams;; A[Index] = Value; 31913b561cSOCHyams;; } 32913b561cSOCHyams;; 33913b561cSOCHyams;; Inner sharedAlloca() { 34913b561cSOCHyams;; if (Cond) { 35913b561cSOCHyams;; Inner A = InnerA; 36913b561cSOCHyams;; return A; 37913b561cSOCHyams;; } else { 38913b561cSOCHyams;; Inner B = InnerB; 39913b561cSOCHyams;; return B; 40913b561cSOCHyams;; } 41913b561cSOCHyams;; } 42913b561cSOCHyams;; 43913b561cSOCHyams;; Large sret() { 44913b561cSOCHyams;; Large X = L; 45913b561cSOCHyams;; return X; 46913b561cSOCHyams;; } 47913b561cSOCHyams;; 48913b561cSOCHyams;; void byval(Large X) {} 49913b561cSOCHyams;; 50913b561cSOCHyams;; LCopyCtor indirectReturn() { 51913b561cSOCHyams;; LCopyCtor R; 52913b561cSOCHyams;; return R; 53913b561cSOCHyams;; } 54913b561cSOCHyams;; 55913b561cSOCHyams;; $ clang++ -g test.cpp -o - -emit-llvm -S -Xclang -disable-llvm-passes -O2 56913b561cSOCHyams;; 57913b561cSOCHyams;; Then these functions are added manually to the IR using 58913b561cSOCHyams;; $ clang++ -g test.cpp -o - -emit-llvm -S -O0 59913b561cSOCHyams;; and removing the optnone attributes: 60913b561cSOCHyams;; 61913b561cSOCHyams;; __attribute__((always_inline)) 62913b561cSOCHyams;; int sqr(int Y) { return Y * Y; } 63913b561cSOCHyams;; int fun(int X) { return sqr(X); } 64913b561cSOCHyams 65913b561cSOCHyams 66913b561cSOCHyamssource_filename = "test.cpp" 67913b561cSOCHyamstarget datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 68913b561cSOCHyamstarget triple = "x86_64-unknown-linux-gnu" 69913b561cSOCHyams 70913b561cSOCHyams%struct.Inner = type { i32, i32 } 71913b561cSOCHyams%struct.Large = type { [10 x i32] } 72913b561cSOCHyams%struct.Outer = type { %struct.Inner, %struct.Inner } 73913b561cSOCHyams%struct.LCopyCtor = type { [4 x i32] } 74913b561cSOCHyams 75913b561cSOCHyams@Value = dso_local global i32 0, align 4, !dbg !0 76913b561cSOCHyams@Index = dso_local global i32 0, align 4, !dbg !5 77913b561cSOCHyams@Cond = dso_local global i32 0, align 4, !dbg !8 78913b561cSOCHyams@InnerA = dso_local global %struct.Inner zeroinitializer, align 4, !dbg !10 79913b561cSOCHyams@InnerB = dso_local global %struct.Inner zeroinitializer, align 4, !dbg !16 80913b561cSOCHyams@L = dso_local global %struct.Large zeroinitializer, align 4, !dbg !18 81913b561cSOCHyams@__const._Z10memcpyInitv.A = private unnamed_addr constant [4 x i32] [i32 0, i32 1, i32 2, i32 3], align 16 82913b561cSOCHyams 83913b561cSOCHyams;; Zero init with a memset. 84913b561cSOCHyams;; 85913b561cSOCHyams;; void zeroInit() { int Z[3] = {0, 0, 0}; } 86913b561cSOCHyams;; 87913b561cSOCHyams;; Check that we get two dbg.assign intrinsics. The first linked to the alloca 88913b561cSOCHyams;; and the second linked to the zero-init-memset, which should have a constant 0 89913b561cSOCHyams;; for the value component. 90913b561cSOCHyamsdefine dso_local void @_Z8zeroInitv() #0 !dbg !31 { 91913b561cSOCHyams; CHECK-LABEL: define dso_local void @_Z8zeroInitv 92913b561cSOCHyamsentry: 93913b561cSOCHyams %Z = alloca [3 x i32], align 4 94913b561cSOCHyams; CHECK: %Z = alloca [3 x i32], align 4, !DIAssignID ![[ID_0:[0-9]+]] 95*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_0:[0-9]+]], !DIExpression(), ![[ID_0]], ptr %Z, !DIExpression(), 96a5b457b7SOCHyams %0 = bitcast ptr %Z to ptr, !dbg !39 973a05e01dSFangrui Song call void @llvm.lifetime.start.p0(i64 12, ptr %0) #5, !dbg !39 98a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %Z, metadata !35, metadata !DIExpression()), !dbg !40 99a5b457b7SOCHyams %1 = bitcast ptr %Z to ptr, !dbg !40 1003a05e01dSFangrui Song call void @llvm.memset.p0.i64(ptr align 4 %1, i8 0, i64 12, i1 false), !dbg !40 101a5b457b7SOCHyams; CHECK: @llvm.memset{{.*}}, !DIAssignID ![[ID_1:[0-9]+]] 102*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i8 0, ![[VAR_0]], !DIExpression(), ![[ID_1]], ptr %1, !DIExpression(), 103a5b457b7SOCHyams %2 = bitcast ptr %Z to ptr, !dbg !41 1043a05e01dSFangrui Song call void @llvm.lifetime.end.p0(i64 12, ptr %2) #5, !dbg !41 105913b561cSOCHyams ret void, !dbg !41 106913b561cSOCHyams} 107913b561cSOCHyams 108913b561cSOCHyams;; Init with a memcpy (from a global). 109913b561cSOCHyams;; 110913b561cSOCHyams;; void memcpyInit() { int A[4] = {0, 1, 2, 3}; } 111913b561cSOCHyams;; 112913b561cSOCHyams;; Check that we get two dbg.assign intrinsics. The first linked to the alloca 113913b561cSOCHyams;; and the second linked to the initialising memcpy, which should have an Undef 114913b561cSOCHyams;; value component. 115913b561cSOCHyamsdefine dso_local void @_Z10memcpyInitv() #0 !dbg !42 { 116913b561cSOCHyams; CHECK-LABEL: define dso_local void @_Z10memcpyInitv 117913b561cSOCHyamsentry: 118913b561cSOCHyams %A = alloca [4 x i32], align 16 119913b561cSOCHyams; CHECK: %A = alloca [4 x i32], align 16, !DIAssignID ![[ID_2:[0-9]+]] 120*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_1:[0-9]+]], !DIExpression(), ![[ID_2]], ptr %A, !DIExpression(), 121a5b457b7SOCHyams %0 = bitcast ptr %A to ptr, !dbg !48 1223a05e01dSFangrui Song call void @llvm.lifetime.start.p0(i64 16, ptr %0) #5, !dbg !48 123a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %A, metadata !44, metadata !DIExpression()), !dbg !49 124a5b457b7SOCHyams %1 = bitcast ptr %A to ptr, !dbg !49 1253a05e01dSFangrui Song call void @llvm.memcpy.p0.p0.i64(ptr align 16 %1, ptr align 16 @__const._Z10memcpyInitv.A, i64 16, i1 false), !dbg !49 126a5b457b7SOCHyams; CHECK: @llvm.memcpy{{.*}}, !DIAssignID ![[ID_3:[0-9]+]] 127*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_1]], !DIExpression(), ![[ID_3]], ptr %1, !DIExpression(), 128a5b457b7SOCHyams %2 = bitcast ptr %A to ptr, !dbg !50 1293a05e01dSFangrui Song call void @llvm.lifetime.end.p0(i64 16, ptr %2) #5, !dbg !50 130913b561cSOCHyams ret void, !dbg !50 131913b561cSOCHyams} 132913b561cSOCHyams 133913b561cSOCHyams;; Assign to field of local variable. 134913b561cSOCHyams;; 135913b561cSOCHyams;; void setField() { 136913b561cSOCHyams;; Outer O; 137913b561cSOCHyams;; O.A.B = Value; 138913b561cSOCHyams;; } 139913b561cSOCHyams;; 140913b561cSOCHyams;; Check that we get two dbg.assign intrinsics. The first linked to the alloca 141913b561cSOCHyams;; and the second linked to the store to O.A.B, which should include the 142913b561cSOCHyams;; appropriate fragment info (SizeInBits: 32, OffsetInBits: 32) with respect to 143913b561cSOCHyams;; the base variable. 144913b561cSOCHyamsdefine dso_local void @_Z8setFieldv() #0 !dbg !51 { 145913b561cSOCHyams; CHECK-LABEL: define dso_local void @_Z8setFieldv 146913b561cSOCHyamsentry: 147913b561cSOCHyams %O = alloca %struct.Outer, align 4 148913b561cSOCHyams; CHECK: %O = alloca %struct.Outer, align 4, !DIAssignID ![[ID_4:[0-9]+]] 149*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_2:[0-9]+]], !DIExpression(), ![[ID_4]], ptr %O, !DIExpression(), 150a5b457b7SOCHyams %0 = bitcast ptr %O to ptr, !dbg !58 1513a05e01dSFangrui Song call void @llvm.lifetime.start.p0(i64 16, ptr %0) #5, !dbg !58 152a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %O, metadata !53, metadata !DIExpression()), !dbg !59 153a5b457b7SOCHyams %1 = load i32, ptr @Value, align 4, !dbg !60, !tbaa !61 154a5b457b7SOCHyams %A = getelementptr inbounds %struct.Outer, ptr %O, i32 0, i32 0, !dbg !65 155a5b457b7SOCHyams %B = getelementptr inbounds %struct.Inner, ptr %A, i32 0, i32 1, !dbg !66 156a5b457b7SOCHyams store i32 %1, ptr %B, align 4, !dbg !67, !tbaa !68 157a5b457b7SOCHyams; CHECK: store i32 %1, ptr %B, align 4,{{.*}}!DIAssignID ![[ID_5:[0-9]+]] 158*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i32 %1, ![[VAR_2]], !DIExpression(DW_OP_LLVM_fragment, 32, 32), ![[ID_5]], ptr %B, !DIExpression(), 159a5b457b7SOCHyams %2 = bitcast ptr %O to ptr, !dbg !71 1603a05e01dSFangrui Song call void @llvm.lifetime.end.p0(i64 16, ptr %2) #5, !dbg !71 161913b561cSOCHyams ret void, !dbg !71 162913b561cSOCHyams} 163913b561cSOCHyams 164913b561cSOCHyams;; Assign to (statically) unknown offset into a local variable. 165913b561cSOCHyams;; 166913b561cSOCHyams;; void unknownOffset() { 167913b561cSOCHyams;; int A[2]; 168913b561cSOCHyams;; A[Index] = Value; 169913b561cSOCHyams;; } 170913b561cSOCHyams;; 171913b561cSOCHyams;; Check that we get only one dbg.assign intrinsic and that it is linked to the 172913b561cSOCHyams;; alloca. The assignment doesn't get a dbg.assign intrinsic because we cannot 173913b561cSOCHyams;; encode the fragment info for the assignment. 174913b561cSOCHyams;; Note: This doesn't mean we lose the assignment entirely: the backend will 175913b561cSOCHyams;; interpret the store (as it sees it) as an assignment. 176913b561cSOCHyamsdefine dso_local void @_Z13unknownOffsetv() #0 !dbg !72 { 177913b561cSOCHyams; CHECK-LABEL: define dso_local void @_Z13unknownOffsetv 178913b561cSOCHyamsentry: 179913b561cSOCHyams %A = alloca [2 x i32], align 4 180913b561cSOCHyams; CHECK: %A = alloca [2 x i32], align 4, !DIAssignID ![[ID_6:[0-9]+]] 181*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_3:[0-9]+]], !DIExpression(), ![[ID_6]], ptr %A, !DIExpression(), 182a5b457b7SOCHyams %0 = bitcast ptr %A to ptr, !dbg !78 1833a05e01dSFangrui Song call void @llvm.lifetime.start.p0(i64 8, ptr %0) #5, !dbg !78 184a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %A, metadata !74, metadata !DIExpression()), !dbg !79 185a5b457b7SOCHyams %1 = load i32, ptr @Value, align 4, !dbg !80, !tbaa !61 186a5b457b7SOCHyams %2 = load i32, ptr @Index, align 4, !dbg !81, !tbaa !61 187913b561cSOCHyams %idxprom = sext i32 %2 to i64, !dbg !82 188a5b457b7SOCHyams %arrayidx = getelementptr inbounds [2 x i32], ptr %A, i64 0, i64 %idxprom, !dbg !82 189a5b457b7SOCHyams store i32 %1, ptr %arrayidx, align 4, !dbg !83, !tbaa !61 190a5b457b7SOCHyams %3 = bitcast ptr %A to ptr, !dbg !84 1913a05e01dSFangrui Song call void @llvm.lifetime.end.p0(i64 8, ptr %3) #5, !dbg !84 192913b561cSOCHyams ret void, !dbg !84 193913b561cSOCHyams} 194913b561cSOCHyams 195913b561cSOCHyams;; Assignments to variables which share the same backing storage. 196913b561cSOCHyams;; 197913b561cSOCHyams;; Inner sharedAlloca() { 198913b561cSOCHyams;; if (Cond) { 199913b561cSOCHyams;; Inner A = InnerA; 200913b561cSOCHyams;; return A; 201913b561cSOCHyams;; } else { 202913b561cSOCHyams;; Inner B = InnerB; 203913b561cSOCHyams;; return B; 204913b561cSOCHyams;; } 205913b561cSOCHyams;; } 206913b561cSOCHyams;; 207913b561cSOCHyamsdefine dso_local i64 @_Z12sharedAllocav() #0 !dbg !85 { 208913b561cSOCHyams; CHECK-LABEL: define dso_local i64 @_Z12sharedAllocav 209913b561cSOCHyamsentry: 210913b561cSOCHyams %retval = alloca %struct.Inner, align 4 211913b561cSOCHyams; CHECK: %retval = alloca %struct.Inner, align 4, !DIAssignID ![[ID_7:[0-9]+]] 212*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_4:[0-9]+]], !DIExpression(), ![[ID_7]], ptr %retval, !DIExpression(), 213*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_5:[0-9]+]], !DIExpression(), ![[ID_7]], ptr %retval, !DIExpression(), 214a5b457b7SOCHyams %0 = load i32, ptr @Cond, align 4, !dbg !94, !tbaa !61 215913b561cSOCHyams %tobool = icmp ne i32 %0, 0, !dbg !94 216913b561cSOCHyams br i1 %tobool, label %if.then, label %if.else, !dbg !95 217913b561cSOCHyams 218913b561cSOCHyamsif.then: ; preds = %entry 219913b561cSOCHyams; CHECK: if.then: 220a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %retval, metadata !89, metadata !DIExpression()), !dbg !96 221a5b457b7SOCHyams %1 = bitcast ptr %retval to ptr, !dbg !97 2223a05e01dSFangrui Song call void @llvm.memcpy.p0.p0.i64(ptr align 4 %1, ptr align 4 @InnerA, i64 8, i1 false), !dbg !97, !tbaa.struct !98 223913b561cSOCHyams; CHECK: call void @llvm.memcpy{{.*}}, !DIAssignID ![[ID_8:[0-9]+]] 224*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_4]], !DIExpression(), ![[ID_8]], ptr %1, !DIExpression(), 225*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_5]], !DIExpression(), ![[ID_8]], ptr %1, !DIExpression(), 226913b561cSOCHyams br label %return, !dbg !99 227913b561cSOCHyams 228913b561cSOCHyamsif.else: ; preds = %entry 229913b561cSOCHyams; CHECK: if.else: 230a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %retval, metadata !92, metadata !DIExpression()), !dbg !100 231a5b457b7SOCHyams %2 = bitcast ptr %retval to ptr, !dbg !101 2323a05e01dSFangrui Song call void @llvm.memcpy.p0.p0.i64(ptr align 4 %2, ptr align 4 @InnerB, i64 8, i1 false), !dbg !101, !tbaa.struct !98 233913b561cSOCHyams; CHECK: call void @llvm.memcpy{{.*}}, !DIAssignID ![[ID_9:[0-9]+]] 234*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_4]], !DIExpression(), ![[ID_9]], ptr %2, !DIExpression(), 235*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_5]], !DIExpression(), ![[ID_9]], ptr %2, !DIExpression(), 236913b561cSOCHyams br label %return, !dbg !102 237913b561cSOCHyams 238913b561cSOCHyamsreturn: ; preds = %if.else, %if.then 239a5b457b7SOCHyams %3 = bitcast ptr %retval to ptr, !dbg !103 240a5b457b7SOCHyams %4 = load i64, ptr %3, align 4, !dbg !103 241913b561cSOCHyams ret i64 %4, !dbg !103 242913b561cSOCHyams} 243913b561cSOCHyams 244913b561cSOCHyams;; Caller-allocated memory for a local (sret parameter). 245913b561cSOCHyams;; 246913b561cSOCHyams;; Large sret() { 247913b561cSOCHyams;; Large X = L; 248913b561cSOCHyams;; return X; 249913b561cSOCHyams;; } 250913b561cSOCHyams;; 251913b561cSOCHyams;; TODO: Currently not supported by `trackAssignments` (or the rest of the 252913b561cSOCHyams;; assignment tracking pipeline). In lieu of being able to xfail a part of a 253913b561cSOCHyams;; test, check that the dbg.declare is preserved so the test fails (and can be 254913b561cSOCHyams;; updated) when this is fixed. 255a5b457b7SOCHyamsdefine dso_local void @_Z4sretv(ptr noalias sret(%struct.Large) align 4 %agg.result) #0 !dbg !104 { 256913b561cSOCHyams; CHECK-LABEL: define dso_local void @_Z4sretv 257913b561cSOCHyamsentry: 258*09457270SStephen Tozer; CHECK: #dbg_declare 259a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %agg.result, metadata !108, metadata !DIExpression()), !dbg !109 260a5b457b7SOCHyams %0 = bitcast ptr %agg.result to ptr, !dbg !110 2613a05e01dSFangrui Song call void @llvm.memcpy.p0.p0.i64(ptr align 4 %0, ptr align 4 @L, i64 40, i1 false), !dbg !110, !tbaa.struct !111 262913b561cSOCHyams ret void, !dbg !113 263913b561cSOCHyams} 264913b561cSOCHyams 265913b561cSOCHyams;; Caller-allocated memory for a local (byval parameter). 266913b561cSOCHyams;; 267913b561cSOCHyams;; void byval(Large X) {} 268913b561cSOCHyams;; 269913b561cSOCHyams;; TODO: See comment for sret parameters above. 270a5b457b7SOCHyamsdefine dso_local void @_Z5byval5Large(ptr noundef byval(%struct.Large) align 8 %X) #0 !dbg !114 { 271913b561cSOCHyams; CHECK-LABEL: define dso_local void @_Z5byval5Large 272913b561cSOCHyamsentry: 273*09457270SStephen Tozer; CHECK: #dbg_declare 274a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %X, metadata !118, metadata !DIExpression()), !dbg !119 275913b561cSOCHyams ret void, !dbg !120 276913b561cSOCHyams} 277913b561cSOCHyams 278913b561cSOCHyams;; Caller-allocated memory for a local (sret parameter) with address stored to 279913b561cSOCHyams;; local alloca. 280913b561cSOCHyams;; 281913b561cSOCHyams;; LCopyCtor indirectReturn() { 282913b561cSOCHyams;; LCopyCtor R; 283913b561cSOCHyams;; return R; 284913b561cSOCHyams;; } 285913b561cSOCHyams;; 286913b561cSOCHyams;; A sret parameter is used here also, but in this case clang emits an alloca 287913b561cSOCHyams;; to store the passed-in address for the storage for the variable. The 288913b561cSOCHyams;; dbg.declare for the local R therefore requires a DW_OP_deref expression. 289913b561cSOCHyams;; TODO: This isn't supported yet, so check the dbg.declare remains. 290a5b457b7SOCHyamsdefine dso_local void @_Z14indirectReturnv(ptr noalias sret(%struct.LCopyCtor) align 4 %agg.result) #0 !dbg !121 { 291913b561cSOCHyams; CHECK-LABEL: define dso_local void @_Z14indirectReturnv 292913b561cSOCHyamsentry: 293a5b457b7SOCHyams %result.ptr = alloca ptr, align 8 294a5b457b7SOCHyams %0 = bitcast ptr %agg.result to ptr 295a5b457b7SOCHyams store ptr %0, ptr %result.ptr, align 8 296a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %result.ptr, metadata !126, metadata !DIExpression(DW_OP_deref)), !dbg !127 297*09457270SStephen Tozer; CHECK: #dbg_declare 298a5b457b7SOCHyams call void @_ZN9LCopyCtorC1Ev(ptr noundef nonnull align 4 dereferenceable(16) %agg.result), !dbg !127 299913b561cSOCHyams ret void, !dbg !128 300913b561cSOCHyams} 301913b561cSOCHyams 302913b561cSOCHyams;; Inlined variable. 303913b561cSOCHyams;; 304913b561cSOCHyams;; __attribute__((always_inline)) 305913b561cSOCHyams;; int sqr(int Y) { return Y * Y; } 306913b561cSOCHyams;; int fun(int X) { return sqr(X); } 307913b561cSOCHyams;; 308913b561cSOCHyams;; Check that dbg.assign intrinsics correctly inherit the !dbg attachment from 309913b561cSOCHyams;; the dbg.declre. 310913b561cSOCHyamsdefine dso_local noundef i32 @_Z3funi(i32 noundef %X) !dbg !139 { 311913b561cSOCHyams; CHECK-LABEL: define dso_local noundef i32 @_Z3funi 312913b561cSOCHyamsentry: 313913b561cSOCHyams %Y.addr.i = alloca i32, align 4 314913b561cSOCHyams; CHECK: %Y.addr.i = alloca i32, align 4, !DIAssignID ![[ID_10:[0-9]+]] 315*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_6:[0-9]+]], !DIExpression(), ![[ID_10]], ptr %Y.addr.i, !DIExpression(), ![[DBG_0:[0-9]+]] 316913b561cSOCHyams %X.addr = alloca i32, align 4 317913b561cSOCHyams; CHECK-NEXT: %X.addr = alloca i32, align 4, !DIAssignID ![[ID_11:[0-9]+]] 318*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR_7:[0-9]+]], !DIExpression(), ![[ID_11]], ptr %X.addr, !DIExpression(), ![[DBG_1:[0-9]+]] 319a5b457b7SOCHyams store i32 %X, ptr %X.addr, align 4 320a5b457b7SOCHyams; CHECK-NEXT: store i32 %X, ptr %X.addr, align 4, !DIAssignID ![[ID_12:[0-9]+]] 321*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i32 %X, ![[VAR_7]], !DIExpression(), ![[ID_12]], ptr %X.addr, !DIExpression(), ![[DBG_1]] 322a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %X.addr, metadata !140, metadata !DIExpression()), !dbg !141 323a5b457b7SOCHyams %0 = load i32, ptr %X.addr, align 4, !dbg !142 324a5b457b7SOCHyams store i32 %0, ptr %Y.addr.i, align 4 325a5b457b7SOCHyams; CHECK: store i32 %0, ptr %Y.addr.i, align 4, !DIAssignID ![[ID_13:[0-9]+]] 326*09457270SStephen Tozer; CHECK-NEXT: #dbg_assign(i32 %0, ![[VAR_6]], !DIExpression(), ![[ID_13]], ptr %Y.addr.i, !DIExpression(), ![[DBG_0]] 327a5b457b7SOCHyams call void @llvm.dbg.declare(metadata ptr %Y.addr.i, metadata !133, metadata !DIExpression()), !dbg !143 328a5b457b7SOCHyams %1 = load i32, ptr %Y.addr.i, align 4, !dbg !145 329a5b457b7SOCHyams %2 = load i32, ptr %Y.addr.i, align 4, !dbg !146 330913b561cSOCHyams %mul.i = mul nsw i32 %1, %2, !dbg !147 331913b561cSOCHyams ret i32 %mul.i, !dbg !148 332913b561cSOCHyams} 333913b561cSOCHyams 3343a05e01dSFangrui Songdeclare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1 335913b561cSOCHyamsdeclare void @llvm.dbg.declare(metadata, metadata, metadata) #2 3363a05e01dSFangrui Songdeclare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #3 3373a05e01dSFangrui Songdeclare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #4 3383a05e01dSFangrui Songdeclare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1 339a5b457b7SOCHyamsdeclare dso_local void @_ZN9LCopyCtorC1Ev(ptr noundef nonnull align 4 dereferenceable(16)) unnamed_addr 340913b561cSOCHyams 341913b561cSOCHyams!llvm.dbg.cu = !{!2} 3424ece5073SOCHyams!llvm.module.flags = !{!26, !27, !28, !29, !1000} 343913b561cSOCHyams!llvm.ident = !{!30} 344913b561cSOCHyams 345913b561cSOCHyams; CHECK-DAG: ![[VAR_0]] = !DILocalVariable(name: "Z", 346913b561cSOCHyams; CHECK-DAG: ![[VAR_1]] = !DILocalVariable(name: "A", 347913b561cSOCHyams; CHECK-DAG: ![[VAR_2]] = !DILocalVariable(name: "O", 348913b561cSOCHyams; CHECK-DAG: ![[VAR_3]] = !DILocalVariable(name: "A", 349913b561cSOCHyams; CHECK-DAG: ![[VAR_4]] = !DILocalVariable(name: "B", 350913b561cSOCHyams; CHECK-DAG: ![[VAR_5]] = !DILocalVariable(name: "A", 351913b561cSOCHyams; CHECK-DAG: ![[VAR_6]] = !DILocalVariable(name: "Y", arg: 1, scope: ![[SQR:[0-9]+]], 352913b561cSOCHyams; CHECK-DAG: ![[VAR_7]] = !DILocalVariable(name: "X", arg: 1, scope: ![[FUN:[0-9]+]], 353913b561cSOCHyams; CHECK-DAG: ![[SQR]] = distinct !DISubprogram(name: "sqr", 354913b561cSOCHyams; CHECK-DAG: ![[FUN]] = distinct !DISubprogram(name: "fun", 355913b561cSOCHyams; CHECK-DAG: ![[DBG_0]] = !DILocation(line: 0, scope: ![[SQR]], inlinedAt: ![[SQR_INLINE_SITE:[0-9]+]]) 356913b561cSOCHyams; CHECK-DAG: [[SQR_INLINE_SITE]] = distinct !DILocation(line: 3, column: 25, scope: ![[FUN]]) 357913b561cSOCHyams; CHECK-DAG: ![[DBG_1]] = !DILocation(line: 0, scope: ![[FUN]]) 358913b561cSOCHyams 359913b561cSOCHyams!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) 360913b561cSOCHyams!1 = distinct !DIGlobalVariable(name: "Value", scope: !2, file: !3, line: 5, type: !7, isLocal: false, isDefinition: true) 361913b561cSOCHyams!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 14.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) 362913b561cSOCHyams!3 = !DIFile(filename: "test.cpp", directory: "/") 363913b561cSOCHyams!4 = !{!0, !5, !8, !10, !16, !18} 364913b561cSOCHyams!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) 365913b561cSOCHyams!6 = distinct !DIGlobalVariable(name: "Index", scope: !2, file: !3, line: 5, type: !7, isLocal: false, isDefinition: true) 366913b561cSOCHyams!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 367913b561cSOCHyams!8 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression()) 368913b561cSOCHyams!9 = distinct !DIGlobalVariable(name: "Cond", scope: !2, file: !3, line: 5, type: !7, isLocal: false, isDefinition: true) 369913b561cSOCHyams!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) 370913b561cSOCHyams!11 = distinct !DIGlobalVariable(name: "InnerA", scope: !2, file: !3, line: 6, type: !12, isLocal: false, isDefinition: true) 371913b561cSOCHyams!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Inner", file: !3, line: 1, size: 64, flags: DIFlagTypePassByValue, elements: !13, identifier: "_ZTS5Inner") 372913b561cSOCHyams!13 = !{!14, !15} 373913b561cSOCHyams!14 = !DIDerivedType(tag: DW_TAG_member, name: "A", scope: !12, file: !3, line: 1, baseType: !7, size: 32) 374913b561cSOCHyams!15 = !DIDerivedType(tag: DW_TAG_member, name: "B", scope: !12, file: !3, line: 1, baseType: !7, size: 32, offset: 32) 375913b561cSOCHyams!16 = !DIGlobalVariableExpression(var: !17, expr: !DIExpression()) 376913b561cSOCHyams!17 = distinct !DIGlobalVariable(name: "InnerB", scope: !2, file: !3, line: 6, type: !12, isLocal: false, isDefinition: true) 377913b561cSOCHyams!18 = !DIGlobalVariableExpression(var: !19, expr: !DIExpression()) 378913b561cSOCHyams!19 = distinct !DIGlobalVariable(name: "L", scope: !2, file: !3, line: 7, type: !20, isLocal: false, isDefinition: true) 379913b561cSOCHyams!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Large", file: !3, line: 3, size: 320, flags: DIFlagTypePassByValue, elements: !21, identifier: "_ZTS5Large") 380913b561cSOCHyams!21 = !{!22} 381913b561cSOCHyams!22 = !DIDerivedType(tag: DW_TAG_member, name: "A", scope: !20, file: !3, line: 3, baseType: !23, size: 320) 382913b561cSOCHyams!23 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 320, elements: !24) 383913b561cSOCHyams!24 = !{!25} 384913b561cSOCHyams!25 = !DISubrange(count: 10) 385913b561cSOCHyams!26 = !{i32 7, !"Dwarf Version", i32 5} 386913b561cSOCHyams!27 = !{i32 2, !"Debug Info Version", i32 3} 387913b561cSOCHyams!28 = !{i32 1, !"wchar_size", i32 4} 388913b561cSOCHyams!29 = !{i32 7, !"uwtable", i32 1} 389913b561cSOCHyams!30 = !{!"clang version 14.0.0"} 390913b561cSOCHyams!31 = distinct !DISubprogram(name: "zeroInit", linkageName: "_Z8zeroInitv", scope: !3, file: !3, line: 9, type: !32, scopeLine: 9, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !34) 391913b561cSOCHyams!32 = !DISubroutineType(types: !33) 392913b561cSOCHyams!33 = !{null} 393913b561cSOCHyams!34 = !{!35} 394913b561cSOCHyams!35 = !DILocalVariable(name: "Z", scope: !31, file: !3, line: 9, type: !36) 395913b561cSOCHyams!36 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 96, elements: !37) 396913b561cSOCHyams!37 = !{!38} 397913b561cSOCHyams!38 = !DISubrange(count: 3) 398913b561cSOCHyams!39 = !DILocation(line: 9, column: 19, scope: !31) 399913b561cSOCHyams!40 = !DILocation(line: 9, column: 23, scope: !31) 400913b561cSOCHyams!41 = !DILocation(line: 9, column: 41, scope: !31) 401913b561cSOCHyams!42 = distinct !DISubprogram(name: "memcpyInit", linkageName: "_Z10memcpyInitv", scope: !3, file: !3, line: 11, type: !32, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !43) 402913b561cSOCHyams!43 = !{!44} 403913b561cSOCHyams!44 = !DILocalVariable(name: "A", scope: !42, file: !3, line: 11, type: !45) 404913b561cSOCHyams!45 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 128, elements: !46) 405913b561cSOCHyams!46 = !{!47} 406913b561cSOCHyams!47 = !DISubrange(count: 4) 407913b561cSOCHyams!48 = !DILocation(line: 11, column: 21, scope: !42) 408913b561cSOCHyams!49 = !DILocation(line: 11, column: 25, scope: !42) 409913b561cSOCHyams!50 = !DILocation(line: 11, column: 46, scope: !42) 410913b561cSOCHyams!51 = distinct !DISubprogram(name: "setField", linkageName: "_Z8setFieldv", scope: !3, file: !3, line: 13, type: !32, scopeLine: 13, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !52) 411913b561cSOCHyams!52 = !{!53} 412913b561cSOCHyams!53 = !DILocalVariable(name: "O", scope: !51, file: !3, line: 14, type: !54) 413913b561cSOCHyams!54 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Outer", file: !3, line: 2, size: 128, flags: DIFlagTypePassByValue, elements: !55, identifier: "_ZTS5Outer") 414913b561cSOCHyams!55 = !{!56, !57} 415913b561cSOCHyams!56 = !DIDerivedType(tag: DW_TAG_member, name: "A", scope: !54, file: !3, line: 2, baseType: !12, size: 64) 416913b561cSOCHyams!57 = !DIDerivedType(tag: DW_TAG_member, name: "B", scope: !54, file: !3, line: 2, baseType: !12, size: 64, offset: 64) 417913b561cSOCHyams!58 = !DILocation(line: 14, column: 3, scope: !51) 418913b561cSOCHyams!59 = !DILocation(line: 14, column: 9, scope: !51) 419913b561cSOCHyams!60 = !DILocation(line: 15, column: 11, scope: !51) 420913b561cSOCHyams!61 = !{!62, !62, i64 0} 421913b561cSOCHyams!62 = !{!"int", !63, i64 0} 422913b561cSOCHyams!63 = !{!"omnipotent char", !64, i64 0} 423913b561cSOCHyams!64 = !{!"Simple C++ TBAA"} 424913b561cSOCHyams!65 = !DILocation(line: 15, column: 5, scope: !51) 425913b561cSOCHyams!66 = !DILocation(line: 15, column: 7, scope: !51) 426913b561cSOCHyams!67 = !DILocation(line: 15, column: 9, scope: !51) 427913b561cSOCHyams!68 = !{!69, !62, i64 4} 428913b561cSOCHyams!69 = !{!"_ZTS5Outer", !70, i64 0, !70, i64 8} 429913b561cSOCHyams!70 = !{!"_ZTS5Inner", !62, i64 0, !62, i64 4} 430913b561cSOCHyams!71 = !DILocation(line: 16, column: 1, scope: !51) 431913b561cSOCHyams!72 = distinct !DISubprogram(name: "unknownOffset", linkageName: "_Z13unknownOffsetv", scope: !3, file: !3, line: 18, type: !32, scopeLine: 18, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !73) 432913b561cSOCHyams!73 = !{!74} 433913b561cSOCHyams!74 = !DILocalVariable(name: "A", scope: !72, file: !3, line: 19, type: !75) 434913b561cSOCHyams!75 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 64, elements: !76) 435913b561cSOCHyams!76 = !{!77} 436913b561cSOCHyams!77 = !DISubrange(count: 2) 437913b561cSOCHyams!78 = !DILocation(line: 19, column: 3, scope: !72) 438913b561cSOCHyams!79 = !DILocation(line: 19, column: 7, scope: !72) 439913b561cSOCHyams!80 = !DILocation(line: 20, column: 14, scope: !72) 440913b561cSOCHyams!81 = !DILocation(line: 20, column: 5, scope: !72) 441913b561cSOCHyams!82 = !DILocation(line: 20, column: 3, scope: !72) 442913b561cSOCHyams!83 = !DILocation(line: 20, column: 12, scope: !72) 443913b561cSOCHyams!84 = !DILocation(line: 21, column: 1, scope: !72) 444913b561cSOCHyams!85 = distinct !DISubprogram(name: "sharedAlloca", linkageName: "_Z12sharedAllocav", scope: !3, file: !3, line: 23, type: !86, scopeLine: 23, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !88) 445913b561cSOCHyams!86 = !DISubroutineType(types: !87) 446913b561cSOCHyams!87 = !{!12} 447913b561cSOCHyams!88 = !{!89, !92} 448913b561cSOCHyams!89 = !DILocalVariable(name: "A", scope: !90, file: !3, line: 25, type: !12) 449913b561cSOCHyams!90 = distinct !DILexicalBlock(scope: !91, file: !3, line: 24, column: 13) 450913b561cSOCHyams!91 = distinct !DILexicalBlock(scope: !85, file: !3, line: 24, column: 7) 451913b561cSOCHyams!92 = !DILocalVariable(name: "B", scope: !93, file: !3, line: 28, type: !12) 452913b561cSOCHyams!93 = distinct !DILexicalBlock(scope: !91, file: !3, line: 27, column: 10) 453913b561cSOCHyams!94 = !DILocation(line: 24, column: 7, scope: !91) 454913b561cSOCHyams!95 = !DILocation(line: 24, column: 7, scope: !85) 455913b561cSOCHyams!96 = !DILocation(line: 25, column: 11, scope: !90) 456913b561cSOCHyams!97 = !DILocation(line: 25, column: 15, scope: !90) 457913b561cSOCHyams!98 = !{i64 0, i64 4, !61, i64 4, i64 4, !61} 458913b561cSOCHyams!99 = !DILocation(line: 26, column: 5, scope: !90) 459913b561cSOCHyams!100 = !DILocation(line: 28, column: 11, scope: !93) 460913b561cSOCHyams!101 = !DILocation(line: 28, column: 15, scope: !93) 461913b561cSOCHyams!102 = !DILocation(line: 29, column: 5, scope: !93) 462913b561cSOCHyams!103 = !DILocation(line: 31, column: 1, scope: !85) 463913b561cSOCHyams!104 = distinct !DISubprogram(name: "sret", linkageName: "_Z4sretv", scope: !3, file: !3, line: 33, type: !105, scopeLine: 33, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !107) 464913b561cSOCHyams!105 = !DISubroutineType(types: !106) 465913b561cSOCHyams!106 = !{!20} 466913b561cSOCHyams!107 = !{!108} 467913b561cSOCHyams!108 = !DILocalVariable(name: "X", scope: !104, file: !3, line: 34, type: !20) 468913b561cSOCHyams!109 = !DILocation(line: 34, column: 9, scope: !104) 469913b561cSOCHyams!110 = !DILocation(line: 34, column: 13, scope: !104) 470913b561cSOCHyams!111 = !{i64 0, i64 40, !112} 471913b561cSOCHyams!112 = !{!63, !63, i64 0} 472913b561cSOCHyams!113 = !DILocation(line: 35, column: 3, scope: !104) 473913b561cSOCHyams!114 = distinct !DISubprogram(name: "byval", linkageName: "_Z5byval5Large", scope: !3, file: !3, line: 38, type: !115, scopeLine: 38, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !117) 474913b561cSOCHyams!115 = !DISubroutineType(types: !116) 475913b561cSOCHyams!116 = !{null, !20} 476913b561cSOCHyams!117 = !{!118} 477913b561cSOCHyams!118 = !DILocalVariable(name: "X", arg: 1, scope: !114, file: !3, line: 38, type: !20) 478913b561cSOCHyams!119 = !DILocation(line: 38, column: 18, scope: !114) 479913b561cSOCHyams!120 = !DILocation(line: 38, column: 22, scope: !114) 480913b561cSOCHyams!121 = distinct !DISubprogram(name: "indirectReturn", linkageName: "_Z14indirectReturnv", scope: !2, file: !3, line: 41, type: !122, scopeLine: 41, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !125) 481913b561cSOCHyams!122 = !DISubroutineType(types: !123) 482913b561cSOCHyams!123 = !{!124} 483913b561cSOCHyams!124 = !DICompositeType(tag: DW_TAG_structure_type, name: "LCopyCtor", file: !3, line: 4, size: 128, flags: DIFlagFwdDecl | DIFlagNonTrivial, identifier: "_ZTS9LCopyCtor") 484913b561cSOCHyams!125 = !{} 485913b561cSOCHyams!126 = !DILocalVariable(name: "R", scope: !121, file: !3, line: 42, type: !124) 486913b561cSOCHyams!127 = !DILocation(line: 42, column: 13, scope: !121) 487913b561cSOCHyams!128 = !DILocation(line: 43, column: 3, scope: !121) 488913b561cSOCHyams!129 = distinct !DISubprogram(name: "sqr", linkageName: "_Z3sqri", scope: !2, file: !3, line: 2, type: !130, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !132) 489913b561cSOCHyams!130 = !DISubroutineType(types: !131) 490913b561cSOCHyams!131 = !{!7, !7} 491913b561cSOCHyams!132 = !{} 492913b561cSOCHyams!133 = !DILocalVariable(name: "Y", arg: 1, scope: !129, file: !3, line: 2, type: !7) 493913b561cSOCHyams!134 = !DILocation(line: 2, column: 13, scope: !129) 494913b561cSOCHyams!135 = !DILocation(line: 2, column: 25, scope: !129) 495913b561cSOCHyams!136 = !DILocation(line: 2, column: 29, scope: !129) 496913b561cSOCHyams!137 = !DILocation(line: 2, column: 27, scope: !129) 497913b561cSOCHyams!138 = !DILocation(line: 2, column: 18, scope: !129) 498913b561cSOCHyams!139 = distinct !DISubprogram(name: "fun", linkageName: "_Z3funi", scope: !2, file: !3, line: 3, type: !130, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !132) 499913b561cSOCHyams!140 = !DILocalVariable(name: "X", arg: 1, scope: !139, file: !3, line: 3, type: !7) 500913b561cSOCHyams!141 = !DILocation(line: 3, column: 13, scope: !139) 501913b561cSOCHyams!142 = !DILocation(line: 3, column: 29, scope: !139) 502913b561cSOCHyams!143 = !DILocation(line: 2, column: 13, scope: !129, inlinedAt: !144) 503913b561cSOCHyams!144 = distinct !DILocation(line: 3, column: 25, scope: !139) 504913b561cSOCHyams!145 = !DILocation(line: 2, column: 25, scope: !129, inlinedAt: !144) 505913b561cSOCHyams!146 = !DILocation(line: 2, column: 29, scope: !129, inlinedAt: !144) 506913b561cSOCHyams!147 = !DILocation(line: 2, column: 27, scope: !129, inlinedAt: !144) 507913b561cSOCHyams!148 = !DILocation(line: 3, column: 18, scope: !139) 5084ece5073SOCHyams!1000 = !{i32 7, !"debug-info-assignment-tracking", i1 true} 509