diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1230,12 +1230,13 @@ /// Dbg Intrinsic utilities /// -/// See if there is a dbg.value intrinsic for DIVar before I. +/// See if there is a dbg.value intrinsic for DIVar before/after I. static bool LdStHasDebugValue(DILocalVariable *DIVar, DIExpression *DIExpr, Instruction *I) { // Since we can't guarantee that the original dbg.declare instrinsic // is removed by LowerDbgDeclare(), we need to make sure that we are // not inserting the same dbg.value intrinsic over and over. + // check if the same dbg.value already exists before I BasicBlock::InstListType::iterator PrevI(I); if (PrevI != I->getParent()->getInstList().begin()) { --PrevI; @@ -1245,6 +1246,15 @@ DVI->getExpression() == DIExpr) return true; } + // check if the same dbg.value already exists after I + BasicBlock::InstListType::iterator NextI(I); + ++NextI; + if (NextI != I->getParent()->getInstList().end()) { + if (DbgValueInst *DVI = dyn_cast(NextI)) + if (DVI->getValue() == I && DVI->getVariable() == DIVar && + DVI->getExpression() == DIExpr) + return true; + } return false; } diff --git a/llvm/test/DebugInfo/duplicate_dbgvalue.ll b/llvm/test/DebugInfo/duplicate_dbgvalue.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/duplicate_dbgvalue.ll @@ -0,0 +1,228 @@ +; RUN: opt -O2 -S -o - < %s | FileCheck %s + +; CHECK-LABEL: getelementptr inbounds +; CHECK: call void @llvm.dbg.value(metadata i32 5 +; CHECK-NEXT: tail call i32 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;program main +;integer :: res +; res = mfun() +; print *, res +;contains +; function mfun() +; integer :: i1 +; i1 = 5 +; mfun = fun(i1) +; write (*,*) i1 +; end function +; function fun(a) +; integer, intent (in) :: a +; fun = a +; end function +;end program main +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +; ModuleID = 'duplicate-dbgvalue.f90' +target datalayout = "e-p:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +%struct.struct_ul_MAIN__297 = type { i8*} +%struct.BSS1 = type <{[4 x i8]}> +@.BSS1 = internal global %struct.BSS1 <{[4 x i8] zeroinitializer }> , align 32, !dbg !24 +@.C308_MAIN_ = internal constant i32 25 +@.C284_MAIN_ = internal constant i64 0 +@.C303_MAIN_ = internal constant i32 6 +@.C300_MAIN_ = internal constant [22 x i8] [i8 100,i8 117,i8 112,i8 108,i8 105,i8 99,i8 97,i8 116,i8 101,i8 45,i8 100,i8 98,i8 103,i8 118,i8 97,i8 108,i8 117,i8 101,i8 46,i8 102,i8 57,i8 48] +@.C302_MAIN_ = internal constant i32 4 +@.C283_MAIN_ = internal constant i32 0 +define void @MAIN_() !dbg !14 { +L.entry: + %.S0000_313 = alloca %struct.struct_ul_MAIN__297, align 8 + %z__io_305 = alloca i32, align 4 + %MAIN___$eq_297 = alloca [16 x i8], align 4 + + %0 = bitcast i32* @.C283_MAIN_ to i8*, !dbg !19 + %1 = bitcast void (...)* @fort_init to void (i8*, ...)*, !dbg !19 + call void (i8*, ...) %1 (i8* %0), !dbg !19 + br label %L.LB1_317 +L.LB1_317: + %2 = bitcast %struct.struct_ul_MAIN__297* %.S0000_313 to i64*, !dbg !20 + %3 = call i32 @main_mfun (i64* %2), !dbg !20 + %4 = bitcast %struct.BSS1* @.BSS1 to i32*, !dbg !20 + store i32 %3, i32* %4, align 4, !tbaa !32, !dbg !20 + %5 = bitcast i32* @.C302_MAIN_ to i8*, !dbg !25 + %6 = bitcast [22 x i8]* @.C300_MAIN_ to i8*, !dbg !25 + %7 = bitcast void (...)* @f90io_src_info03a to void (i8*, i8*, i64, ...)*, !dbg !25 + call void (i8*, i8*, i64, ...) %7 (i8* %5, i8* %6, i64 22), !dbg !25 + %8 = bitcast i32* @.C303_MAIN_ to i8*, !dbg !25 + %9 = bitcast i32* @.C283_MAIN_ to i8*, !dbg !25 + %10 = bitcast i32 (...)* @f90io_print_init to i32 (i8*, i8*, i8*, i8*, ...)*, !dbg !25 + %11 = call i32 (i8*, i8*, i8*, i8*, ...) %10 (i8* %8, i8* null, i8* %9, i8* %9), !dbg !25 + call void @llvm.dbg.declare (metadata i32* %z__io_305, metadata !26, metadata !23), !dbg !17 + store i32 %11, i32* %z__io_305, align 4, !tbaa !34, !dbg !25 + %12 = bitcast %struct.BSS1* @.BSS1 to i32*, !dbg !25 + %13 = load i32, i32* %12, align 4, !tbaa !32, !dbg !25 + %14 = bitcast i32 (...)* @f90io_sc_i_ldw to i32 (i32, i32, ...)*, !dbg !25 + %15 = call i32 (i32, i32, ...) %14 (i32 %13, i32 25), !dbg !25 + store i32 %15, i32* %z__io_305, align 4, !tbaa !34, !dbg !25 + %16 = call i32 (...) @f90io_ldw_end (), !dbg !25 + store i32 %16, i32* %z__io_305, align 4, !tbaa !34, !dbg !25 + ret void, !dbg !27 +} +%struct.struct_ul_main_mfun_309 = type { i8*} +@.C306_main_mfun = internal constant i32 25 +@.C283_main_mfun = internal constant i32 0 +@.C284_main_mfun = internal constant i64 0 +@.C302_main_mfun = internal constant i32 6 +@.C300_main_mfun = internal constant [22 x i8] [i8 100,i8 117,i8 112,i8 108,i8 105,i8 99,i8 97,i8 116,i8 101,i8 45,i8 100,i8 98,i8 103,i8 118,i8 97,i8 108,i8 117,i8 101,i8 46,i8 102,i8 57,i8 48] +@.C313_main_mfun = internal constant i32 10 +@.C312_main_mfun = internal constant i32 5 +define internal signext i32 @main_mfun(i64* noalias %.S0000) !dbg !39 { +L.entry: + %i1_311 = alloca i32, align 4 + %mfun_310 = alloca i32, align 4 + %z__io_314 = alloca i32, align 4 + + call void @llvm.dbg.declare (metadata i64* %.S0000, metadata !44, metadata !23), !dbg !42 + br label %L.LB2_320 +L.LB2_320: + call void @llvm.dbg.declare (metadata i32* %i1_311, metadata !46, metadata !23), !dbg !42 + store i32 5, i32* %i1_311, align 4, !tbaa !55, !dbg !45 + %0 = bitcast i32* %i1_311 to i64*, !dbg !47 + %1 = call float @main_fun (i64* %0, i64* %.S0000), !dbg !47 + %2 = fptosi float %1 to i32, !dbg !47 + store i32 %2, i32* %mfun_310, align 4, !tbaa !57, !dbg !47 + %3 = bitcast i32* @.C313_main_mfun to i8*, !dbg !48 + %4 = bitcast [22 x i8]* @.C300_main_mfun to i8*, !dbg !48 + %5 = bitcast void (...)* @f90io_src_info03a to void (i8*, i8*, i64, ...)*, !dbg !48 + call void (i8*, i8*, i64, ...) %5 (i8* %3, i8* %4, i64 22), !dbg !48 + %6 = bitcast i32* @.C302_main_mfun to i8*, !dbg !48 + %7 = bitcast i32* @.C283_main_mfun to i8*, !dbg !48 + %8 = bitcast i32 (...)* @f90io_print_init to i32 (i8*, i8*, i8*, i8*, ...)*, !dbg !48 + %9 = call i32 (i8*, i8*, i8*, i8*, ...) %8 (i8* %6, i8* null, i8* %7, i8* %7), !dbg !48 + call void @llvm.dbg.declare (metadata i32* %z__io_314, metadata !49, metadata !23), !dbg !42 + store i32 %9, i32* %z__io_314, align 4, !tbaa !59, !dbg !48 + %10 = load i32, i32* %i1_311, align 4, !tbaa !55, !dbg !48 + call void @llvm.dbg.value (metadata i32 %10, i64 0, metadata !46, metadata !23), !dbg !42 + %11 = bitcast i32 (...)* @f90io_sc_i_ldw to i32 (i32, i32, ...)*, !dbg !48 + %12 = call i32 (i32, i32, ...) %11 (i32 %10, i32 25), !dbg !48 + store i32 %12, i32* %z__io_314, align 4, !tbaa !59, !dbg !48 + %13 = call i32 (...) @f90io_ldw_end (), !dbg !48 + store i32 %13, i32* %z__io_314, align 4, !tbaa !59, !dbg !48 + %14 = load i32, i32* %mfun_310, align 4, !tbaa !57, !dbg !50 + ret i32 %14, !dbg !50 +} +%struct.struct_ul_main_fun_301 = type { i8*} +define internal float @main_fun(i64* noalias %a, i64* noalias %.S0000) !dbg !67 { +L.entry: + %fun_303 = alloca float, align 4 + + call void @llvm.dbg.declare (metadata i64* %a, metadata !71, metadata !23), !dbg !70 + call void @llvm.dbg.declare (metadata i64* %.S0000, metadata !72, metadata !23), !dbg !70 + br label %L.LB3_310 +L.LB3_310: + %0 = bitcast i64* %a to i32*, !dbg !73 + %1 = load i32, i32* %0, align 4, !tbaa !79, !dbg !73 + %2 = sitofp i32 %1 to float, !dbg !73 + store float %2, float* %fun_303, align 4, !tbaa !81, !dbg !73 + ret float %2, !dbg !74 +} + +; Named metadata +!llvm.module.flags = !{ !1, !2 } +!llvm.dbg.cu = !{ !10 } + +; Metadata +!1 = !{ i32 2, !"Dwarf Version", i32 4 } +!2 = !{ i32 2, !"Debug Info Version", i32 3 } +!3 = !DIFile(filename: "duplicate-dbgvalue.f90", directory: "/dir") +; !4 = !DIFile(tag: DW_TAG_file_type, pair: !3) +!4 = !{ i32 41, !3 } +!5 = !{ } +!6 = !{ } +!7 = !{ !14, !39, !67 } +!8 = !{ !24, !61, !83 } +!9 = !{ } +!10 = distinct !DICompileUnit(file: !3, language: DW_LANG_Fortran90, producer: " F90 Flang - 1.5", enums: !5, retainedTypes: !6, globals: !8, emissionKind: FullDebug, imports: !9) +!11 = !{ null } +!12 = !DISubroutineType(types: !11, cc: 2) +!13 = !{ } +!14 = distinct !DISubprogram(file: !3, scope: !10, name: "main", line: 1, type: !12, spFlags: 264, unit: !10, scopeLine: 1) +!15 = !DILocation(scope: !14) +!16 = !DILexicalBlock(file: !3, scope: !14, line: 1, column: 1) +!17 = !DILocation(scope: !16) +!18 = distinct !{ } +!19 = !DILocation(line: 1, column: 1, scope: !16) +!20 = !DILocation(line: 3, column: 1, scope: !16) +!21 = !DIBasicType(tag: DW_TAG_base_type, name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!22 = distinct !DIGlobalVariable(scope: !14, name: "res", file: !3, type: !21, isLocal: true, isDefinition: true) +!23 = !DIExpression() +!24 = !DIGlobalVariableExpression(var: !22, expr: !23) +!25 = !DILocation(line: 4, column: 1, scope: !16) +!26 = !DILocalVariable(scope: !16, file: !3, type: !21, flags: 64) +!27 = !DILocation(line: 5, column: 1, scope: !16) +!28 = !{ !"Flang FAA 1" } +!29 = !{ !"unref ptr", !28, i64 0 } +!30 = !{ !"unlimited ptr", !28, i64 0 } +!31 = !{ !"t1.2", !30, i64 0 } +!32 = !{ !31, !31, i64 0 } +!33 = !{ !"t1.4", !30, i64 0 } +!34 = !{ !33, !33, i64 0 } +!35 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !21) +!36 = !{ !35 } +!37 = !DISubroutineType(types: !36) +!38 = !{ } +!39 = distinct !DISubprogram(file: !3, scope: !14, name: "mfun", line: 6, type: !37, spFlags: 12, unit: !10, scopeLine: 6) +!40 = !DILocation(scope: !39) +!41 = !DILexicalBlock(file: !3, scope: !39, line: 6, column: 1) +!42 = !DILocation(scope: !41) +!43 = !DIBasicType(tag: DW_TAG_base_type, name: "uinteger*8", size: 64, align: 64, encoding: DW_ATE_unsigned) +!44 = !DILocalVariable(scope: !39, arg: 1, file: !3, type: !43, flags: 64) +!45 = !DILocation(line: 8, column: 1, scope: !41) +!46 = !DILocalVariable(scope: !41, name: "i1", file: !3, type: !21) +!47 = !DILocation(line: 9, column: 1, scope: !41) +!48 = !DILocation(line: 10, column: 1, scope: !41) +!49 = !DILocalVariable(scope: !41, file: !3, type: !21, flags: 64) +!50 = !DILocation(line: 11, column: 1, scope: !41) +!51 = !{ !"Flang FAA 2" } +!52 = !{ !"unref ptr", !51, i64 0 } +!53 = !{ !"unlimited ptr", !51, i64 0 } +!54 = !{ !"t2.2", !53, i64 0 } +!55 = !{ !54, !54, i64 0 } +!56 = !{ !"t2.4", !53, i64 0 } +!57 = !{ !56, !56, i64 0 } +!58 = !{ !"t2.6", !53, i64 0 } +!59 = !{ !58, !58, i64 0 } +!60 = distinct !DIGlobalVariable(scope: !10, name: "res", file: !3, type: !21, isLocal: true, isDefinition: true) +!61 = !DIGlobalVariableExpression(var: !60, expr: !23) +!62 = !DIBasicType(tag: DW_TAG_base_type, name: "real", size: 32, align: 32, encoding: DW_ATE_float) +!63 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !62) +!64 = !{ !63, !21 } +!65 = !DISubroutineType(types: !64) +!66 = !{ } +!67 = distinct !DISubprogram(file: !3, scope: !14, name: "fun", line: 12, type: !65, spFlags: 12, unit: !10, scopeLine: 12) +!68 = !DILocation(scope: !67) +!69 = !DILexicalBlock(file: !3, scope: !67, line: 12, column: 1) +!70 = !DILocation(scope: !69) +!71 = !DILocalVariable(scope: !67, name: "a", arg: 1, file: !3, type: !21) +!72 = !DILocalVariable(scope: !67, arg: 2, file: !3, type: !43, flags: 64) +!73 = !DILocation(line: 14, column: 1, scope: !69) +!74 = !DILocation(line: 15, column: 1, scope: !69) +!75 = !{ !"Flang FAA 3" } +!76 = !{ !"unref ptr", !75, i64 0 } +!77 = !{ !"unlimited ptr", !75, i64 0 } +!78 = !{ !"t3.2", !77, i64 0 } +!79 = !{ !78, !78, i64 0 } +!80 = !{ !"t3.4", !77, i64 0 } +!81 = !{ !80, !80, i64 0 } +!82 = distinct !DIGlobalVariable(scope: !10, name: "res", file: !3, type: !21, isLocal: true, isDefinition: true) +!83 = !DIGlobalVariableExpression(var: !82, expr: !23) + +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) +declare signext i32 @f90io_ldw_end(...) +declare signext i32 @f90io_sc_i_ldw(...) +declare void @llvm.dbg.declare(metadata, metadata, metadata) +declare signext i32 @f90io_print_init(...) +declare void @f90io_src_info03a(...) +declare void @fort_init(...)