From 4d4149da555cbb29f6fafb150caaf18ecea3a356 Mon Sep 17 00:00:00 2001 From: Mikael Holmen Date: Thu, 21 Sep 2017 11:14:27 +0000 Subject: [PATCH] [SROA] Really remove associated dbg.declare when removing dead alloca Summary: There already was code that tried to remove the dbg.declare, but that code was placed after we had called I->replaceAllUsesWith(UndefValue::get(I->getType())); on the alloca, so when we searched for the relevant dbg.declare, we couldn't find it. Now we do the search before we call RAUW so there is a chance to find it. An existing testcase needed update due to this. Two dbg.declare with undef were removed and then suddenly one of the two CHECKS failed. Before this patch we got call void @llvm.dbg.declare(metadata i24* undef, metadata !14, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 24)), !dbg !15 call void @llvm.dbg.declare(metadata %struct.prog_src_register* undef, metadata !14, metadata !DIExpression()), !dbg !15 call void @llvm.dbg.value(metadata i32 0, metadata !14, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !15 call void @llvm.dbg.value(metadata i32 0, metadata !14, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 24)), !dbg !15 and with it we get call void @llvm.dbg.value(metadata i32 0, metadata !14, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !15 call void @llvm.dbg.value(metadata i32 0, metadata !14, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 24)), !dbg !15 However, the CHECKs in the testcase checked things in a silly order, so they only passed since they found things in the first dbg.declare. Now we changed the order of the checks and the test passes. Reviewers: rnk Reviewed By: rnk Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D37900 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313875 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SROA.cpp | 15 +++--- test/DebugInfo/X86/sroasplit-5.ll | 4 +- test/DebugInfo/X86/sroasplit-dbg-declare.ll | 59 +++++++++++++++++++++ 3 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 test/DebugInfo/X86/sroasplit-dbg-declare.ll diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index d5986a53aa9..b968cb8c892 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -4247,6 +4247,15 @@ void SROA::deleteDeadInstructions( Instruction *I = DeadInsts.pop_back_val(); DEBUG(dbgs() << "Deleting dead instruction: " << *I << "\n"); + // If the instruction is an alloca, find the possible dbg.declare connected + // to it, and remove it too. We must do this before calling RAUW or we will + // not be able to find it. + if (AllocaInst *AI = dyn_cast(I)) { + DeletedAllocas.insert(AI); + for (DbgInfoIntrinsic *OldDII : FindDbgAddrUses(AI)) + OldDII->eraseFromParent(); + } + I->replaceAllUsesWith(UndefValue::get(I->getType())); for (Use &Operand : I->operands()) @@ -4257,12 +4266,6 @@ void SROA::deleteDeadInstructions( DeadInsts.insert(U); } - if (AllocaInst *AI = dyn_cast(I)) { - DeletedAllocas.insert(AI); - for (DbgInfoIntrinsic *OldDII : FindDbgAddrUses(AI)) - OldDII->eraseFromParent(); - } - ++NumDeleted; I->eraseFromParent(); } diff --git a/test/DebugInfo/X86/sroasplit-5.ll b/test/DebugInfo/X86/sroasplit-5.ll index dbd3b49a6cb..78f5ca9a979 100644 --- a/test/DebugInfo/X86/sroasplit-5.ll +++ b/test/DebugInfo/X86/sroasplit-5.ll @@ -20,10 +20,10 @@ target triple = "x86_64-unknown-linux-gnu" ; ; There should be no debug info for the padding. ; CHECK-NOT: DW_OP_LLVM_fragment, 56 -; CHECK: DIExpression(DW_OP_LLVM_fragment, 32, 24) -; CHECK-NOT: DW_OP_LLVM_fragment, 56 ; CHECK: DIExpression(DW_OP_LLVM_fragment, 0, 32) ; CHECK-NOT: DW_OP_LLVM_fragment, 56 +; CHECK: DIExpression(DW_OP_LLVM_fragment, 32, 24) +; CHECK-NOT: DW_OP_LLVM_fragment, 56 %struct.prog_src_register = type { i32, i24 } ; Function Attrs: nounwind diff --git a/test/DebugInfo/X86/sroasplit-dbg-declare.ll b/test/DebugInfo/X86/sroasplit-dbg-declare.ll new file mode 100644 index 00000000000..0a1a41bd591 --- /dev/null +++ b/test/DebugInfo/X86/sroasplit-dbg-declare.ll @@ -0,0 +1,59 @@ +; RUN: opt -S -sroa -o - %s | FileCheck %s + +; SROA should split the alloca in two new ones, each with its own dbg.declare. +; The original alloca and dbg.declare should be removed. + +define void @f1() { +entry: + %0 = alloca [9 x i32] + call void @llvm.dbg.declare(metadata [9 x i32]* %0, metadata !11, metadata !DIExpression()), !dbg !17 + %1 = bitcast [9 x i32]* %0 to i8* + call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 36, i32 16, i1 true) + %2 = getelementptr [9 x i32], [9 x i32]* %0, i32 0, i32 0 + store volatile i32 1, i32* %2 + ret void +} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: argmemonly nounwind +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1) #0 + +attributes #0 = { argmemonly nounwind } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "foo.c", directory: "/bar") +!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 version 6.0.0"} +!7 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !12) +!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 288, elements: !15) +!13 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !14) +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !{!16} +!16 = !DISubrange(count: 9) +!17 = !DILocation(line: 3, column: 18, scope: !7) + +; CHECK-NOT: = alloca [9 x i32] +; CHECK-NOT: call void @llvm.dbg.declare(metadata [9 x i32]* + +; CHECK: %[[VAR1:.*]] = alloca i32 +; CHECK-NEXT: %[[VAR2:.*]] = alloca [8 x i32] +; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32* %[[VAR1]] +; CHECK-NEXT: call void @llvm.dbg.declare(metadata [8 x i32]* %[[VAR2]] + +; CHECK-NOT: = alloca [9 x i32] +; CHECK-NOT: call void @llvm.dbg.declare(metadata [9 x i32]* + -- 2.40.0