Index: include/llvm/CodeGen/SelectionDAG.h =================================================================== --- include/llvm/CodeGen/SelectionDAG.h +++ include/llvm/CodeGen/SelectionDAG.h @@ -1356,7 +1356,7 @@ /// Look up the node specified by ID in CSEMap. If it exists, return it. If /// not, return the insertion token that will make insertion faster. Performs /// additional processing for constant nodes. - SDNode *FindNodeOrInsertPos(const FoldingSetNodeID &ID, DebugLoc DL, + SDNode *FindNodeOrInsertPos(const FoldingSetNodeID &ID, SDLoc DL, void *&InsertPos); /// List of non-single value types. Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -832,7 +832,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops); AddNodeIDCustom(ID, N); - SDNode *Node = FindNodeOrInsertPos(ID, N->getDebugLoc(), InsertPos); + SDNode *Node = FindNodeOrInsertPos(ID, SDLoc(N), InsertPos); if (Node) if (const SDNodeFlags *Flags = N->getFlags()) Node->intersectFlagsWith(Flags); @@ -853,7 +853,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops); AddNodeIDCustom(ID, N); - SDNode *Node = FindNodeOrInsertPos(ID, N->getDebugLoc(), InsertPos); + SDNode *Node = FindNodeOrInsertPos(ID, SDLoc(N), InsertPos); if (Node) if (const SDNodeFlags *Flags = N->getFlags()) Node->intersectFlagsWith(Flags); @@ -873,7 +873,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops); AddNodeIDCustom(ID, N); - SDNode *Node = FindNodeOrInsertPos(ID, N->getDebugLoc(), InsertPos); + SDNode *Node = FindNodeOrInsertPos(ID, SDLoc(N), InsertPos); if (Node) if (const SDNodeFlags *Flags = N->getFlags()) Node->intersectFlagsWith(Flags); @@ -964,19 +964,25 @@ } SDNode *SelectionDAG::FindNodeOrInsertPos(const FoldingSetNodeID &ID, - DebugLoc DL, void *&InsertPos) { + SDLoc DL, void *&InsertPos) { SDNode *N = CSEMap.FindNodeOrInsertPos(ID, InsertPos); if (N) { switch (N->getOpcode()) { - default: break; // Process only regular (non-target) constant nodes. case ISD::Constant: case ISD::ConstantFP: // Erase debug location from the node if the node is used at several // different places to do not propagate one location to all uses as it // leads to incorrect debug info. - if (N->getDebugLoc() != DL) + if (N->getDebugLoc() != DL.getDebugLoc()) N->setDebugLoc(DebugLoc()); break; + default: + // When the node's point of use is located earlier in the instruction + // sequence than its prior point of use, update its debug info to the + // earlier location. + if (DL.getIROrder() && DL.getIROrder() < N->getIROrder()) + N->setDebugLoc(DL.getDebugLoc()); + break; } } return N; @@ -1185,7 +1191,7 @@ ID.AddBoolean(isO); void *IP = nullptr; SDNode *N = nullptr; - if ((N = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP))) + if ((N = FindNodeOrInsertPos(ID, DL, IP))) if (!VT.isVector()) return SDValue(N, 0); @@ -1228,7 +1234,7 @@ ID.AddPointer(&V); void *IP = nullptr; SDNode *N = nullptr; - if ((N = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP))) + if ((N = FindNodeOrInsertPos(ID, DL, IP))) if (!VT.isVector()) return SDValue(N, 0); @@ -1290,7 +1296,7 @@ ID.AddInteger(TargetFlags); ID.AddInteger(GV->getType()->getAddressSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return SDValue(E, 0); auto *N = newSDNode( @@ -1631,7 +1637,7 @@ ID.AddInteger(MaskVec[i]); void* IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) return SDValue(E, 0); // Allocate the mask array for the node out of the BumpPtrAllocator, since @@ -1673,7 +1679,7 @@ SDValue Ops[] = { Val, DTy, STy, Rnd, Sat }; AddNodeIDNode(ID, ISD::CONVERT_RNDSAT, getVTList(VT), Ops); void* IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) return SDValue(E, 0); auto *N = @@ -1803,7 +1809,7 @@ ID.AddInteger(DestAS); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) return SDValue(E, 0); auto *N = newSDNode(dl.getIROrder(), dl.getDebugLoc(), @@ -2878,7 +2884,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, getVTList(VT), None); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return SDValue(E, 0); auto *N = newSDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), @@ -3198,7 +3204,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTs, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return SDValue(E, 0); N = newSDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs); @@ -3911,7 +3917,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTs, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) { if (Flags) E->intersectFlagsWith(Flags); return SDValue(E, 0); @@ -4013,7 +4019,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTs, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return SDValue(E, 0); N = newSDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs); @@ -4808,7 +4814,7 @@ AddNodeIDNode(ID, Opcode, VTList, Ops); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void* IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5004,7 +5010,7 @@ AddNodeIDNode(ID, Opcode, VTList, Ops); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5130,7 +5136,7 @@ MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5237,7 +5243,7 @@ MMO->isNonTemporal(), MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5307,7 +5313,7 @@ MMO->isNonTemporal(), MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5333,7 +5339,7 @@ ID.AddInteger(ST->getRawSubclassData()); ID.AddInteger(ST->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) return SDValue(E, 0); auto *N = newSDNode(dl.getIROrder(), dl.getDebugLoc(), VTs, AM, @@ -5362,7 +5368,7 @@ MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5390,7 +5396,7 @@ MMO->isNonTemporal(), MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5418,7 +5424,7 @@ MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5454,7 +5460,7 @@ MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5544,7 +5550,7 @@ AddNodeIDNode(ID, Opcode, VTs, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return SDValue(E, 0); N = newSDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs); @@ -5599,7 +5605,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTList, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return SDValue(E, 0); N = newSDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList); @@ -5998,7 +6004,7 @@ if (VTs.VTs[VTs.NumVTs-1] != MVT::Glue) { FoldingSetNodeID ID; AddNodeIDNode(ID, Opc, VTs, Ops); - if (SDNode *ON = FindNodeOrInsertPos(ID, N->getDebugLoc(), IP)) + if (SDNode *ON = FindNodeOrInsertPos(ID, SDLoc(N), IP)) return UpdadeSDLocOnMergedSDNode(ON, SDLoc(N)); } @@ -6179,7 +6185,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, ~Opcode, VTs, Ops); IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) { return cast(UpdadeSDLocOnMergedSDNode(E, DL)); } } @@ -6226,7 +6232,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTList, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, SDLoc(), IP)) { if (Flags) E->intersectFlagsWith(Flags); return E; Index: test/DebugInfo/Generic/isel-cse-line.ll =================================================================== --- test/DebugInfo/Generic/isel-cse-line.ll +++ test/DebugInfo/Generic/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: norecurse nounwind uwtable +define i32 @main() !dbg !7 { +entry: + %retval = 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* %retval, align 4 + call void @llvm.dbg.declare(metadata i64* %start, metadata !19, metadata !20), !dbg !21 + %0 = load i64, i64* @glb_start, align 8, !dbg !22 + store i64 %0, i64* %start, align 8, !dbg !21 + call void @llvm.dbg.declare(metadata i64* %end, metadata !23, metadata !20), !dbg !24 + %1 = load i64, i64* @glb_end, align 8, !dbg !25 + store i64 %1, i64* %end, align 8, !dbg !24 + call void @llvm.dbg.declare(metadata double* %dbl_start, metadata !26, metadata !20), !dbg !27 + %2 = load i64, i64* %start, align 8, !dbg !28 + %conv = uitofp i64 %2 to double, !dbg !28 + store double %conv, double* %dbl_start, align 8, !dbg !27 + call void @llvm.dbg.declare(metadata double* %dbl_end, metadata !29, metadata !20), !dbg !30 + %3 = load i64, i64* %end, align 8, !dbg !31 + %conv1 = uitofp i64 %3 to double, !dbg !31 + store double %conv1, 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 253648)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !6, globals: !11) +!1 = !DIFile(filename: "t.cpp", directory: "/home/wpieb/orbis/Bugzillas/BZ83616") +!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 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 7, type: !8, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, 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 253648)"} +!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)