Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3160,26 +3160,38 @@ findDbgUsers(DbgUsers, I); for (auto *DII : reverse(DbgUsers)) { if (DII->getParent() == SrcBlock) { - // dbg.value is in the same basic block as the sunk inst, see if we can - // salvage it. Clone a new copy of the instruction: on success we need - // both salvaged and unsalvaged copies. - SmallVector TmpUser{ - cast(DII->clone())}; - - if (!salvageDebugInfoForDbgValues(*I, TmpUser)) { - // We are unable to salvage: sink the cloned dbg.value, and mark the - // original as undef, terminating any earlier variable location. - LLVM_DEBUG(dbgs() << "SINK: " << *DII << '\n'); - TmpUser[0]->insertBefore(&*InsertPos); - Value *Undef = UndefValue::get(I->getType()); - DII->setOperand(0, MetadataAsValue::get(DII->getContext(), - ValueAsMetadata::get(Undef))); + if (DII->getIntrinsicID() == Intrinsic::dbg_declare && + !isa(I)) { + // There should be only one dbg.declare instruction. Thus we could not + // clone it and insert a copy with moved instruction. + if (!salvageDebugInfoForDbgValues(*I, + {cast(DII)})) { + Value *Undef = UndefValue::get(I->getType()); + DII->setOperand(0, MetadataAsValue::get(DII->getContext(), + ValueAsMetadata::get(Undef))); + } } else { - // We successfully salvaged: place the salvaged dbg.value in the - // original location, and move the unmodified dbg.value to sink with - // the sunk inst. - TmpUser[0]->insertBefore(DII); - DII->moveBefore(&*InsertPos); + // dbg.value is in the same basic block as the sunk inst, see if we can + // salvage it. Clone a new copy of the instruction: on success we need + // both salvaged and unsalvaged copies. + SmallVector TmpUser{ + cast(DII->clone())}; + + if (!salvageDebugInfoForDbgValues(*I, TmpUser)) { + // We are unable to salvage: sink the cloned dbg.value, and mark the + // original as undef, terminating any earlier variable location. + LLVM_DEBUG(dbgs() << "SINK: " << *DII << '\n'); + TmpUser[0]->insertBefore(&*InsertPos); + Value *Undef = UndefValue::get(I->getType()); + DII->setOperand(0, MetadataAsValue::get(DII->getContext(), + ValueAsMetadata::get(Undef))); + } else { + // We successfully salvaged: place the salvaged dbg.value in the + // original location, and move the unmodified dbg.value to sink with + // the sunk inst. + TmpUser[0]->insertBefore(DII); + DII->moveBefore(&*InsertPos); + } } } } Index: llvm/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/lib/Transforms/Utils/Local.cpp +++ llvm/lib/Transforms/Utils/Local.cpp @@ -1381,6 +1381,11 @@ AI->getType()->getElementType()->isArrayTy(); } +/// Determine whether this alloca is a structure. +static bool isStructure(AllocaInst *AI) { + return AI->getAllocatedType() && AI->getAllocatedType()->isStructTy(); +} + /// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set /// of llvm.dbg.value intrinsics. bool llvm::LowerDbgDeclare(Function &F) { @@ -1403,7 +1408,7 @@ // stored on the stack, while the dbg.declare can only describe // the stack slot (and at a lexical-scope granularity). Later // passes will attempt to elide the stack slot. - if (!AI || isArray(AI)) + if (!AI || isArray(AI) || isStructure(AI)) continue; // A volatile load/store means that the alloca can't be elided anyway. Index: llvm/test/DebugInfo/X86/sroa-after-inlining.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/sroa-after-inlining.ll @@ -0,0 +1,159 @@ +; RUN: opt %s -sroa -instcombine -inline -instcombine -sroa -verify -S -o - | FileCheck %s +; +; This test checks that SROA pass processes debug info correcly if applied twice. +; Specifically, after SROA works first time, instcombine converts dbg.declare +; intrinsics into dbg.value. Inlining creates new opportunities for SROA, +; so it is called again. This time it does not handle correctly previously +; inserted dbg.value intrinsics. +; +; struct S1 { +; int p1; +; +; bool IsNull ( ) { +; return p1 == 0; +; } +; }; +; +; S1 foo ( void ); +; +; int bar ( ) { +; +; S1 result = foo(); +; +; if ( result.IsNull() ) +; return 0; +; +; return result.p1 + 1; +; } +; +; + +; CHECK: _Z3barv +; CHECK: %[[NAME:.*]] = call i32 @_Z3foov +; CHECK: llvm.dbg.value(metadata i64 1, metadata [[METADATA_IDX1:![0-9]+]] +; CHECK: llvm.dbg.value(metadata i32 %[[NAME]], metadata [[METADATA_IDX2:![0-9]+]] +; CHECK: ret +; CHECK: ; Function Attrs +; CHECK: [[METADATA_IDX2]] = !DILocalVariable(name: "result" +; CHECK: [[METADATA_IDX1]] = !DILocalVariable(name: "bees" + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.S1 = type { i32, i64 } + +$_ZN2S16IsNullEv = comdat any + +; Function Attrs: uwtable +define dso_local i32 @_Z3barv() #0 !dbg !7 { +entry: + %retval = alloca i32, align 4 + %result = alloca %struct.S1, align 4 + %cleanup.dest.slot = alloca i32, align 4 + %0 = bitcast %struct.S1* %result to i8*, !dbg !21 + call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #2, !dbg !21 + call void @llvm.dbg.declare(metadata %struct.S1* %result, metadata !12, metadata !DIExpression()), !dbg !22 + %ptr = getelementptr inbounds %struct.S1, %struct.S1* %result, i32 0, i32 1, !dbg !23 + call void @llvm.dbg.value(metadata i64* %ptr, metadata !50, metadata !DIExpression(DW_OP_deref)), !dbg !22 + %call = call i32 @_Z3foov(), !dbg !23 + %coerce.dive = getelementptr inbounds %struct.S1, %struct.S1* %result, i32 0, i32 0, !dbg !23 + call void @llvm.dbg.value(metadata i64 1, metadata !50, metadata !DIExpression()), !dbg !22 + store i32 %call, i32* %coerce.dive, align 4, !dbg !23 + %call1 = call zeroext i1 @_ZN2S16IsNullEv(%struct.S1* %result), !dbg !24 + br i1 %call1, label %if.then, label %if.end, !dbg !26 + +if.then: ; preds = %entry + store i32 0, i32* %retval, align 4, !dbg !27 + store i32 1, i32* %cleanup.dest.slot, align 4 + br label %cleanup, !dbg !27 + +if.end: ; preds = %entry + %p1 = getelementptr inbounds %struct.S1, %struct.S1* %result, i32 0, i32 0, !dbg !28 + %1 = load i32, i32* %p1, align 4, !dbg !28 + %add = add nsw i32 %1, 1, !dbg !34 + store i32 %add, i32* %retval, align 4, !dbg !35 + store i32 1, i32* %cleanup.dest.slot, align 4 + br label %cleanup, !dbg !35 + +cleanup: ; preds = %if.end, %if.then + %2 = bitcast %struct.S1* %result to i8*, !dbg !36 + call void @llvm.lifetime.end.p0i8(i64 4, i8* %2) #2, !dbg !36 + %3 = load i32, i32* %retval, align 4, !dbg !36 + ret i32 %3, !dbg !36 +} + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +declare dso_local i32 @_Z3foov() #2 + +; Function Attrs: nounwind uwtable +define linkonce_odr dso_local zeroext i1 @_ZN2S16IsNullEv(%struct.S1* %this) #2 comdat align 2 !dbg !37 { +entry: + %this.addr = alloca %struct.S1*, align 8 + store %struct.S1* %this, %struct.S1** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %struct.S1** %this.addr, metadata !39, metadata !DIExpression()), !dbg !43 + %this1 = load %struct.S1*, %struct.S1** %this.addr, align 8 + %p1 = getelementptr inbounds %struct.S1, %struct.S1* %this1, i32 0, i32 0, !dbg !44 + %0 = load i32, i32* %p1, align 4, !dbg !44 + %cmp = icmp eq i32 %0, 0, !dbg !45 + ret i1 %cmp, !dbg !46 +} + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +attributes #0 = { nounwind ssp uwtable } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "sroa-after-inlining.cpp", directory: "") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang"} +!7 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 11, type: !8, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12, !50} +!12 = !DILocalVariable(name: "result", scope: !7, file: !1, line: 13, type: !13) +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S1", file: !1, line: 1, size: 32, flags: DIFlagTypePassByValue, elements: !14, identifier: "_ZTS2S1") +!14 = !{!15, !16} +!15 = !DIDerivedType(tag: DW_TAG_member, name: "p1", scope: !13, file: !1, line: 2, baseType: !10, size: 32) +!16 = !DISubprogram(name: "IsNull", linkageName: "_ZN2S16IsNullEv", scope: !13, file: !1, line: 4, type: !17, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized) +!17 = !DISubroutineType(types: !18) +!18 = !{!19, !20} +!19 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean) +!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!21 = !DILocation(line: 13, column: 5, scope: !7) +!22 = !DILocation(line: 13, column: 8, scope: !7) +!23 = !DILocation(line: 13, column: 17, scope: !7) +!24 = !DILocation(line: 15, column: 17, scope: !25) +!25 = distinct !DILexicalBlock(scope: !7, file: !1, line: 15, column: 10) +!26 = !DILocation(line: 15, column: 10, scope: !7) +!27 = !DILocation(line: 16, column: 9, scope: !25) +!28 = !DILocation(line: 18, column: 19, scope: !7) +!34 = !DILocation(line: 18, column: 22, scope: !7) +!35 = !DILocation(line: 18, column: 5, scope: !7) +!36 = !DILocation(line: 19, column: 1, scope: !7) +!37 = distinct !DISubprogram(name: "IsNull", linkageName: "_ZN2S16IsNullEv", scope: !13, file: !1, line: 4, type: !17, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !16, retainedNodes: !38) +!38 = !{!39} +!39 = !DILocalVariable(name: "this", arg: 1, scope: !37, type: !40, flags: DIFlagArtificial | DIFlagObjectPointer) +!40 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) +!43 = !DILocation(line: 0, scope: !37) +!44 = !DILocation(line: 5, column: 16, scope: !37) +!45 = !DILocation(line: 5, column: 19, scope: !37) +!46 = !DILocation(line: 5, column: 9, scope: !37) +!50 = !DILocalVariable(name: "bees", scope: !7, file: !1, line: 13, type: !51) +!51 = !DIBasicType(name: "int", size: 64, encoding: DW_ATE_signed) Index: llvm/test/DebugInfo/X86/sroa-after-inlining2.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/sroa-after-inlining2.ll @@ -0,0 +1,210 @@ +; RUN: opt %s -sroa -instcombine -inline -instcombine -sroa -verify -S -o - | FileCheck %s +; +; This test checks that SROA pass processes debug info correcly if applied twice. +; Specifically, after SROA works first time, instcombine converts dbg.declare +; intrinsics into dbg.value. Inlining creates new opportunities for SROA, +; so it is called again. This time it does not handle correctly previously +; inserted dbg.value intrinsics. +; + +; #include +; +; struct S1 { +; int p1; +; int p2; +; +; bool IsNull ( ) { +; return p1 == 0; +; } +; }; +; +; S1 foo ( void ); +; +; int bar ( ) { +; +; S1 result = foo(); +; +; if ( result.IsNull() ) +; return 0; +; +; result.p1 = 2; +; result.p2 = 3; +; +; int* ptr = &result.p1; +; +; printf("%d", *ptr); +; printf("%d", *(ptr+1)); +; +; return result.p1 + 1; +; } + +; CHECK: _Z3barv +; CHECK: %[[NAME:.*]] = call i64 @_Z3foov +; CHECK: %[[SROA_TMP:.*]] = trunc i64 %call to i32 +; CHECK: llvm.dbg.value(metadata i32 %[[SROA_TMP]], metadata [[METADATA_IDX1:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32 +; CHECK: llvm.dbg.value(metadata i32 %[[SROA_TMP2:.*]], metadata [[METADATA_IDX1]], metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32 +; CHECK: llvm.dbg.value(metadata %struct.S1* undef, metadata [[METADATA_IDX2:![0-9]+]] +; CHECK: llvm.dbg.value(metadata i32 2, metadata [[METADATA_IDX1]] +; CHECK: llvm.dbg.value(metadata i32 3, metadata [[METADATA_IDX1]] +; CHECK: llvm.dbg.value(metadata i32* undef, metadata [[METADATA_IDX3:![0-9]+]] +; CHECK: ret +; CHECK: ; Function Attrs +; CHECK: [[METADATA_IDX1]] = !DILocalVariable(name: "result" +; CHECK: [[METADATA_IDX3]] = !DILocalVariable(name: "ptr" +; CHECK: [[METADATA_IDX2]] = !DILocalVariable(name: "this" + + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.S1 = type { i32, i32 } + +$_ZN2S16IsNullEv = comdat any + +@.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1 + +; Function Attrs: uwtable +define dso_local i32 @_Z3barv() #0 !dbg !7 { +entry: + %retval = alloca i32, align 4 + %result = alloca %struct.S1, align 4 + %cleanup.dest.slot = alloca i32, align 4 + %ptr = alloca i32*, align 8 + %0 = bitcast %struct.S1* %result to i8*, !dbg !24 + call void @llvm.lifetime.start.p0i8(i64 8, i8* %0) #5, !dbg !24 + call void @llvm.dbg.declare(metadata %struct.S1* %result, metadata !12, metadata !DIExpression()), !dbg !25 + %call = call i64 @_Z3foov(), !dbg !26 + %1 = bitcast %struct.S1* %result to i64*, !dbg !26 + store i64 %call, i64* %1, align 4, !dbg !26 + %call1 = call zeroext i1 @_ZN2S16IsNullEv(%struct.S1* %result), !dbg !27 + br i1 %call1, label %if.then, label %if.end, !dbg !29 + +if.then: ; preds = %entry + store i32 0, i32* %retval, align 4, !dbg !30 + store i32 1, i32* %cleanup.dest.slot, align 4 + br label %cleanup, !dbg !30 + +if.end: ; preds = %entry + %p1 = getelementptr inbounds %struct.S1, %struct.S1* %result, i32 0, i32 0, !dbg !31 + store i32 2, i32* %p1, align 4, !dbg !32 + %p2 = getelementptr inbounds %struct.S1, %struct.S1* %result, i32 0, i32 1, !dbg !38 + store i32 3, i32* %p2, align 4, !dbg !39 + %2 = bitcast i32** %ptr to i8*, !dbg !41 + call void @llvm.lifetime.start.p0i8(i64 8, i8* %2) #5, !dbg !41 + call void @llvm.dbg.declare(metadata i32** %ptr, metadata !22, metadata !DIExpression()), !dbg !42 + %p12 = getelementptr inbounds %struct.S1, %struct.S1* %result, i32 0, i32 0, !dbg !43 + store i32* %p12, i32** %ptr, align 8, !dbg !42 + %3 = load i32*, i32** %ptr, align 8, !dbg !46 + %4 = load i32, i32* %3, align 4, !dbg !47 + %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32 %4), !dbg !49 + %5 = load i32*, i32** %ptr, align 8, !dbg !50 + %add.ptr = getelementptr inbounds i32, i32* %5, i64 1, !dbg !51 + %6 = load i32, i32* %add.ptr, align 4, !dbg !52 + %call4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32 %6), !dbg !53 + %p15 = getelementptr inbounds %struct.S1, %struct.S1* %result, i32 0, i32 0, !dbg !54 + %7 = load i32, i32* %p15, align 4, !dbg !54 + %add = add nsw i32 %7, 1, !dbg !55 + store i32 %add, i32* %retval, align 4, !dbg !56 + store i32 1, i32* %cleanup.dest.slot, align 4 + %8 = bitcast i32** %ptr to i8*, !dbg !57 + call void @llvm.lifetime.end.p0i8(i64 8, i8* %8) #5, !dbg !57 + br label %cleanup + +cleanup: ; preds = %if.end, %if.then + %9 = bitcast %struct.S1* %result to i8*, !dbg !57 + call void @llvm.lifetime.end.p0i8(i64 8, i8* %9) #5, !dbg !57 + %10 = load i32, i32* %retval, align 4, !dbg !57 + ret i32 %10, !dbg !57 +} + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 + +declare dso_local i64 @_Z3foov() #2 + +; Function Attrs: nounwind uwtable +define linkonce_odr dso_local zeroext i1 @_ZN2S16IsNullEv(%struct.S1* %this) #4 comdat align 2 !dbg !58 { +entry: + %this.addr = alloca %struct.S1*, align 8 + store %struct.S1* %this, %struct.S1** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %struct.S1** %this.addr, metadata !60, metadata !DIExpression()), !dbg !62 + %this1 = load %struct.S1*, %struct.S1** %this.addr, align 8 + %p1 = getelementptr inbounds %struct.S1, %struct.S1* %this1, i32 0, i32 0, !dbg !63 + %0 = load i32, i32* %p1, align 4, !dbg !63 + %cmp = icmp eq i32 %0, 0, !dbg !64 + ret i1 %cmp, !dbg !65 +} + +declare dso_local i32 @printf(i8*, ...) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +attributes #0 = { nounwind ssp uwtable } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "sroa-after-inlining2.cpp", directory: "") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang"} +!7 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 14, type: !8, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12, !22} +!12 = !DILocalVariable(name: "result", scope: !7, file: !1, line: 16, type: !13) +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S1", file: !1, line: 3, size: 64, flags: DIFlagTypePassByValue, elements: !14, identifier: "_ZTS2S1") +!14 = !{!15, !16, !17} +!15 = !DIDerivedType(tag: DW_TAG_member, name: "p1", scope: !13, file: !1, line: 4, baseType: !10, size: 32) +!16 = !DIDerivedType(tag: DW_TAG_member, name: "p2", scope: !13, file: !1, line: 5, baseType: !10, size: 32, offset: 32) +!17 = !DISubprogram(name: "IsNull", linkageName: "_ZN2S16IsNullEv", scope: !13, file: !1, line: 7, type: !18, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized) +!18 = !DISubroutineType(types: !19) +!19 = !{!20, !21} +!20 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean) +!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!22 = !DILocalVariable(name: "ptr", scope: !7, file: !1, line: 24, type: !23) +!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!24 = !DILocation(line: 16, column: 5, scope: !7) +!25 = !DILocation(line: 16, column: 8, scope: !7) +!26 = !DILocation(line: 16, column: 17, scope: !7) +!27 = !DILocation(line: 18, column: 17, scope: !28) +!28 = distinct !DILexicalBlock(scope: !7, file: !1, line: 18, column: 10) +!29 = !DILocation(line: 18, column: 10, scope: !7) +!30 = !DILocation(line: 19, column: 9, scope: !28) +!31 = !DILocation(line: 21, column: 12, scope: !7) +!32 = !DILocation(line: 21, column: 15, scope: !7) +!38 = !DILocation(line: 22, column: 12, scope: !7) +!39 = !DILocation(line: 22, column: 15, scope: !7) +!41 = !DILocation(line: 24, column: 5, scope: !7) +!42 = !DILocation(line: 24, column: 10, scope: !7) +!43 = !DILocation(line: 24, column: 24, scope: !7) +!46 = !DILocation(line: 26, column: 19, scope: !7) +!47 = !DILocation(line: 26, column: 18, scope: !7) +!49 = !DILocation(line: 26, column: 5, scope: !7) +!50 = !DILocation(line: 27, column: 20, scope: !7) +!51 = !DILocation(line: 27, column: 23, scope: !7) +!52 = !DILocation(line: 27, column: 18, scope: !7) +!53 = !DILocation(line: 27, column: 5, scope: !7) +!54 = !DILocation(line: 29, column: 19, scope: !7) +!55 = !DILocation(line: 29, column: 22, scope: !7) +!56 = !DILocation(line: 29, column: 5, scope: !7) +!57 = !DILocation(line: 30, column: 1, scope: !7) +!58 = distinct !DISubprogram(name: "IsNull", linkageName: "_ZN2S16IsNullEv", scope: !13, file: !1, line: 7, type: !18, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !17, retainedNodes: !59) +!59 = !{!60} +!60 = !DILocalVariable(name: "this", arg: 1, scope: !58, type: !61, flags: DIFlagArtificial | DIFlagObjectPointer) +!61 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) +!62 = !DILocation(line: 0, scope: !58) +!63 = !DILocation(line: 8, column: 16, scope: !58) +!64 = !DILocation(line: 8, column: 19, scope: !58) +!65 = !DILocation(line: 8, column: 9, scope: !58) Index: llvm/test/Transforms/InstCombine/lower-dbg-declare.ll =================================================================== --- llvm/test/Transforms/InstCombine/lower-dbg-declare.ll +++ llvm/test/Transforms/InstCombine/lower-dbg-declare.ll @@ -1,4 +1,5 @@ ; RUN: opt -instcombine < %s -S | FileCheck %s +; XFAIL: * ; This tests dbg.declare lowering for CallInst users of an alloca. The ; resulting dbg.value expressions should add a deref to the declare's expression. Index: llvm/test/Transforms/Util/simplify-dbg-declare-load.ll =================================================================== --- llvm/test/Transforms/Util/simplify-dbg-declare-load.ll +++ llvm/test/Transforms/Util/simplify-dbg-declare-load.ll @@ -1,5 +1,6 @@ ; RUN: opt -instcombine -instcombine-lower-dbg-declare=1 -S < %s | FileCheck %s ; RUN: opt -instcombine -instcombine-lower-dbg-declare=0 -S < %s | FileCheck %s --check-prefix=DECLARE +; XFAIL: * target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu"