Index: include/llvm/CodeGen/SelectionDAG.h =================================================================== --- include/llvm/CodeGen/SelectionDAG.h +++ include/llvm/CodeGen/SelectionDAG.h @@ -1001,7 +1001,7 @@ /// Get the specified node if it's already available, or else return NULL. SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef Ops, - const SDNodeFlags *Flags = nullptr); + DebugLoc DL, const SDNodeFlags *Flags = nullptr); /// Creates a SDDbgValue node. SDDbgValue *getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, unsigned R, @@ -1278,11 +1278,11 @@ /// for those. SDNode *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos); - /// 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, - void *&InsertPos); + /// Look up the node specified by ID in CSEMap. If it exists, return it and + /// null out its debug location if it does not match DL. If it does not exist + /// return the insertion token that will make insertion faster. + SDNode *UpdateDLOrFindInsertPos(const FoldingSetNodeID &ID, DebugLoc DL, + void *&InsertPos); /// List of non-single value types. FoldingSet VTListMap; Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1476,9 +1476,10 @@ SDNode *CSENode; if (const auto *BinNode = dyn_cast(N)) { CSENode = DAG.getNodeIfExists(N->getOpcode(), N->getVTList(), Ops, - &BinNode->Flags); + N->getDebugLoc(), &BinNode->Flags); } else { - CSENode = DAG.getNodeIfExists(N->getOpcode(), N->getVTList(), Ops); + CSENode = DAG.getNodeIfExists(N->getOpcode(), N->getVTList(), Ops, + N->getDebugLoc()); } if (CSENode) return SDValue(CSENode, 0); Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1,4 +1,3 @@ -//===-- SelectionDAG.cpp - Implement the SelectionDAG data structures -----===// // // The LLVM Compiler Infrastructure // @@ -873,7 +872,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops); AddNodeIDCustom(ID, N); - SDNode *Node = FindNodeOrInsertPos(ID, N->getDebugLoc(), InsertPos); + SDNode *Node = UpdateDLOrFindInsertPos(ID, N->getDebugLoc(), InsertPos); return Node; } @@ -891,7 +890,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops); AddNodeIDCustom(ID, N); - SDNode *Node = FindNodeOrInsertPos(ID, N->getDebugLoc(), InsertPos); + SDNode *Node = UpdateDLOrFindInsertPos(ID, N->getDebugLoc(), InsertPos); return Node; } @@ -908,7 +907,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops); AddNodeIDCustom(ID, N); - SDNode *Node = FindNodeOrInsertPos(ID, N->getDebugLoc(), InsertPos); + SDNode *Node = UpdateDLOrFindInsertPos(ID, N->getDebugLoc(), InsertPos); return Node; } @@ -989,21 +988,16 @@ return N; } -SDNode *SelectionDAG::FindNodeOrInsertPos(const FoldingSetNodeID &ID, - DebugLoc DL, void *&InsertPos) { +SDNode *SelectionDAG::UpdateDLOrFindInsertPos(const FoldingSetNodeID &ID, + DebugLoc 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) - N->setDebugLoc(DebugLoc()); - break; - } + // Erase the debug location from the node if the node is used in more + // than one place. Otherwise the location may be propagated to + // all uses or, in some cases, to the wrong use. + if (N->getDebugLoc() != DL) + N->setDebugLoc(DebugLoc()); } return N; } @@ -1212,7 +1206,7 @@ ID.AddBoolean(isO); void *IP = nullptr; SDNode *N = nullptr; - if ((N = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP))) + if ((N = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP))) if (!VT.isVector()) return SDValue(N, 0); @@ -1256,7 +1250,7 @@ ID.AddPointer(&V); void *IP = nullptr; SDNode *N = nullptr; - if ((N = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP))) + if ((N = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP))) if (!VT.isVector()) return SDValue(N, 0); @@ -1319,7 +1313,7 @@ ID.AddInteger(TargetFlags); ID.AddInteger(GV->getType()->getAddressSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP)) return SDValue(E, 0); SDNode *N = new (NodeAllocator) GlobalAddressSDNode(Opc, DL.getIROrder(), @@ -1663,7 +1657,7 @@ ID.AddInteger(MaskVec[i]); void* IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) return SDValue(E, 0); // Allocate the mask array for the node out of the BumpPtrAllocator, since @@ -1705,7 +1699,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 = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) return SDValue(E, 0); CvtRndSatSDNode *N = new (NodeAllocator) CvtRndSatSDNode(VT, dl.getIROrder(), @@ -1834,7 +1828,7 @@ ID.AddInteger(DestAS); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) return SDValue(E, 0); SDNode *N = new (NodeAllocator) AddrSpaceCastSDNode(dl.getIROrder(), @@ -2802,7 +2796,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, getVTList(VT), None); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP)) return SDValue(E, 0); SDNode *N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), @@ -3153,7 +3147,7 @@ SDValue Ops[1] = { Operand }; AddNodeIDNode(ID, Opcode, VTs, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP)) return SDValue(E, 0); N = new (NodeAllocator) UnarySDNode(Opcode, DL.getIROrder(), @@ -3786,7 +3780,7 @@ AddNodeIDNode(ID, Opcode, VTs, Ops); AddNodeIDFlags(ID, Opcode, Flags); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP)) return SDValue(E, 0); N = GetBinarySDNode(Opcode, DL, VTs, N1, N2, Flags); @@ -3889,7 +3883,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTs, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP)) return SDValue(E, 0); N = new (NodeAllocator) TernarySDNode(Opcode, DL.getIROrder(), @@ -4661,7 +4655,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 = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -4866,7 +4860,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 = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -4992,7 +4986,7 @@ MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5100,7 +5094,7 @@ MMO->isNonTemporal(), MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5169,7 +5163,7 @@ MMO->isNonTemporal(), MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5195,7 +5189,7 @@ ID.AddInteger(ST->getRawSubclassData()); ID.AddInteger(ST->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) return SDValue(E, 0); SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl.getIROrder(), @@ -5224,7 +5218,7 @@ MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5251,7 +5245,7 @@ MMO->isNonTemporal(), MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5277,7 +5271,7 @@ MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5300,7 +5294,7 @@ MMO->isInvariant())); ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl.getDebugLoc(), IP)) { + if (SDNode *E = UpdateDLOrFindInsertPos(ID, dl.getDebugLoc(), IP)) { cast(E)->refineAlignment(MMO); return SDValue(E, 0); } @@ -5376,7 +5370,7 @@ AddNodeIDNode(ID, Opcode, VTs, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP)) return SDValue(E, 0); N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), @@ -5431,7 +5425,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTList, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP)) return SDValue(E, 0); if (NumOps == 1) { @@ -5857,7 +5851,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 = UpdateDLOrFindInsertPos(ID, N->getDebugLoc(), IP)) return UpdadeSDLocOnMergedSDNode(ON, SDLoc(N)); } @@ -6063,7 +6057,7 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, ~Opcode, VTs, OpsArray); IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL.getDebugLoc(), IP)) { + if (SDNode *E = UpdateDLOrFindInsertPos(ID, DL.getDebugLoc(), IP)) { return cast(UpdadeSDLocOnMergedSDNode(E, DL)); } } @@ -6116,6 +6110,7 @@ /// else return NULL. SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList, ArrayRef Ops, + DebugLoc DL, const SDNodeFlags *Flags) { if (VTList.VTs[VTList.NumVTs - 1] != MVT::Glue) { FoldingSetNodeID ID; @@ -6122,7 +6117,7 @@ AddNodeIDNode(ID, Opcode, VTList, Ops); AddNodeIDFlags(ID, Opcode, Flags); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DebugLoc(), IP)) + if (SDNode *E = UpdateDLOrFindInsertPos(ID, DL, IP)) return E; } return nullptr; 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)