1# RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=btver2 -run-pass=post-RA-sched -o - %s | FileCheck %s 2 3# Test that multiple DBG_VALUE's following an instruction whose register needs 4# to be changed during the post-RA scheduler pass are updated correctly. 5 6# Test case was derived from the output from the following command and 7# the source code below: 8# 9# clang -S -emit-llvm -target x86_64 -march=btver2 -O2 -g -o - <srcfile> | 10# llc -stop-before=post-RA-sched -o - 11# 12# Source code reduced from the original 8MB source file: 13# 14# struct a; 15# class b { 16# public: 17# a *c = ap; 18# unsigned *d() { return (unsigned *)c; } 19# a *ap; 20# }; 21# enum { e = 2 }; 22# template <typename f> f *g(f *h, f *i) { 23# long j = long(i), k = -!h; 24# return reinterpret_cast<f *>(long(h) | k & j); 25# } 26# class l { 27# public: 28# l(int); 29# int m; 30# }; 31# unsigned *n; 32# unsigned o; 33# class p { 34# public: 35# int aa(); 36# unsigned *q() { 37# n = r.d(); 38# return g(n, &o); 39# } 40# b r; 41# }; 42# class s : l { 43# public: 44# p t; 45# s(int h) : l(h), ab(t), ac(~0 << h) { ae(); } 46# p &ab; 47# int ac; 48# void ae() { 49# const unsigned *v; 50# const unsigned u = 0; 51# v = ab.q(); 52# const unsigned *x = g(v, &u); 53# int w = x[m] & ac; 54# while (w) { 55# int z = (ab.aa() - 1) / e; 56# if (m <= z) 57# return; 58# } 59# } 60# }; 61# class ad { 62# public: 63# ~ad() { 64# for (y();;) 65# ; 66# } 67# class y { 68# public: 69# y() : af(0) {} 70# s af; 71# }; 72# }; 73# class ag { 74# ad ah; 75# }; 76# enum ai {}; 77# class aj { 78# public: 79# aj(unsigned(ai)); 80# ag ak; 81# }; 82# struct al { 83# static unsigned am(ai); 84# }; 85# template <int> struct an : al { static aj ao; }; 86# template <> aj an<0>::ao(am); 87 88--- | 89 90 %class.s = type <{ %class.l, [4 x i8], %class.p, %class.p*, i32, [4 x i8] }> 91 %class.l = type { i32 } 92 %class.p = type { %class.b } 93 %class.b = type { %struct.a*, %struct.a* } 94 %struct.a = type opaque 95 96 @n = local_unnamed_addr global i32* null, align 8 97 @o = global i32 0, align 4 98 99 define linkonce_odr void @_ZN1sC2Ei(%class.s*, i32) unnamed_addr #0 align 2 !dbg !4 { 100 %3 = alloca i32, align 4 101 %4 = bitcast %class.s* %0 to %class.l* 102 tail call void @_ZN1lC2Ei(%class.l* %4, i32 %1) 103 %5 = getelementptr inbounds %class.s, %class.s* %0, i64 0, i32 2 104 tail call void @llvm.dbg.value(metadata %class.p* %5, i64 0, metadata !10, metadata !17), !dbg !18 105 tail call void @llvm.dbg.value(metadata %class.p* %5, i64 0, metadata !20, metadata !17), !dbg !27 106 %6 = getelementptr inbounds %class.s, %class.s* %0, i64 0, i32 2, i32 0, i32 1 107 %7 = bitcast %struct.a** %6 to i64* 108 %8 = load i64, i64* %7, align 8 109 %9 = bitcast %class.p* %5 to i64* 110 store i64 %8, i64* %9, align 8 111 %10 = getelementptr inbounds %class.s, %class.s* %0, i64 0, i32 3 112 store %class.p* %5, %class.p** %10, align 8 113 %11 = getelementptr inbounds %class.s, %class.s* %0, i64 0, i32 4 114 %12 = shl i32 -1, %1 115 store i32 %12, i32* %11, align 8 116 store i32 0, i32* %3, align 4 117 %13 = bitcast %class.p* %5 to i32** 118 %14 = load i32*, i32** %13, align 8 119 store i32* %14, i32** @n, align 8 120 %15 = icmp eq i32* %14, null 121 %16 = ptrtoint i32* %14 to i64 122 %17 = select i1 %15, i64 ptrtoint (i32* @o to i64), i64 0 123 %18 = or i64 %17, %16 124 tail call void @llvm.dbg.value(metadata i32* %3, i64 0, metadata !29, metadata !35), !dbg !36 125 tail call void @llvm.dbg.value(metadata i32* %3, i64 0, metadata !39, metadata !17), !dbg !44 126 %19 = ptrtoint i32* %3 to i64 127 call void @llvm.dbg.value(metadata i64 %19, i64 0, metadata !46, metadata !17), !dbg !48 128 %20 = icmp eq i64 %18, 0 129 %21 = select i1 %20, i64 %19, i64 0 130 %22 = or i64 %21, %18 131 %23 = inttoptr i64 %22 to i32* 132 %24 = bitcast %class.s* %0 to i32* 133 %25 = load i32, i32* %24, align 8 134 %26 = sext i32 %25 to i64 135 %27 = getelementptr inbounds i32, i32* %23, i64 %26 136 %28 = load i32, i32* %27, align 4 137 %29 = and i32 %12, %28 138 %30 = icmp eq i32 %29, 0 139 br i1 %30, label %47, label %31 140 141 ; <label>:31: ; preds = %2 142 %32 = bitcast %class.s* %0 to i32* 143 %33 = call i32 @_ZN1p2aaEv(%class.p* %5) 144 %34 = add nsw i32 %33, -1 145 %35 = sdiv i32 %34, 2 146 %36 = load i32, i32* %32, align 8 147 %37 = icmp sgt i32 %36, %35 148 br i1 %37, label %38, label %47 149 150 ; <label>:38: ; preds = %31 151 br label %39 152 153 ; <label>:39: ; preds = %39, %38 154 %40 = bitcast %class.s* %0 to i32* 155 %sunkaddr = ptrtoint %class.s* %0 to i64 156 %sunkaddr1 = add i64 %sunkaddr, 24 157 %sunkaddr2 = inttoptr i64 %sunkaddr1 to %class.p** 158 %41 = load %class.p*, %class.p** %sunkaddr2, align 8 159 %42 = call i32 @_ZN1p2aaEv(%class.p* %41) 160 %43 = add nsw i32 %42, -1 161 %44 = sdiv i32 %43, 2 162 %45 = load i32, i32* %40, align 8 163 %46 = icmp sgt i32 %45, %44 164 br i1 %46, label %39, label %47 165 166 ; <label>:47: ; preds = %39, %31, %2 167 ret void 168 } 169 170 declare void @_ZN1lC2Ei(%class.l*, i32) unnamed_addr #1 171 172 declare i32 @_ZN1p2aaEv(%class.p*) local_unnamed_addr #1 173 174 ; Function Attrs: nounwind readnone 175 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2 176 177 !llvm.dbg.cu = !{!0} 178 !llvm.module.flags = !{!2, !3} 179 180 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) 181 !1 = !DIFile(filename: "test.cpp", directory: "") 182 !2 = !{i32 2, !"Dwarf Version", i32 4} 183 !3 = !{i32 2, !"Debug Info Version", i32 3} 184 !4 = distinct !DISubprogram(name: "s", linkageName: "_ZN1sC2Ei", scope: !5, file: !1, line: 32, type: !6, isLocal: false, isDefinition: true, scopeLine: 32, flags: DIFlagPrototyped, isOptimized: true, unit: !0) 185 !5 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "s", file: !1, line: 29, size: 320, identifier: "_ZTS1s") 186 !6 = !DISubroutineType(types: !7) 187 !7 = !{null, !8, !9} 188 !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) 189 !9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 190 !10 = !DILocalVariable(name: "this", arg: 1, scope: !11, type: !16, flags: DIFlagArtificial | DIFlagObjectPointer) 191 !11 = distinct !DISubprogram(name: "p", linkageName: "_ZN1pC2Ev", scope: !12, file: !1, line: 20, type: !13, isLocal: false, isDefinition: true, scopeLine: 20, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: true, unit: !0) 192 !12 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "p", file: !1, line: 20, size: 128, identifier: "_ZTS1p") 193 !13 = !DISubroutineType(types: !14) 194 !14 = !{null, !15} 195 !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) 196 !16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) 197 !17 = !DIExpression() 198 !18 = !DILocation(line: 0, scope: !11, inlinedAt: !19) 199 !19 = distinct !DILocation(line: 32, column: 3, scope: !4) 200 !20 = !DILocalVariable(name: "this", arg: 1, scope: !21, type: !26, flags: DIFlagArtificial | DIFlagObjectPointer) 201 !21 = distinct !DISubprogram(name: "b", linkageName: "_ZN1bC2Ev", scope: !22, file: !1, line: 2, type: !23, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: true, unit: !0) 202 !22 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "b", file: !1, line: 2, size: 128, identifier: "_ZTS1b") 203 !23 = !DISubroutineType(types: !24) 204 !24 = !{null, !25} 205 !25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) 206 !26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 64) 207 !27 = !DILocation(line: 0, scope: !21, inlinedAt: !28) 208 !28 = distinct !DILocation(line: 20, column: 7, scope: !11, inlinedAt: !19) 209 !29 = !DILocalVariable(name: "u", scope: !30, file: !1, line: 37, type: !33) 210 !30 = distinct !DISubprogram(name: "ae", linkageName: "_ZN1s2aeEv", scope: !5, file: !1, line: 35, type: !31, isLocal: false, isDefinition: true, scopeLine: 35, flags: DIFlagPrototyped, isOptimized: true, unit: !0) 211 !31 = !DISubroutineType(types: !32) 212 !32 = !{null, !8} 213 !33 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !34) 214 !34 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) 215 !35 = !DIExpression(DW_OP_deref) 216 !36 = !DILocation(line: 37, column: 20, scope: !30, inlinedAt: !37) 217 !37 = distinct !DILocation(line: 32, column: 41, scope: !38) 218 !38 = distinct !DILexicalBlock(scope: !4, file: !1, line: 32, column: 39) 219 !39 = !DILocalVariable(name: "i", arg: 2, scope: !40, file: !1, line: 9, type: !43) 220 !40 = distinct !DISubprogram(name: "g<const unsigned int>", linkageName: "_Z1gIKjEPT_S2_S2_", scope: !1, file: !1, line: 9, type: !41, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true, unit: !0) 221 !41 = !DISubroutineType(types: !42) 222 !42 = !{!43, !43, !43} 223 !43 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !33, size: 64) 224 !44 = !DILocation(line: 9, column: 37, scope: !40, inlinedAt: !45) 225 !45 = distinct !DILocation(line: 39, column: 25, scope: !30, inlinedAt: !37) 226 !46 = !DILocalVariable(name: "j", scope: !40, file: !1, line: 10, type: !47) 227 !47 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed) 228 !48 = !DILocation(line: 10, column: 8, scope: !40, inlinedAt: !45) 229 230# CHECK: ![[I_VAR:[0-9]+]] = !DILocalVariable(name: "i", {{.*}}line: 9, {{.*}}) 231# CHECK: ![[I_LOC:[0-9]+]] = !DILocation(line: 9, column: 37, {{.*}}) 232# CHECK: ![[J_VAR:[0-9]+]] = !DILocalVariable(name: "j", {{.*}}line: 10, {{.*}}) 233# CHECK: ![[J_LOC:[0-9]+]] = !DILocation(line: 10, column: 8, {{.*}}) 234 235... 236--- 237name: _ZN1sC2Ei 238tracksRegLiveness: true 239liveins: 240 - { reg: '$rdi' } 241 - { reg: '$esi' } 242fixedStack: 243 - { id: 0, type: spill-slot, offset: -32, size: 8, alignment: 16, callee-saved-register: '$rbx' } 244 - { id: 1, type: spill-slot, offset: -24, size: 8, alignment: 8, callee-saved-register: '$r14' } 245 - { id: 2, type: spill-slot, offset: -16, size: 8, alignment: 16 } 246stack: 247 - { id: 0, offset: -36, size: 4, alignment: 4 } 248body: | 249 bb.0: 250 successors: %bb.3, %bb.2 251 liveins: $esi, $rdi, $r14, $rbx, $rbp 252 253 ; CHECK: [[REGISTER:\$r[a-z0-9]+]] = LEA64r {{\$r[a-z0-9]+}}, 1, $noreg, -20, $noreg 254 ; CHECK-NEXT: DBG_VALUE [[REGISTER]], $noreg, ![[J_VAR]], !DIExpression(), debug-location ![[J_LOC]] 255 ; CHECK-NEXT: DBG_VALUE [[REGISTER]], $noreg, ![[I_VAR]], !DIExpression(), debug-location ![[I_LOC]] 256 257 frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp 258 CFI_INSTRUCTION def_cfa_offset 16 259 CFI_INSTRUCTION offset $rbp, -16 260 $rbp = frame-setup MOV64rr $rsp 261 CFI_INSTRUCTION def_cfa_register $rbp 262 frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp 263 frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp 264 $rsp = frame-setup SUB64ri8 $rsp, 16, implicit-def dead $eflags 265 CFI_INSTRUCTION offset $rbx, -32 266 CFI_INSTRUCTION offset $r14, -24 267 $r14d = MOV32rr $esi 268 $rbx = MOV64rr $rdi 269 CALL64pcrel32 @_ZN1lC2Ei, csr_64, implicit $rsp, implicit $rdi, implicit $esi, implicit-def $rsp 270 $rdi = LEA64r $rbx, 1, $noreg, 8, $noreg 271 DBG_VALUE $rdi, $noreg, !20, !17, debug-location !27 272 DBG_VALUE $rdi, $noreg, !10, !17, debug-location !18 273 $rax = MOV64rm $rbx, 1, $noreg, 16, $noreg :: (load 8) 274 MOV64mr $rbx, 1, $noreg, 8, $noreg, killed $rax :: (store 8) 275 MOV64mr $rbx, 1, $noreg, 24, $noreg, $rdi :: (store 8) 276 $eax = MOV32ri -1 277 $cl = MOV8rr $r14b, implicit killed $r14d 278 $eax = SHL32rCL killed $eax, implicit-def dead $eflags, implicit $cl 279 MOV32mr $rbx, 1, $noreg, 32, $noreg, $eax :: (store 4, align 8) 280 MOV32mi $rbp, 1, $noreg, -20, $noreg, 0 :: (store 4) 281 $rcx = MOV64rm $rbx, 1, $noreg, 8, $noreg :: (load 8) 282 MOV64mr $rip, 1, $noreg, @n, $noreg, $rcx :: (store 8) 283 $edx = XOR32rr undef $edx, undef $edx, implicit-def dead $eflags, implicit-def $rdx 284 TEST64rr $rcx, $rcx, implicit-def $eflags 285 $esi = MOV32ri @o, implicit-def $rsi 286 $rsi = CMOV64rr killed $rsi, $rdx, 5, implicit killed $eflags 287 $rsi = OR64rr killed $rsi, killed $rcx, implicit-def $eflags 288 $rcx = LEA64r $rbp, 1, $noreg, -20, $noreg 289 DBG_VALUE $rcx, $noreg, !46, !17, debug-location !48 290 DBG_VALUE $rcx, $noreg, !39, !17, debug-location !44 291 DBG_VALUE $rbp, -20, !29, !17, debug-location !36 292 $rcx = CMOV64rr killed $rcx, killed $rdx, 5, implicit killed $eflags 293 $rcx = OR64rr killed $rcx, killed $rsi, implicit-def dead $eflags 294 $rdx = MOVSX64rm32 $rbx, 1, $noreg, 0, $noreg :: (load 4, align 8) 295 TEST32mr killed $rcx, 4, killed $rdx, 0, $noreg, killed $eax, implicit-def $eflags :: (load 4) 296 JCC_1 %bb.2, 5, implicit $eflags 297 JMP_1 %bb.3 298 299 bb.1: 300 successors: %bb.2 301 liveins: $rbx, $rbp 302 303 $rdi = MOV64rm $rbx, 1, $noreg, 24, $noreg :: (load 8) 304 305 bb.2: 306 successors: %bb.1, %bb.3 307 liveins: $rbx, $rbp, $rsp, $rdi 308 309 CALL64pcrel32 @_ZN1p2aaEv, csr_64, implicit $rsp, implicit $rdi, implicit-def $rsp, implicit-def $eax 310 $eax = KILL $eax, implicit-def $rax 311 $ecx = LEA64_32r $rax, 1, $noreg, -1, $noreg, implicit-def $rcx 312 $ecx = SHR32ri $ecx, 31, implicit-def dead $eflags, implicit killed $rcx, implicit-def $rcx 313 $eax = LEA64_32r killed $rax, 1, killed $rcx, -1, $noreg 314 $eax = SAR32r1 killed $eax, implicit-def dead $eflags 315 CMP32mr $rbx, 1, $noreg, 0, $noreg, killed $eax, implicit-def $eflags :: (load 4, align 8), (load 4, align 8) 316 JCC_1 %bb.1, 15, implicit killed $eflags 317 318 bb.3: 319 liveins: $rbp 320 321 $rsp = ADD64ri8 $rsp, 16, implicit-def dead $eflags 322 $rbx = POP64r implicit-def $rsp, implicit $rsp 323 $r14 = POP64r implicit-def $rsp, implicit $rsp 324 $rbp = POP64r implicit-def $rsp, implicit $rsp 325 RETQ 326 327... 328