Index: include/llvm/CodeGen/SelectionDAG.h =================================================================== --- include/llvm/CodeGen/SelectionDAG.h +++ include/llvm/CodeGen/SelectionDAG.h @@ -1008,7 +1008,8 @@ SDValue Operand, SDValue Subreg); /// Get the specified node if it's already available, or else return NULL. - SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef Ops, + SDNode *getNodeIfExists(unsigned Opcode, SDLoc DL, SDVTList VTs, + ArrayRef Ops, const SDNodeFlags *Flags = nullptr); /// Creates a SDDbgValue node. @@ -1297,7 +1298,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/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1508,8 +1508,8 @@ // Constant operands are canonicalized to RHS. if (isa(N0) || !isa(N1)) { SDValue Ops[] = {N1, N0}; - SDNode *CSENode = DAG.getNodeIfExists(N->getOpcode(), N->getVTList(), Ops, - N->getFlags()); + SDNode *CSENode = DAG.getNodeIfExists(N->getOpcode(), SDLoc(N), + N->getVTList(), Ops, N->getFlags()); if (CSENode) return SDValue(CSENode, 0); } Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -850,7 +850,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(), InsertPos); return Node; } @@ -868,7 +868,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); return Node; } @@ -885,7 +885,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); return Node; } @@ -970,19 +970,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; @@ -1192,7 +1198,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); @@ -1236,7 +1242,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); @@ -1299,7 +1305,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); SDNode *N = new (NodeAllocator) GlobalAddressSDNode(Opc, DL.getIROrder(), @@ -1643,7 +1649,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 @@ -1685,7 +1691,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); CvtRndSatSDNode *N = new (NodeAllocator) CvtRndSatSDNode(VT, dl.getIROrder(), @@ -1814,7 +1820,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); SDNode *N = new (NodeAllocator) AddrSpaceCastSDNode(dl.getIROrder(), @@ -2849,7 +2855,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); SDNode *N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), @@ -3167,7 +3173,7 @@ SDValue Ops[1] = { Operand }; 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 = new (NodeAllocator) UnarySDNode(Opcode, DL.getIROrder(), @@ -3873,7 +3879,7 @@ AddNodeIDNode(ID, Opcode, VTs, Ops); AddNodeIDFlags(ID, Opcode, Flags); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return SDValue(E, 0); N = GetBinarySDNode(Opcode, DL, VTs, N1, N2, Flags); @@ -3979,7 +3985,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 = new (NodeAllocator) TernarySDNode(Opcode, DL.getIROrder(), @@ -4751,7 +4757,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); } @@ -4956,7 +4962,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); } @@ -5082,7 +5088,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); } @@ -5190,7 +5196,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); } @@ -5259,7 +5265,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); } @@ -5285,7 +5291,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); SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl.getIROrder(), @@ -5314,7 +5320,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); } @@ -5341,7 +5347,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); } @@ -5367,7 +5373,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->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); } @@ -5466,7 +5472,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 = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), @@ -5521,7 +5527,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); if (NumOps == 1) { @@ -5947,7 +5953,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)); } @@ -6153,7 +6159,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, ~Opcode, VTs, OpsArray); IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) { + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) { return cast(UpdadeSDLocOnMergedSDNode(E, DL)); } } @@ -6204,15 +6210,15 @@ /// getNodeIfExists - Get the specified node if it's already available, or /// else return NULL. -SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList, - ArrayRef Ops, +SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDLoc DL, + SDVTList VTList, ArrayRef Ops, const SDNodeFlags *Flags) { if (VTList.VTs[VTList.NumVTs - 1] != MVT::Glue) { FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTList, Ops); AddNodeIDFlags(ID, Opcode, Flags); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DebugLoc(), IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return E; } return nullptr; 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)