Fix a bug in GlobalOpt's handling of DIExpressions.
authorAdrian Prantl <aprantl@apple.com>
Fri, 27 Apr 2018 21:41:36 +0000 (21:41 +0000)
committerAdrian Prantl <aprantl@apple.com>
Fri, 27 Apr 2018 21:41:36 +0000 (21:41 +0000)
This patch adds support for fragment expressions
TryToShrinkGlobalToBoolean() which were previously just dropped.

Thanks to Reid Kleckner for providing me a reproducer!

llvm-svn: 331086

llvm/include/llvm/IR/DebugInfoMetadata.h
llvm/lib/IR/DebugInfoMetadata.cpp
llvm/lib/Transforms/IPO/GlobalOpt.cpp
llvm/lib/Transforms/Utils/Local.cpp
llvm/test/Transforms/GlobalOpt/integer-bool-dwarf.ll

index 749d475..fea3f5a 100644 (file)
@@ -2402,9 +2402,9 @@ public:
 
   /// Prepend \p DIExpr with the given opcodes and optionally turn it into a
   /// stack value.
-  static DIExpression *doPrepend(const DIExpression *DIExpr,
-                                 SmallVectorImpl<uint64_t> &Ops,
-                                 bool StackValue = false);
+  static DIExpression *prependOpcodes(const DIExpression *DIExpr,
+                                      SmallVectorImpl<uint64_t> &Ops,
+                                      bool StackValue = false);
 
   /// Create a DIExpression to describe one part of an aggregate variable that
   /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation
index fe57aa7..f1ad72d 100644 (file)
@@ -785,12 +785,12 @@ DIExpression *DIExpression::prepend(const DIExpression *Expr, bool DerefBefore,
   if (DerefAfter)
     Ops.push_back(dwarf::DW_OP_deref);
 
-  return doPrepend(Expr, Ops, StackValue);
+  return prependOpcodes(Expr, Ops, StackValue);
 }
 
-DIExpression *DIExpression::doPrepend(const DIExpression *Expr,
-                                      SmallVectorImpl<uint64_t> &Ops,
-                                      bool StackValue) {
+DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,
+                                           SmallVectorImpl<uint64_t> &Ops,
+                                           bool StackValue) {
   if (Expr)
     for (auto Op : Expr->expr_ops()) {
       // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
index 96a1f4d..1ae5dde 100644 (file)
@@ -1668,15 +1668,11 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
         // val * (ValOther - ValInit) + ValInit:
         // DW_OP_deref DW_OP_constu <ValMinus>
         // DW_OP_mul DW_OP_constu <ValInit> DW_OP_plus DW_OP_stack_value
-        E = DIExpression::get(NewGV->getContext(),
-                             {dwarf::DW_OP_deref,
-                              dwarf::DW_OP_constu,
-                              ValMinus,
-                              dwarf::DW_OP_mul,
-                              dwarf::DW_OP_constu,
-                              ValInit,
-                              dwarf::DW_OP_plus,
-                              dwarf::DW_OP_stack_value});
+        SmallVector<uint64_t, 12> Ops = {
+            dwarf::DW_OP_deref, dwarf::DW_OP_constu, ValMinus,
+            dwarf::DW_OP_mul,   dwarf::DW_OP_constu, ValInit,
+            dwarf::DW_OP_plus};
+        E = DIExpression::prependOpcodes(E, Ops, DIExpression::WithStackValue);
         DIGlobalVariableExpression *DGVE =
           DIGlobalVariableExpression::get(NewGV->getContext(), DGV, E);
         NewGV->addDebugInfo(DGVE);
index edb01d1..2f7d414 100644 (file)
@@ -1522,8 +1522,8 @@ void llvm::salvageDebugInfo(Instruction &I) {
 
   auto doSalvage = [&](DbgInfoIntrinsic *DII, SmallVectorImpl<uint64_t> &Ops) {
     auto *DIExpr = DII->getExpression();
-    DIExpr = DIExpression::doPrepend(DIExpr, Ops,
-                                     DIExpression::WithStackValue);
+    DIExpr =
+        DIExpression::prependOpcodes(DIExpr, Ops, DIExpression::WithStackValue);
     DII->setOperand(0, wrapMD(I.getOperand(0)));
     DII->setOperand(2, MetadataAsValue::get(I.getContext(), DIExpr));
     DEBUG(dbgs() << "SALVAGE: " << *DII << '\n');
index 5ee9897..3b4460a 100644 (file)
@@ -1,6 +1,10 @@
 ;RUN: opt -S -globalopt -f %s | FileCheck %s
 
-;CHECK: !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_deref, DW_OP_constu, 111, DW_OP_mul, DW_OP_constu, 0, DW_OP_plus, DW_OP_stack_value))
+;CHECK: @foo = internal unnamed_addr global i1 false, align 4, !dbg ![[VAR:.*]]
+;CHECK: ![[VAR]] = !DIGlobalVariableExpression(var: !1, expr:
+;CHECK-SAME: !DIExpression(DW_OP_deref, DW_OP_constu, 111, DW_OP_mul,
+;CHECK-SAME:               DW_OP_constu, 0, DW_OP_plus, DW_OP_stack_value,
+;CHECK-SAME:               DW_OP_LLVM_fragment, 0, 1)) 
 
 @foo = internal global i32 0, align 4, !dbg !0
 
@@ -31,7 +35,7 @@ attributes #0 = { noinline nounwind optnone uwtable }
 !llvm.module.flags = !{!7, !8, !9}
 !llvm.ident = !{!10}
 
-!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_LLVM_fragment, 0, 1))
 !1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !3, line: 1, type: !6, isLocal: true, isDefinition: true)
 !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 6.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
 !3 = !DIFile(filename: "integer-bool-dwarf.c", directory: "/")