From dad5caa59e6b2bde8d6cf5b64a972c393c526c82 Mon Sep 17 00:00:00 2001 From: Amy Huang Date: Mon, 12 Apr 2021 20:02:41 -0700 Subject: [PATCH] Revert "Reapply "[DebugInfo] Use variadic debug values to salvage BinOps and GEP instrs with non-const operands"" This change causes an assert / segmentation fault in LTO builds. This reverts commit f2e4f3eff3c9135d92840016f8ed4540cdd1313b. --- llvm/include/llvm/IR/DebugInfoMetadata.h | 14 -- llvm/include/llvm/IR/Instructions.h | 4 +- llvm/include/llvm/IR/IntrinsicInst.h | 5 - llvm/include/llvm/IR/Operator.h | 6 - llvm/include/llvm/Transforms/Utils/Local.h | 3 +- .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 15 +-- llvm/lib/IR/DebugInfoMetadata.cpp | 21 --- llvm/lib/IR/Instructions.cpp | 9 -- llvm/lib/IR/IntrinsicInst.cpp | 17 --- llvm/lib/IR/Operator.cpp | 57 --------- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 13 +- llvm/lib/Transforms/Utils/Local.cpp | 98 +++++--------- llvm/test/DebugInfo/NVPTX/debug-info.ll | 10 +- llvm/test/DebugInfo/salvage-gep.ll | 56 -------- llvm/test/DebugInfo/salvage-nonconst-binop.ll | 45 ------- llvm/test/Transforms/InstCombine/debuginfo-sink.ll | 16 +-- .../undef_intrinsics_when_deleting_instructions.ll | 142 ++++++++++++--------- 17 files changed, 132 insertions(+), 399 deletions(-) delete mode 100644 llvm/test/DebugInfo/salvage-gep.ll delete mode 100644 llvm/test/DebugInfo/salvage-nonconst-binop.ll diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 48e8c17..a09fee1 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -2594,16 +2594,6 @@ public: // return it's sign information. llvm::Optional isConstant() const; - /// Return the number of unique location operands referred to (via - /// DW_OP_LLVM_arg) in this expression; this is not necessarily the number of - /// instances of DW_OP_LLVM_arg within the expression. - /// For example, for the expression: - /// (DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_plus, - /// DW_OP_LLVM_arg 0, DW_OP_mul) - /// This function would return 2, as there are two unique location operands - /// (0 and 1). - uint64_t getNumLocationOperands() const; - using element_iterator = ArrayRef::iterator; element_iterator elements_begin() const { return getElements().begin(); } @@ -2751,10 +2741,6 @@ public: /// return true with an offset of zero. bool extractIfOffset(int64_t &Offset) const; - /// Returns true iff this DIExpression contains at least one instance of - /// `DW_OP_LLVM_arg, n` for all n in [0, N). - bool hasAllLocationOps(unsigned N) const; - /// Checks if the last 4 elements of the expression are DW_OP_constu DW_OP_swap DW_OP_xderef and extracts the . diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index 14ba509..a0f0897 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -1122,9 +1122,7 @@ public: /// must be at least as wide as the IntPtr type for the address space of /// the base GEP pointer. bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const; - bool collectOffset(const DataLayout &DL, unsigned BitWidth, - SmallDenseMap &VariableOffsets, - APInt &ConstantOffset) const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::GetElementPtr); diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h index eb9b498..e217f97 100644 --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -204,11 +204,6 @@ public: void replaceVariableLocationOp(Value *OldValue, Value *NewValue); void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue); - /// Adding a new location operand will always result in this intrinsic using - /// an ArgList, and must always be accompanied by a new expression that uses - /// the new operand. - void addVariableLocationOps(ArrayRef NewValues, - DIExpression *NewExpr); void setVariable(DILocalVariable *NewVar) { setArgOperand(1, MetadataAsValue::get(NewVar->getContext(), NewVar)); diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h index 303539f..03bcea3 100644 --- a/llvm/include/llvm/IR/Operator.h +++ b/llvm/include/llvm/IR/Operator.h @@ -576,12 +576,6 @@ public: Type *SourceType, ArrayRef Index, const DataLayout &DL, APInt &Offset, function_ref ExternalAnalysis = nullptr); - - /// Collect the offset of this GEP as a map of Values to their associated - /// APInt multipliers, as well as a total Constant Offset. - bool collectOffset(const DataLayout &DL, unsigned BitWidth, - SmallDenseMap &VariableOffsets, - APInt &ConstantOffset) const; }; class PtrToIntOperator diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h index bb57a37..f7efeeb 100644 --- a/llvm/include/llvm/Transforms/Utils/Local.h +++ b/llvm/include/llvm/Transforms/Utils/Local.h @@ -314,8 +314,7 @@ void salvageDebugInfoForDbgValues(Instruction &I, /// appended to the expression. \p LocNo: the index of the location operand to /// which \p I applies, should be 0 for debug info without a DIArgList. DIExpression *salvageDebugInfoImpl(Instruction &I, DIExpression *DIExpr, - bool StackVal, unsigned LocNo, - SmallVectorImpl &AdditionalValues); + bool StackVal, unsigned LocNo); /// Point debug users of \p From to \p To or salvage them. Use this function /// only when replacing all uses of \p From with \p To, with a guarantee that diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index be1c00c..9e14e85 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1238,10 +1238,6 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V, } void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) { - // TODO: For the variadic implementation, instead of only checking the fail - // state of `handleDebugValue`, we need know specifically which values were - // invalid, so that we attempt to salvage only those values when processing - // a DIArgList. assert(!DDI.getDI()->hasArgList() && "Not implemented for variadic dbg_values"); Value *V = DDI.getDI()->getValue(0); @@ -1265,21 +1261,16 @@ void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) { while (isa(V)) { Instruction &VAsInst = *cast(V); // Temporary "0", awaiting real implementation. - SmallVector AdditionalValues; - DIExpression *SalvagedExpr = - salvageDebugInfoImpl(VAsInst, Expr, StackValue, 0, AdditionalValues); + DIExpression *NewExpr = salvageDebugInfoImpl(VAsInst, Expr, StackValue, 0); // If we cannot salvage any further, and haven't yet found a suitable debug // expression, bail out. - // TODO: If AdditionalValues isn't empty, then the salvage can only be - // represented with a DBG_VALUE_LIST, so we give up. When we have support - // here for variadic dbg_values, remove that condition. - if (!SalvagedExpr || !AdditionalValues.empty()) + if (!NewExpr) break; // New value and expr now represent this debuginfo. V = VAsInst.getOperand(0); - Expr = SalvagedExpr; + Expr = NewExpr; // Some kind of simplification occurred: check whether the operand of the // salvaged debug expression can be encoded in this DAG. diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 936a303..1299acd 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -1244,17 +1244,6 @@ bool DIExpression::extractIfOffset(int64_t &Offset) const { return false; } -bool DIExpression::hasAllLocationOps(unsigned N) const { - SmallDenseSet SeenOps; - for (auto ExprOp : expr_ops()) - if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg) - SeenOps.insert(ExprOp.getArg(0)); - for (uint64_t Idx = 0; Idx < N; ++Idx) - if (!is_contained(SeenOps, Idx)) - return false; - return true; -} - const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr, unsigned &AddrClass) { // FIXME: This seems fragile. Nothing that verifies that these elements @@ -1469,16 +1458,6 @@ Optional DIExpression::createFragmentExpression( return DIExpression::get(Expr->getContext(), Ops); } -uint64_t DIExpression::getNumLocationOperands() const { - uint64_t Result = 0; - for (auto ExprOp : expr_ops()) - if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg) - Result = std::max(Result, ExprOp.getArg(0) + 1); - assert(hasAllLocationOps(Result) && - "Expression is missing one or more location operands."); - return Result; -} - llvm::Optional DIExpression::isConstant() const { diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 397561c..8ddadf4 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -1806,15 +1806,6 @@ bool GetElementPtrInst::accumulateConstantOffset(const DataLayout &DL, return cast(this)->accumulateConstantOffset(DL, Offset); } -bool GetElementPtrInst::collectOffset( - const DataLayout &DL, unsigned BitWidth, - SmallDenseMap &VariableOffsets, - APInt &ConstantOffset) const { - // Delegate to the generic GEPOperator implementation. - return cast(this)->collectOffset(DL, BitWidth, VariableOffsets, - ConstantOffset); -} - //===----------------------------------------------------------------------===// // ExtractElementInst Implementation //===----------------------------------------------------------------------===// diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp index 80198d4..14b8732 100644 --- a/llvm/lib/IR/IntrinsicInst.cpp +++ b/llvm/lib/IR/IntrinsicInst.cpp @@ -118,23 +118,6 @@ void DbgVariableIntrinsic::replaceVariableLocationOp(unsigned OpIdx, 0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs))); } -void DbgVariableIntrinsic::addVariableLocationOps(ArrayRef NewValues, - DIExpression *NewExpr) { - assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() + - NewValues.size()) && - "NewExpr for debug variable intrinsic does not reference every " - "location operand."); - assert(!is_contained(NewValues, nullptr) && "New values must be non-null"); - setArgOperand(2, MetadataAsValue::get(getContext(), NewExpr)); - SmallVector MDs; - for (auto *VMD : location_ops()) - MDs.push_back(getAsMetadata(VMD)); - for (auto *VMD : NewValues) - MDs.push_back(getAsMetadata(VMD)); - setArgOperand( - 0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs))); -} - Optional DbgVariableIntrinsic::getFragmentSizeInBits() const { if (auto Fragment = getExpression()->getFragmentInfo()) return Fragment->SizeInBits; diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp index e030cb5..69181f3 100644 --- a/llvm/lib/IR/Operator.cpp +++ b/llvm/lib/IR/Operator.cpp @@ -142,61 +142,4 @@ bool GEPOperator::accumulateConstantOffset( } return true; } - -bool GEPOperator::collectOffset( - const DataLayout &DL, unsigned BitWidth, - SmallDenseMap &VariableOffsets, - APInt &ConstantOffset) const { - assert(BitWidth == DL.getIndexSizeInBits(getPointerAddressSpace()) && - "The offset bit width does not match DL specification."); - - auto CollectConstantOffset = [&](APInt Index, uint64_t Size) { - Index = Index.sextOrTrunc(BitWidth); - APInt IndexedSize = APInt(BitWidth, Size); - ConstantOffset += Index * IndexedSize; - }; - - for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this); - GTI != GTE; ++GTI) { - // Scalable vectors are multiplied by a runtime constant. - bool ScalableType = isa(GTI.getIndexedType()); - - Value *V = GTI.getOperand(); - StructType *STy = GTI.getStructTypeOrNull(); - // Handle ConstantInt if possible. - if (auto ConstOffset = dyn_cast(V)) { - if (ConstOffset->isZero()) - continue; - // If the type is scalable and the constant is not zero (vscale * n * 0 = - // 0) bailout. - // TODO: If the runtime value is accessible at any point before DWARF - // emission, then we could potentially keep a forward reference to it - // in the debug value to be filled in later. - if (ScalableType) - return false; - // Handle a struct index, which adds its field offset to the pointer. - if (STy) { - unsigned ElementIdx = ConstOffset->getZExtValue(); - const StructLayout *SL = DL.getStructLayout(STy); - // Element offset is in bytes. - CollectConstantOffset(APInt(BitWidth, SL->getElementOffset(ElementIdx)), - 1); - continue; - } - CollectConstantOffset(ConstOffset->getValue(), - DL.getTypeAllocSize(GTI.getIndexedType())); - continue; - } - - if (STy || ScalableType) - return false; - // Insert an initial offset of 0 for V iff none exists already, then - // increment the offset by IndexedSize. - VariableOffsets.try_emplace(V, BitWidth, 0); - APInt IndexedSize = - APInt(BitWidth, DL.getTypeAllocSize(GTI.getIndexedType())); - VariableOffsets[V] += IndexedSize; - } - return true; -} } // namespace llvm diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index 692ba12..65aa06e 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -2101,15 +2101,10 @@ void coro::salvageDebugInfo( } else if (auto *StInst = dyn_cast(Storage)) { Storage = StInst->getOperand(0); } else if (auto *GEPInst = dyn_cast(Storage)) { - SmallVector AdditionalValues; - DIExpression *SalvagedExpr = llvm::salvageDebugInfoImpl( - *GEPInst, Expr, - /*WithStackValue=*/false, 0, AdditionalValues); - // Debug declares cannot currently handle additional location - // operands. - if (!SalvagedExpr || !AdditionalValues.empty()) - break; - Expr = SalvagedExpr; + Expr = llvm::salvageDebugInfoImpl(*GEPInst, Expr, + /*WithStackValue=*/false, 0); + if (!Expr) + return; Storage = GEPInst->getOperand(0); } else if (auto *BCInst = dyn_cast(Storage)) Storage = BCInst->getOperand(0); diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 4730e8f..e285f8a 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1816,26 +1816,17 @@ void llvm::salvageDebugInfoForDbgValues( is_contained(DIILocation, &I) && "DbgVariableIntrinsic must use salvaged instruction as its location"); unsigned LocNo = std::distance(DIILocation.begin(), find(DIILocation, &I)); - SmallVector AdditionalValues; - DIExpression *SalvagedExpr = salvageDebugInfoImpl( - I, DII->getExpression(), StackValue, LocNo, AdditionalValues); + + DIExpression *DIExpr = + salvageDebugInfoImpl(I, DII->getExpression(), StackValue, LocNo); // salvageDebugInfoImpl should fail on examining the first element of // DbgUsers, or none of them. - if (!SalvagedExpr) + if (!DIExpr) break; DII->replaceVariableLocationOp(&I, I.getOperand(0)); - if (AdditionalValues.empty()) { - DII->setExpression(SalvagedExpr); - } else if (isa(DII)) { - DII->addVariableLocationOps(AdditionalValues, SalvagedExpr); - } else { - // Do not salvage using DIArgList for dbg.addr/dbg.declare, as it is - // currently only valid for stack value expressions. - Value *Undef = UndefValue::get(I.getOperand(0)->getType()); - DII->replaceVariableLocationOp(I.getOperand(0), Undef); - } + DII->setExpression(DIExpr); LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n'); Salvaged = true; } @@ -1850,27 +1841,12 @@ void llvm::salvageDebugInfoForDbgValues( } bool getSalvageOpsForGEP(GetElementPtrInst *GEP, const DataLayout &DL, - uint64_t CurrentLocOps, - SmallVectorImpl &Opcodes, - SmallVectorImpl &AdditionalValues) { + SmallVectorImpl &Opcodes) { unsigned BitWidth = DL.getIndexSizeInBits(GEP->getPointerAddressSpace()); - // Rewrite a GEP into a DIExpression. - SmallDenseMap VariableOffsets; + // Rewrite a constant GEP into a DIExpression. APInt ConstantOffset(BitWidth, 0); - if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) + if (!GEP->accumulateConstantOffset(DL, ConstantOffset)) return false; - if (!VariableOffsets.empty() && !CurrentLocOps) { - Opcodes.insert(Opcodes.begin(), {dwarf::DW_OP_LLVM_arg, 0}); - CurrentLocOps = 1; - } - for (auto Offset : VariableOffsets) { - AdditionalValues.push_back(Offset.first); - assert(Offset.second.isStrictlyPositive() && - "Expected strictly positive multiplier for offset."); - Opcodes.append({dwarf::DW_OP_LLVM_arg, CurrentLocOps++, dwarf::DW_OP_constu, - Offset.second.getZExtValue(), dwarf::DW_OP_mul, - dwarf::DW_OP_plus}); - } DIExpression::appendOffset(Opcodes, ConstantOffset.getSExtValue()); return true; } @@ -1905,35 +1881,23 @@ uint64_t getDwarfOpForBinOp(Instruction::BinaryOps Opcode) { } } -bool getSalvageOpsForBinOp(BinaryOperator *BI, uint64_t CurrentLocOps, - SmallVectorImpl &Opcodes, - SmallVectorImpl &AdditionalValues) { - // Handle binary operations with constant integer operands as a special case. +bool getSalvageOpsForBinOp(BinaryOperator *BI, + SmallVectorImpl &Opcodes) { + // Rewrite binary operations with constant integer operands. auto *ConstInt = dyn_cast(BI->getOperand(1)); - // Values wider than 64 bits cannot be represented within a DIExpression. - if (ConstInt && ConstInt->getBitWidth() > 64) + if (!ConstInt || ConstInt->getBitWidth() > 64) return false; - + uint64_t Val = ConstInt->getSExtValue(); Instruction::BinaryOps BinOpcode = BI->getOpcode(); - // Push any Constant Int operand onto the expression stack. - if (ConstInt) { - uint64_t Val = ConstInt->getSExtValue(); - // Add or Sub Instructions with a constant operand can potentially be - // simplified. - if (BinOpcode == Instruction::Add || BinOpcode == Instruction::Sub) { - uint64_t Offset = BinOpcode == Instruction::Add ? Val : -int64_t(Val); - DIExpression::appendOffset(Opcodes, Offset); - return true; - } - Opcodes.append({dwarf::DW_OP_constu, Val}); - } else { - if (!CurrentLocOps) { - Opcodes.append({dwarf::DW_OP_LLVM_arg, 0}); - CurrentLocOps = 1; - } - Opcodes.append({dwarf::DW_OP_LLVM_arg, CurrentLocOps}); - AdditionalValues.push_back(BI->getOperand(1)); + // Add or Sub Instructions with a constant operand can potentially be + // simplified. + if (BinOpcode == Instruction::Add || BinOpcode == Instruction::Sub) { + uint64_t Offset = BinOpcode == Instruction::Add ? Val : -int64_t(Val); + DIExpression::appendOffset(Opcodes, Offset); + return true; } + // Add constant int operand to expression stack. + Opcodes.append({dwarf::DW_OP_constu, Val}); // Add salvaged binary operator to expression stack, if it has a valid // representation in a DIExpression. @@ -1945,11 +1909,9 @@ bool getSalvageOpsForBinOp(BinaryOperator *BI, uint64_t CurrentLocOps, return true; } -DIExpression * -llvm::salvageDebugInfoImpl(Instruction &I, DIExpression *SrcDIExpr, - bool WithStackValue, unsigned LocNo, - SmallVectorImpl &AdditionalValues) { - uint64_t CurrentLocOps = SrcDIExpr->getNumLocationOperands(); +DIExpression *llvm::salvageDebugInfoImpl(Instruction &I, + DIExpression *SrcDIExpr, + bool WithStackValue, unsigned LocNo) { auto &M = *I.getModule(); auto &DL = M.getDataLayout(); @@ -1963,7 +1925,7 @@ llvm::salvageDebugInfoImpl(Instruction &I, DIExpression *SrcDIExpr, }; // initializer-list helper for applying operators to the source DIExpression. - auto applyOps = [&](ArrayRef Opcodes) { + auto applyOps = [&](ArrayRef Opcodes) -> DIExpression * { SmallVector Ops(Opcodes.begin(), Opcodes.end()); return doSalvage(Ops); }; @@ -1989,15 +1951,15 @@ llvm::salvageDebugInfoImpl(Instruction &I, DIExpression *SrcDIExpr, SmallVector Ops; if (auto *GEP = dyn_cast(&I)) { - if (getSalvageOpsForGEP(GEP, DL, CurrentLocOps, Ops, AdditionalValues)) + if (getSalvageOpsForGEP(GEP, DL, Ops)) return doSalvage(Ops); } else if (auto *BI = dyn_cast(&I)) { - if (getSalvageOpsForBinOp(BI, CurrentLocOps, Ops, AdditionalValues)) + if (getSalvageOpsForBinOp(BI, Ops)) return doSalvage(Ops); } - // *Not* to do: we should not attempt to salvage load instructions, - // because the validity and lifetime of a dbg.value containing - // DW_OP_deref becomes difficult to analyze. See PR40628 for examples. + // *Not* to do: we should not attempt to salvage load instructions, + // because the validity and lifetime of a dbg.value containing + // DW_OP_deref becomes difficult to analyze. See PR40628 for examples. return nullptr; } diff --git a/llvm/test/DebugInfo/NVPTX/debug-info.ll b/llvm/test/DebugInfo/NVPTX/debug-info.ll index 15ea41e..08a7e03 100644 --- a/llvm/test/DebugInfo/NVPTX/debug-info.ll +++ b/llvm/test/DebugInfo/NVPTX/debug-info.ll @@ -702,12 +702,12 @@ if.end: ; preds = %if.then, %entry ; CHECK-NEXT: } ; CHECK-NEXT: .section .debug_info ; CHECK-NEXT: { -; CHECK-NEXT:.b32 10034 // Length of Unit +; CHECK-NEXT:.b32 10029 // Length of Unit ; CHECK-NEXT:.b8 2 // DWARF version number ; CHECK-NEXT:.b8 0 ; CHECK-NEXT:.b32 .debug_abbrev // Offset Into Abbrev. Section ; CHECK-NEXT:.b8 8 // Address Size (in bytes) -; CHECK-NEXT:.b8 1 // Abbrev [1] 0xb:0x272b DW_TAG_compile_unit +; CHECK-NEXT:.b8 1 // Abbrev [1] 0xb:0x2726 DW_TAG_compile_unit ; CHECK-NEXT:.b8 0 // DW_AT_producer ; CHECK-NEXT:.b8 4 // DW_AT_language ; CHECK-NEXT:.b8 0 @@ -8306,7 +8306,7 @@ if.end: ; preds = %if.then, %entry ; CHECK-NEXT:.b8 3 // DW_AT_decl_line ; CHECK-NEXT:.b32 3345 // DW_AT_type ; CHECK-NEXT:.b8 0 // End Of Children Mark -; CHECK-NEXT:.b8 40 // Abbrev [40] 0x2671:0xc4 DW_TAG_subprogram +; CHECK-NEXT:.b8 40 // Abbrev [40] 0x2671:0xbf DW_TAG_subprogram ; CHECK-NEXT:.b64 Lfunc_begin0 // DW_AT_low_pc ; CHECK-NEXT:.b64 Lfunc_end0 // DW_AT_high_pc ; CHECK-NEXT:.b8 1 // DW_AT_frame_base @@ -8386,7 +8386,7 @@ if.end: ; preds = %if.then, %entry ; CHECK-NEXT:.b8 12 // DW_AT_call_file ; CHECK-NEXT:.b8 6 // DW_AT_call_line ; CHECK-NEXT:.b8 37 // DW_AT_call_column -; CHECK-NEXT:.b8 43 // Abbrev [43] 0x2711:0x23 DW_TAG_inlined_subroutine +; CHECK-NEXT:.b8 43 // Abbrev [43] 0x2711:0x1e DW_TAG_inlined_subroutine ; CHECK-NEXT:.b32 9791 // DW_AT_abstract_origin ; CHECK-NEXT:.b64 Ltmp9 // DW_AT_low_pc ; CHECK-NEXT:.b64 Ltmp10 // DW_AT_high_pc @@ -8395,8 +8395,6 @@ if.end: ; preds = %if.then, %entry ; CHECK-NEXT:.b8 5 // DW_AT_call_column ; CHECK-NEXT:.b8 44 // Abbrev [44] 0x2729:0x5 DW_TAG_formal_parameter ; CHECK-NEXT:.b32 9820 // DW_AT_abstract_origin -; CHECK-NEXT:.b8 44 // Abbrev [44] 0x272e:0x5 DW_TAG_formal_parameter -; CHECK-NEXT:.b32 9829 // DW_AT_abstract_origin ; CHECK-NEXT:.b8 0 // End Of Children Mark ; CHECK-NEXT:.b8 0 // End Of Children Mark ; CHECK-NEXT:.b8 0 // End Of Children Mark diff --git a/llvm/test/DebugInfo/salvage-gep.ll b/llvm/test/DebugInfo/salvage-gep.ll deleted file mode 100644 index 6c31b0f..0000000 --- a/llvm/test/DebugInfo/salvage-gep.ll +++ /dev/null @@ -1,56 +0,0 @@ -; RUN: opt %s -dce -S | FileCheck %s - -; Tests the salvaging of GEP instructions, specifically struct indexing and -; non-constant array indexing. - -%struct.S = type { i32, i32 } - -; CHECK: call void @llvm.dbg.value(metadata !DIArgList(%struct.S* %ptr, i64 %offset), -; CHECK-SAME: ![[VAR_OFFSET_PTR:[0-9]+]], -; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 8, DW_OP_mul, DW_OP_plus, DW_OP_plus_uconst, 4, DW_OP_stack_value)) - -; CHECK: ![[VAR_OFFSET_PTR]] = !DILocalVariable(name: "offset_ptr" - -define void @"?foo@@YAXPEAUS@@_J@Z"(%struct.S* %ptr, i64 %offset) !dbg !8 { -entry: - call void @llvm.dbg.value(metadata i64 %offset, metadata !20, metadata !DIExpression()), !dbg !24 - call void @llvm.dbg.value(metadata %struct.S* %ptr, metadata !21, metadata !DIExpression()), !dbg !24 - %arrayidx = getelementptr inbounds %struct.S, %struct.S* %ptr, i64 %offset, !dbg !25 - %b = getelementptr inbounds %struct.S, %struct.S* %arrayidx, i32 0, i32 1, !dbg !25 - call void @llvm.dbg.value(metadata i32* %b, metadata !22, metadata !DIExpression()), !dbg !24 - ret void, !dbg !26 -} - -declare void @llvm.dbg.value(metadata, metadata, metadata) - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!3, !4, !5, !6} -!llvm.ident = !{!7} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) -!1 = !DIFile(filename: "salvage-gep.cpp", directory: "/") -!2 = !{} -!3 = !{i32 2, !"CodeView", i32 1} -!4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = !{i32 1, !"wchar_size", i32 2} -!6 = !{i32 7, !"PIC Level", i32 2} -!7 = !{!"clang version 11.0.0"} -!8 = distinct !DISubprogram(name: "foo", linkageName: "?foo@@YAXPEAUS@@_J@Z", scope: !9, file: !9, line: 7, type: !10, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !19) -!9 = !DIFile(filename: ".\\salvage-gep.cpp", directory: "/") -!10 = !DISubroutineType(types: !11) -!11 = !{null, !12, !18} -!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) -!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !9, line: 2, size: 64, flags: DIFlagTypePassByValue, elements: !14, identifier: ".?AUS@@") -!14 = !{!15, !17} -!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !9, line: 3, baseType: !16, size: 32) -!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!17 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !13, file: !9, line: 4, baseType: !16, size: 32, offset: 32) -!18 = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed) -!19 = !{!20, !21, !22} -!20 = !DILocalVariable(name: "offset", arg: 2, scope: !8, file: !9, line: 7, type: !18) -!21 = !DILocalVariable(name: "ptr", arg: 1, scope: !8, file: !9, line: 7, type: !12) -!22 = !DILocalVariable(name: "offset_ptr", scope: !8, file: !9, line: 8, type: !23) -!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) -!24 = !DILocation(line: 0, scope: !8) -!25 = !DILocation(line: 8, scope: !8) -!26 = !DILocation(line: 9, scope: !8) diff --git a/llvm/test/DebugInfo/salvage-nonconst-binop.ll b/llvm/test/DebugInfo/salvage-nonconst-binop.ll deleted file mode 100644 index b470bc1..0000000 --- a/llvm/test/DebugInfo/salvage-nonconst-binop.ll +++ /dev/null @@ -1,45 +0,0 @@ -; RUN: opt %s -dce -S | FileCheck %s - -; Tests the salvaging of binary operators that use more than one non-constant -; SSA value. - -; CHECK: call void @llvm.dbg.value(metadata !DIArgList(i32 %a, i32 %b), -; CHECK-SAME: ![[VAR_C:[0-9]+]], -; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value)) - -; CHECK: ![[VAR_C]] = !DILocalVariable(name: "c" - -define i32 @"?multiply@@YAHHH@Z"(i32 %a, i32 %b) !dbg !8 { -entry: - call void @llvm.dbg.value(metadata i32 %b, metadata !12, metadata !DIExpression()), !dbg !13 - call void @llvm.dbg.value(metadata i32 %a, metadata !14, metadata !DIExpression()), !dbg !13 - %add = add nsw i32 %a, %b, !dbg !15 - call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !13 - %mul = mul nsw i32 %a, %b, !dbg !17 - ret i32 %mul, !dbg !17 -} - -declare void @llvm.dbg.value(metadata, metadata, metadata) - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!3, !4, !5, !6} -!llvm.ident = !{!7} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) -!1 = !DIFile(filename: "test.cpp", directory: "/") -!2 = !{} -!3 = !{i32 2, !"CodeView", i32 1} -!4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = !{i32 1, !"wchar_size", i32 2} -!6 = !{i32 7, !"PIC Level", i32 2} -!7 = !{!"clang version 11.0.0"} -!8 = distinct !DISubprogram(name: "multiply", linkageName: "?multiply@@YAHHH@Z", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) -!9 = !DISubroutineType(types: !10) -!10 = !{!11, !11, !11} -!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!12 = !DILocalVariable(name: "b", arg: 2, scope: !8, file: !1, line: 1, type: !11) -!13 = !DILocation(line: 0, scope: !8) -!14 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 1, type: !11) -!15 = !DILocation(line: 2, scope: !8) -!16 = !DILocalVariable(name: "c", scope: !8, file: !1, line: 2, type: !11) -!17 = !DILocation(line: 3, scope: !8) diff --git a/llvm/test/Transforms/InstCombine/debuginfo-sink.ll b/llvm/test/Transforms/InstCombine/debuginfo-sink.ll index 3fb2763..5a8cc78 100644 --- a/llvm/test/Transforms/InstCombine/debuginfo-sink.ll +++ b/llvm/test/Transforms/InstCombine/debuginfo-sink.ll @@ -33,25 +33,23 @@ sink1: ; value range. ; CHECK-LABEL: define i32 @bar( -; CHECK: call void @llvm.dbg.value(metadata * undef, +; CHECK: call void @llvm.dbg.value(metadata i32* undef, ; CHECK-NEXT: br label %sink2 -define i32 @bar(* %a, i32 %b) !dbg !70 { +define i32 @bar(i32 *%a, i32 %b) !dbg !70 { entry: - %gep = getelementptr , * %a, i32 %b - call void @llvm.dbg.value(metadata * %gep, metadata !73, metadata !12), !dbg !74 + %gep = getelementptr i32, i32 *%a, i32 %b + call void @llvm.dbg.value(metadata i32* %gep, metadata !73, metadata !12), !dbg !74 br label %sink2 sink2: ; CHECK-LABEL: sink2: -; CHECK: call void @llvm.dbg.value(metadata * %gep, +; CHECK: call void @llvm.dbg.value(metadata i32* %gep, ; CHECK-SAME: metadata !{{[0-9]+}}, metadata !DIExpression()) ; CHECK-NEXT: load -; CHECK-NEXT: extractelement ; CHECK-NEXT: ret - %0 = load , * %gep - %extract = extractelement %0, i32 1 - ret i32 %extract + %0 = load i32, i32* %gep + ret i32 %0 } ; This GEP is sunk, and has multiple debug uses in the same block. Check that diff --git a/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll b/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll index 349da85..98c51c5 100644 --- a/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll +++ b/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll @@ -1,73 +1,95 @@ -; RUN: opt < %s -reassociate -S | FileCheck %s - -; Check that reassociate pass now undefs debug intrinsics that reference a value -; that gets dropped and cannot be salvaged. - -; CHECK-NOT: %add = fadd fast float %a, %b -; CHECK: call void @llvm.dbg.value(metadata float undef, metadata [[VAR_X:![0-9]+]], metadata !DIExpression()) - -; CHECK-LABEL: if.then: -; CHECK-NOT: %add1 = fadd fast float %add, %c -; CHECK: call void @llvm.dbg.value(metadata float undef, metadata [[VAR_Y:![0-9]+]], metadata !DIExpression()) -; CHECK-LABEL: !0 = -; CHECK-DAG: [[VAR_Y]] = !DILocalVariable(name: "y" -; CHECK-DAG: [[VAR_X]] = !DILocalVariable(name: "x" - -define float @"?foo@@YAMMMMM@Z"(float %a, float %b, float %c, float %d) !dbg !8 { -entry: - call void @llvm.dbg.value(metadata float %d, metadata !12, metadata !DIExpression()), !dbg !13 - call void @llvm.dbg.value(metadata float %c, metadata !14, metadata !DIExpression()), !dbg !13 - call void @llvm.dbg.value(metadata float %b, metadata !15, metadata !DIExpression()), !dbg !13 - call void @llvm.dbg.value(metadata float %a, metadata !16, metadata !DIExpression()), !dbg !13 - %add = fadd fast float %a, %b, !dbg !17 - call void @llvm.dbg.value(metadata float %add, metadata !18, metadata !DIExpression()), !dbg !13 - %cmp = fcmp fast oeq float %d, 4.000000e+00, !dbg !19 - br i1 %cmp, label %if.then, label %return, !dbg !19 +; RUN: opt < %s -reassociate -S | FileCheck %s -if.then: ; preds = %entry - %add1 = fadd fast float %add, %c, !dbg !20 - call void @llvm.dbg.value(metadata float %add1, metadata !23, metadata !DIExpression()), !dbg !24 - %sub = fsub fast float %add, 1.200000e+01, !dbg !25 - %sub2 = fsub fast float %add1, %sub, !dbg !25 - %mul = fmul fast float %sub2, 2.000000e+01, !dbg !25 - %div = fdiv fast float %mul, 3.000000e+00, !dbg !25 - br label %return, !dbg !25 +; Check that reassociate pass now undefs debug intrinsics that reference a value +; that gets dropped and cannot be salvaged. -return: ; preds = %entry, %if.then - %retval.0 = phi float [ %div, %if.then ], [ 0.000000e+00, %entry ], !dbg !13 - ret float %retval.0, !dbg !26 +define hidden i32 @main() local_unnamed_addr { +entry: + %foo = alloca i32, align 4, !dbg !20 + %foo.0.foo.0..sroa_cast = bitcast i32* %foo to i8*, !dbg !20 + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %foo.0.foo.0..sroa_cast), !dbg !20 + store volatile i32 4, i32* %foo, align 4, !dbg !20, !tbaa !21 + %foo.0.foo.0. = load volatile i32, i32* %foo, align 4, !dbg !25, !tbaa !21 + %foo.0.foo.0.15 = load volatile i32, i32* %foo, align 4, !dbg !27, !tbaa !21 + %foo.0.foo.0.16 = load volatile i32, i32* %foo, align 4, !dbg !28, !tbaa !21 + ; CHECK-NOT: %add = add nsw i32 %foo.0.foo.0., %foo.0.foo.0.15 + %add = add nsw i32 %foo.0.foo.0., %foo.0.foo.0.15, !dbg !29 + ; CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata [[VAR_A:![0-9]+]], metadata !DIExpression()) + call void @llvm.dbg.value(metadata i32 %add, metadata !19, metadata !DIExpression()), !dbg !26 + %foo.0.foo.0.17 = load volatile i32, i32* %foo, align 4, !dbg !30, !tbaa !21 + %cmp = icmp eq i32 %foo.0.foo.0.17, 4, !dbg !30 + br i1 %cmp, label %if.then, label %if.end, !dbg !32 + + ; CHECK-LABEL: if.then: +if.then: + ; CHECK-NOT: %add1 = add nsw i32 %add, %foo.0.foo.0.16 + %add1 = add nsw i32 %add, %foo.0.foo.0.16, !dbg !33 + ; CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata [[VAR_A]], metadata !DIExpression()) + call void @llvm.dbg.value(metadata i32 %add1, metadata !19, metadata !DIExpression()), !dbg !26 + ; CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata [[VAR_CHEESE:![0-9]+]], metadata !DIExpression()) + call void @llvm.dbg.value(metadata i32 %add, metadata !18, metadata !DIExpression()), !dbg !26 + %sub = add nsw i32 %add, -12, !dbg !34 + %sub3 = sub nsw i32 %add1, %sub, !dbg !34 + %mul = mul nsw i32 %sub3, 20, !dbg !36 + %div = sdiv i32 %mul, 3, !dbg !37 + br label %if.end, !dbg !38 + +if.end: + %a.0 = phi i32 [ %div, %if.then ], [ 0, %entry ], !dbg !39 + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %foo.0.foo.0..sroa_cast), !dbg !40 + ret i32 %a.0, !dbg !41 } -declare void @llvm.dbg.value(metadata, metadata, metadata) +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4, !5, !6} !llvm.ident = !{!7} -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) -!1 = !DIFile(filename: "undef_intrinsics_when_deleting_instructions.cpp", directory: "/") +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, debugInfoForProfiling: true, nameTableKind: None) +!1 = !DIFile(filename: "test.cpp", directory: "F:\") !2 = !{} -!3 = !{i32 2, !"CodeView", i32 1} +!3 = !{i32 2, !"Dwarf Version", i32 4} !4 = !{i32 2, !"Debug Info Version", i32 3} !5 = !{i32 1, !"wchar_size", i32 2} !6 = !{i32 7, !"PIC Level", i32 2} -!7 = !{!"clang version 11.0.0"} -!8 = distinct !DISubprogram(name: "foo", linkageName: "?foo@@YAMMMMM@Z", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) -!9 = !DISubroutineType(types: !10) -!10 = !{!11, !11, !11, !11, !11} -!11 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float) -!12 = !DILocalVariable(name: "d", arg: 4, scope: !8, file: !1, line: 1, type: !11) -!13 = !DILocation(line: 0, scope: !8) -!14 = !DILocalVariable(name: "c", arg: 3, scope: !8, file: !1, line: 1, type: !11) -!15 = !DILocalVariable(name: "b", arg: 2, scope: !8, file: !1, line: 1, type: !11) -!16 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 1, type: !11) -!17 = !DILocation(line: 2, scope: !8) -!18 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !11) -!19 = !DILocation(line: 3, scope: !8) -!20 = !DILocation(line: 4, scope: !21) -!21 = distinct !DILexicalBlock(scope: !22, file: !1, line: 3) -!22 = distinct !DILexicalBlock(scope: !8, file: !1, line: 3) -!23 = !DILocalVariable(name: "y", scope: !21, file: !1, line: 4, type: !11) -!24 = !DILocation(line: 0, scope: !21) -!25 = !DILocation(line: 5, scope: !21) -!26 = !DILocation(line: 8, scope: !8) +!7 = !{!"clang version 10.0.0"} +!8 = distinct !DISubprogram(name: "main", scope: !9, file: !9, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13) +!9 = !DIFile(filename: "./test.cpp", directory: "F:\") +!10 = !DISubroutineType(types: !11) +!11 = !{!12} +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{!14, !16, !17, !18, !19} +!14 = !DILocalVariable(name: "foo", scope: !8, file: !9, line: 2, type: !15) +!15 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !12) +!16 = !DILocalVariable(name: "read1", scope: !8, file: !9, line: 3, type: !12) +!17 = !DILocalVariable(name: "read2", scope: !8, file: !9, line: 4, type: !12) +; CHECK: [[VAR_CHEESE]] = !DILocalVariable(name: "cheese" +!18 = !DILocalVariable(name: "cheese", scope: !8, file: !9, line: 6, type: !12) +; CHECK: [[VAR_A]] = !DILocalVariable(name: "a" +!19 = !DILocalVariable(name: "a", scope: !8, file: !9, line: 7, type: !12) +!20 = !DILocation(line: 2, scope: !8) +!21 = !{!22, !22, i64 0} +!22 = !{!"int", !23, i64 0} +!23 = !{!"omnipotent char", !24, i64 0} +!24 = !{!"Simple C++ TBAA"} +!25 = !DILocation(line: 3, scope: !8) +!26 = !DILocation(line: 0, scope: !8) +!27 = !DILocation(line: 4, scope: !8) +!28 = !DILocation(line: 6, scope: !8) +!29 = !DILocation(line: 7, scope: !8) +!30 = !DILocation(line: 10, scope: !31) +!31 = distinct !DILexicalBlock(scope: !8, file: !9, line: 10) +!32 = !DILocation(line: 10, scope: !8) +!33 = !DILocation(line: 8, scope: !8) +!34 = !DILocation(line: 12, scope: !35) +!35 = distinct !DILexicalBlock(scope: !31, file: !9, line: 10) +!36 = !DILocation(line: 13, scope: !35) +!37 = !DILocation(line: 14, scope: !35) +!38 = !DILocation(line: 15, scope: !35) +!39 = !DILocation(line: 0, scope: !31) +!40 = !DILocation(line: 20, scope: !8) +!41 = !DILocation(line: 19, scope: !8) -- 2.7.4