diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -2583,8 +2583,8 @@ return Elements[I]; } - /// Determine whether this represents a standalone constant value. - bool isConstant() const; + /// Determine whether this represents a standalone unsigned constant value. + bool isUnsignedConstant() const; /// Determine whether this represents a standalone signed constant value. bool isSignedConstant() const; diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -3049,7 +3049,7 @@ const DIExpression *DIE = GVE->getExpression(); // Emit constant global variables in a global symbol section. - if (GlobalMap.count(GVE) == 0 && DIE->isConstant()) { + if (GlobalMap.count(GVE) == 0 && DIE->isUnsignedConstant()) { CVGlobalVariable CVGV = {DIGV, DIE}; GlobalVariables.emplace_back(std::move(CVGV)); } @@ -3232,7 +3232,7 @@ endSymbolRecord(DataEnd); } else { const DIExpression *DIE = CVGV.GVInfo.get(); - assert(DIE->isConstant() && + assert(DIE->isUnsignedConstant() && "Global constant variables must contain a constant expression."); // Use unsigned for floats. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -209,11 +209,14 @@ const DIExpression *Expr = GE.Expr; // For compatibility with DWARF 3 and earlier, - // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) becomes + // DW_AT_location(DW_OP_constu, X, DW_OP_stack_value) or + // DW_AT_location(DW_OP_consts, X, DW_OP_stack_value) becomes // DW_AT_const_value(X). - if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) { + if (GlobalExprs.size() == 1 && Expr && + (Expr->isUnsignedConstant() || Expr->isSignedConstant())) { addToAccelTable = true; - addConstantValue(*VariableDIE, /*Unsigned=*/true, Expr->getElement(1)); + addConstantValue(*VariableDIE, Expr->isUnsignedConstant(), + Expr->getElement(1)); break; } @@ -223,7 +226,7 @@ continue; // Nothing to describe without address or constant. - if (!Global && (!Expr || !Expr->isConstant())) + if (!Global && (!Expr || !Expr->isUnsignedConstant())) continue; if (Global && Global->isThreadLocal() && diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1229,7 +1229,7 @@ // expression. auto &GVMapEntry = GVMap[GVE->getVariable()]; auto *Expr = GVE->getExpression(); - if (!GVMapEntry.size() || (Expr && Expr->isConstant())) + if (!GVMapEntry.size() || (Expr && Expr->isUnsignedConstant())) GVMapEntry.push_back({nullptr, Expr}); } DenseSet Processed; diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -1450,7 +1450,7 @@ return DIExpression::get(Expr->getContext(), Ops); } -bool DIExpression::isConstant() const { +bool DIExpression::isUnsignedConstant() const { // Recognize DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment Len Ofs)?. if (getNumElements() != 3 && getNumElements() != 6) return false; @@ -1463,10 +1463,12 @@ } bool DIExpression::isSignedConstant() const { - // Recognize DW_OP_consts C - if (getNumElements() != 2) + // Recognize DW_OP_consts C and DW_OP_consts C DW_OP_stack_value. + if (getNumElements() != 2 && getNumElements() != 3) return false; - if (getElement(0) != dwarf::DW_OP_consts) + if ((getNumElements() == 2 && getElement(0) != dwarf::DW_OP_consts) || + (getNumElements() == 3 && getElement(0) != dwarf::DW_OP_consts && + getElement(2) != dwarf::DW_OP_stack_value)) return false; return true; } diff --git a/llvm/lib/Transforms/IPO/StripSymbols.cpp b/llvm/lib/Transforms/IPO/StripSymbols.cpp --- a/llvm/lib/Transforms/IPO/StripSymbols.cpp +++ b/llvm/lib/Transforms/IPO/StripSymbols.cpp @@ -333,7 +333,7 @@ // Create our live global variable list. bool GlobalVariableChange = false; for (auto *DIG : DIC->getGlobalVariables()) { - if (DIG->getExpression() && DIG->getExpression()->isConstant()) + if (DIG->getExpression() && DIG->getExpression()->isUnsignedConstant()) LiveGVs.insert(DIG); // Make sure we only visit each global variable only once. diff --git a/llvm/test/DebugInfo/X86/global-constants.ll b/llvm/test/DebugInfo/X86/global-constants.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/global-constants.ll @@ -0,0 +1,31 @@ +; RUN: llc %s -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s + +; CHECK-DAG-LABEL: DW_AT_name ("negconstant") +; CHECK: DW_AT_const_value (-1) +; CHECK-DAG-LABEL: DW_AT_name ("negconstant2") +; CHECK: DW_AT_const_value (-2) +; CHECK-DAG-LABEL: DW_AT_name ("posconstant") +; CHECK: DW_AT_const_value (1) +; CHECK-DAG-LABEL: DW_AT_name ("posconstant1") +; CHECK: DW_AT_const_value (2) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!13, !14, !15, !16} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3) +!1 = !DIFile(filename: "globalconst.c", directory: "/") +!2 = !{} +!3 = !{!4, !7, !9, !11} +!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression(DW_OP_consts, 18446744073709551615, DW_OP_stack_value)) +!5 = distinct !DIGlobalVariable(name: "negconstant", scope: !0, file: !1, line: 2, type: !6, isLocal: false, isDefinition: true) +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression(DW_OP_consts, 18446744073709551614, DW_OP_stack_value)) +!8 = distinct !DIGlobalVariable(name: "negconstant2", scope: !0, file: !1, line: 3, type: !6, isLocal: false, isDefinition: true) +!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression(DW_OP_consts, 1, DW_OP_stack_value)) +!10 = distinct !DIGlobalVariable(name: "posconstant", scope: !0, file: !1, line: 2, type: !6, isLocal: false, isDefinition: true) +!11 = !DIGlobalVariableExpression(var: !12, expr: !DIExpression(DW_OP_consts, 2, DW_OP_stack_value)) +!12 = distinct !DIGlobalVariable(name: "posconstant2", scope: !0, file: !1, line: 3, type: !6, isLocal: false, isDefinition: true) +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{i32 7, !"PIC Level", i32 2}