Index: include/llvm/CodeGen/SelectionDAG.h =================================================================== --- include/llvm/CodeGen/SelectionDAG.h +++ include/llvm/CodeGen/SelectionDAG.h @@ -1258,6 +1258,7 @@ SDNode *FindModifiedNodeSlot(SDNode *N, ArrayRef Ops, void *&InsertPos); SDNode *UpdadeSDLocOnMergedSDNode(SDNode *N, SDLoc loc); + static SDNode *FilterDebugLoc(SDNode *N, DebugLoc loc); void DeleteNodeNotInCSEMaps(SDNode *N); void DeallocateNode(SDNode *N); Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1320,7 +1320,7 @@ ID.AddInteger(GV->getType()->getAddressSpace()); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, DL.getDebugLoc()), 0); SDNode *N = new (NodeAllocator) GlobalAddressSDNode(Opc, DL.getIROrder(), DL.getDebugLoc(), GV, VT, @@ -1664,7 +1664,7 @@ void* IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); // Allocate the mask array for the node out of the BumpPtrAllocator, since // SDNode doesn't have access to it. This memory will be "leaked" when @@ -1706,7 +1706,7 @@ AddNodeIDNode(ID, ISD::CONVERT_RNDSAT, getVTList(VT), Ops); void* IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); CvtRndSatSDNode *N = new (NodeAllocator) CvtRndSatSDNode(VT, dl.getIROrder(), dl.getDebugLoc(), @@ -1835,7 +1835,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); SDNode *N = new (NodeAllocator) AddrSpaceCastSDNode(dl.getIROrder(), dl.getDebugLoc(), @@ -2803,7 +2803,7 @@ AddNodeIDNode(ID, Opcode, getVTList(VT), None); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, DL.getDebugLoc()), 0); SDNode *N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), getVTList(VT)); @@ -3154,7 +3154,7 @@ AddNodeIDNode(ID, Opcode, VTs, Ops); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, DL.getDebugLoc()), 0); N = new (NodeAllocator) UnarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Operand); @@ -3779,7 +3779,7 @@ AddNodeIDFlags(ID, Opcode, Flags); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, DL.getDebugLoc()), 0); N = GetBinarySDNode(Opcode, DL, VTs, N1, N2, Flags); @@ -3882,7 +3882,7 @@ AddNodeIDNode(ID, Opcode, VTs, Ops); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, DL.getDebugLoc()), 0); N = new (NodeAllocator) TernarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2, N3); @@ -4655,7 +4655,7 @@ void* IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); } // Allocate the operands array for the node out of the BumpPtrAllocator, since @@ -4860,7 +4860,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); } N = new (NodeAllocator) MemIntrinsicSDNode(Opcode, dl.getIROrder(), @@ -4986,7 +4986,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); } SDNode *N = new (NodeAllocator) LoadSDNode(Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, AM, ExtType, @@ -5094,7 +5094,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); } SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, @@ -5163,7 +5163,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); } SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, @@ -5188,7 +5188,7 @@ ID.AddInteger(ST->getPointerInfo().getAddrSpace()); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, AM, @@ -5218,7 +5218,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); } SDNode *N = new (NodeAllocator) MaskedLoadSDNode(dl.getIROrder(), dl.getDebugLoc(), Ops, 4, VTs, @@ -5245,7 +5245,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); } SDNode *N = new (NodeAllocator) MaskedStoreSDNode(dl.getIROrder(), dl.getDebugLoc(), Ops, 4, @@ -5271,7 +5271,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); } MaskedGatherSDNode *N = new (NodeAllocator) MaskedGatherSDNode(dl.getIROrder(), dl.getDebugLoc(), @@ -5294,7 +5294,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, dl.getDebugLoc()), 0); } SDNode *N = new (NodeAllocator) MaskedScatterSDNode(dl.getIROrder(), dl.getDebugLoc(), @@ -5369,7 +5369,7 @@ void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, DL.getDebugLoc()), 0); N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Ops); @@ -5424,7 +5424,7 @@ AddNodeIDNode(ID, Opcode, VTList, Ops); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) - return SDValue(E, 0); + return SDValue(FilterDebugLoc(E, DL.getDebugLoc()), 0); if (NumOps == 1) { N = new (NodeAllocator) UnarySDNode(Opcode, DL.getIROrder(), @@ -5808,6 +5808,13 @@ return N; } +SDNode *SelectionDAG::FilterDebugLoc(SDNode *N, DebugLoc Loc) +{ + if (N->getDebugLoc() != Loc) + N->setDebugLoc(DebugLoc()); + return N; +} + /// UpdadeSDLocOnMergedSDNode - If the opt level is -O0 then it throws away /// the line number information on the merged node since it is not possible to /// preserve the information that operation is associated with multiple lines. Index: test/DebugInfo/isel-cse-line.ll =================================================================== --- test/DebugInfo/isel-cse-line.ll +++ test/DebugInfo/isel-cse-line.ll @@ -0,0 +1,102 @@ +; RUN: llc -filetype=asm -fast-isel=false -O0 < %s | FileCheck %s +; +; Generated by: +; clang -emit-llvm -S -g test.cpp + +; typedef double fp_t; +; typedef unsigned long int_t; +; +; int_t glb_start = 17; +; int_t glb_end = 42; +; +; int main() +; { +; int_t start = glb_start; +; int_t end = glb_end; +; +; fp_t dbl_start = (fp_t) start; +; fp_t dbl_end = (fp_t) end; +; +; return 0; +; } + +; SelectionDAG performs CSE on constant pool loads. Make sure line numbers +; from such nodes are not propagated. Doing so results in oscillating line numbers. + +; CHECK: .loc 1 12 +; CHECK: .loc 1 13 +; CHECK-NOT: .loc 1 12 + +; ModuleID = 't.cpp' +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@glb_start = global i64 17, align 8 +@glb_end = global i64 42, align 8 + +; Function Attrs: nounwind uwtable +define i32 @main() { + %1 = alloca i32, align 4 + %start = alloca i64, align 8 + %end = alloca i64, align 8 + %dbl_start = alloca double, align 8 + %dbl_end = alloca double, align 8 + store i32 0, i32* %1 + call void @llvm.dbg.declare(metadata i64* %start, metadata !19, metadata !20), !dbg !21 + %2 = load i64, i64* @glb_start, align 8, !dbg !22 + store i64 %2, i64* %start, align 8, !dbg !21 + call void @llvm.dbg.declare(metadata i64* %end, metadata !23, metadata !20), !dbg !24 + %3 = load i64, i64* @glb_end, align 8, !dbg !25 + store i64 %3, i64* %end, align 8, !dbg !24 + call void @llvm.dbg.declare(metadata double* %dbl_start, metadata !26, metadata !20), !dbg !27 + %4 = load i64, i64* %start, align 8, !dbg !28 + %5 = uitofp i64 %4 to double, !dbg !28 + store double %5, double* %dbl_start, align 8, !dbg !27 + call void @llvm.dbg.declare(metadata double* %dbl_end, metadata !29, metadata !20), !dbg !30 + %6 = load i64, i64* %end, align 8, !dbg !31 + %7 = uitofp i64 %6 to double, !dbg !31 + store double %7, double* %dbl_end, align 8, !dbg !30 + ret i32 0, !dbg !32 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) + + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!16, !17} +!llvm.ident = !{!18} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 244974)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !6, globals: !11) +!1 = !DIFile(filename: "t.cpp", directory: "/home/user") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_typedef, name: "fp_t", file: !1, line: 1, baseType: !5) +!5 = !DIBasicType(name: "double", size: 64, align: 64, encoding: DW_ATE_float) +!6 = !{!7} +!7 = !DISubprogram(name: "main", scope: !1, file: !1, line: 7, type: !8, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, function: i32 ()* @main, variables: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!11 = !{!12, !15} +!12 = !DIGlobalVariable(name: "glb_start", scope: !0, file: !1, line: 4, type: !13, isLocal: false, isDefinition: true, variable: i64* @glb_start) +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "int_t", file: !1, line: 2, baseType: !14) +!14 = !DIBasicType(name: "long unsigned int", size: 64, align: 64, encoding: DW_ATE_unsigned) +!15 = !DIGlobalVariable(name: "glb_end", scope: !0, file: !1, line: 5, type: !13, isLocal: false, isDefinition: true, variable: i64* @glb_end) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{!"clang version 3.8.0 (trunk 244974)"} +!19 = !DILocalVariable(name: "start", scope: !7, file: !1, line: 9, type: !13) +!20 = !DIExpression() +!21 = !DILocation(line: 9, column: 9, scope: !7) +!22 = !DILocation(line: 9, column: 17, scope: !7) +!23 = !DILocalVariable(name: "end", scope: !7, file: !1, line: 10, type: !13) +!24 = !DILocation(line: 10, column: 9, scope: !7) +!25 = !DILocation(line: 10, column: 17, scope: !7) +!26 = !DILocalVariable(name: "dbl_start", scope: !7, file: !1, line: 12, type: !4) +!27 = !DILocation(line: 12, column: 8, scope: !7) +!28 = !DILocation(line: 12, column: 27, scope: !7) +!29 = !DILocalVariable(name: "dbl_end", scope: !7, file: !1, line: 13, type: !4) +!30 = !DILocation(line: 13, column: 8, scope: !7) +!31 = !DILocation(line: 13, column: 27, scope: !7) +!32 = !DILocation(line: 15, column: 3, scope: !7)