[llvm] r226598 - Reapply: Teach SROA how to update debug info for fragmented variables.

Dimitry Andric dimitry at andric.com
Fri Jan 23 09:23:44 PST 2015


Maybe just take the test case I put in PR22309, that is quite short.

-Dimitry

> On 23 Jan 2015, at 18:11, Adrian Prantl <aprantl at apple.com> wrote:
>> On Jan 23, 2015, at 9:02 AM, Dimitry Andric <dimitry at andric.com> wrote:
>> I just submitted http://llvm.org/bugs/show_bug.cgi?id=22309 which is the same issue.  I think this should fix it:
>> 
>> diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
>> index 3d3da2a..0d1979d 100644
>> --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
>> +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
>> @@ -584,7 +584,8 @@ static bool isUnsignedDIType(DwarfDebug *DD, DIType Ty) {
>>        T == dwarf::DW_TAG_ptr_to_member_type ||
>>        T == dwarf::DW_TAG_reference_type ||
>>        T == dwarf::DW_TAG_rvalue_reference_type ||
>> -        T == dwarf::DW_TAG_structure_type)
>> +        T == dwarf::DW_TAG_structure_type ||
>> +        T == dwarf::DW_TAG_union_type)
>>      return true;
>>    assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
>>           T == dwarf::DW_TAG_volatile_type ||
>> 
>> but I'm not really sure whether that is the right solution.
> No this probably correct. I will just need to create a testcase for it and then I’ll commit the fix.
> 
>> Maybe there are even more aggregate types to add to this list?
> Yes, historically we’ve been adding them on a case-by-case basis.
> 
> -- adrian
> 
>> 
>> -Dimitry
>> 
>>> On 23 Jan 2015, at 16:59, Adrian Prantl <aprantl at apple.com> wrote:
>>> 
>>> 
>>>> On Jan 23, 2015, at 2:15 AM, Hao Liu <Hao.Liu at arm.com> wrote:
>>>> 
>>>> Hi Adrian,
>>>> 
>>>> I observe a crash caused by this commit on our internal tests. Without "-g"
>>>> the test can be built successfully. This original case is a little difficult
>>>> to be simplified. I will work on reproducer.
>>> 
>>> That would be great!
>>> 
>>>> Just let you know so that maybe you can find the root cause and fix it.
>>> 
>>> In order to diagnose the problem, it might be sufficient information if you could just to just invoke ->dump() on the type that is passed into isUnsignedDIType(). We may simply need to add another TAG to this list.
>>> 
>>> thanks,
>>> -- adrian
>>>> 
>>>> clang-3.7: ./llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:592: bool
>>>> isUnsignedDIType(llvm::DwarfDebug*, llvm::DIType): Assertion `T ==
>>>> dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type || T ==
>>>> dwarf::DW_TAG_volatile_type || T == dwarf::DW_TAG_restrict_type || T ==
>>>> dwarf::DW_TAG_enumeration_type' failed.
>>>> #0 0x1d27f90 llvm::sys::PrintStackTrace(_IO_FILE*)
>>>> ./llvm/lib/Support/Unix/Signals.inc:423:0
>>>> #1 0x1d2822b PrintStackTraceSignalHandler(void*)
>>>> ./llvm/lib/Support/Unix/Signals.inc:481:0
>>>> #2 0x1d26e4d SignalHandler(int) ./llvm/lib/Support/Unix/Signals.inc:198:0
>>>> #3 0x7ffaa3f5f340 __restore_rt
>>>> (/lib/x86_64-linux-gnu/libpthread.so.0+0x10340)
>>>> #4 0x7ffaa3186cc9 gsignal
>>>> /build/buildd/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:
>>>> 0
>>>> #5 0x7ffaa318a0d8 abort /build/buildd/eglibc-2.19/stdlib/abort.c:91:0
>>>> #6 0x7ffaa317fb86 __assert_fail_base
>>>> /build/buildd/eglibc-2.19/assert/assert.c:92:0
>>>> #7 0x7ffaa317fc32 (/lib/x86_64-linux-gnu/libc.so.6+0x2fc32)
>>>> #8 0x207f2b5 isUnsignedDIType(llvm::DwarfDebug*, llvm::DIType)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:593:0
>>>> #9 0x207f300 isUnsignedDIType(llvm::DwarfDebug*, llvm::DIType)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:594:0
>>>> #10 0x207f8a4 llvm::DwarfUnit::addConstantValue(llvm::DIE&,
>>>> llvm::MachineOperand const&, llvm::DIType)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:686:0
>>>> #11 0x20ad32e
>>>> llvm::DwarfCompileUnit::constructVariableDIEImpl(llvm::DbgVariable const&,
>>>> bool) ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:508:0
>>>> #12 0x20ad081
>>>> llvm::DwarfCompileUnit::constructVariableDIE(llvm::DbgVariable&, bool)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:472:0
>>>> #13 0x20ad50f
>>>> llvm::DwarfCompileUnit::constructVariableDIE(llvm::DbgVariable&,
>>>> llvm::LexicalScope const&, llvm::DIE*&)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:535:0
>>>> #14 0x20ad623
>>>> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&, unsigned int*)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:546:0
>>>> #15 0x20ac41c llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:346:0
>>>> #16 0x20ad6f0
>>>> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&, unsigned int*)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
>>>> #17 0x20ac41c llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:346:0
>>>> #18 0x20ad6f0
>>>> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&, unsigned int*)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
>>>> #19 0x20ac3cd llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:333:0
>>>> #20 0x20ad6f0
>>>> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&, unsigned int*)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
>>>> #21 0x20ac41c llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:346:0
>>>> #22 0x20ad6f0
>>>> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&, unsigned int*)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
>>>> #23 0x20ac41c llvm::DwarfCompileUnit::constructScopeDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:346:0
>>>> #24 0x20ad6f0
>>>> llvm::DwarfCompileUnit::createScopeChildrenDIE(llvm::LexicalScope*,
>>>> llvm::SmallVectorImpl<std::unique_ptr<llvm::DIE,
>>>> std::default_delete<llvm::DIE> > >&, unsigned int*)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:550:0
>>>> #25 0x20ada2d
>>>> llvm::DwarfCompileUnit::createAndAddScopeChildren(llvm::LexicalScope*,
>>>> llvm::DIE&) ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:593:0
>>>> #26 0x20ad8f1
>>>> llvm::DwarfCompileUnit::constructSubprogramScopeDIE(llvm::LexicalScope*)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:577:0
>>>> #27 0x20562e7 llvm::DwarfDebug::endFunction(llvm::MachineFunction const*)
>>>> ./llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:1306:0
>>>> #28 0x203ec5a llvm::AsmPrinter::EmitFunctionBody()
>>>> ./llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:887:0
>>>> #29 0x12c03dd llvm::AsmPrinter::runOnMachineFunction(llvm::MachineFunction&)
>>>> ./llvm/include/llvm/CodeGen/AsmPrinter.h:189:0
>>>> #30 0x12c0604 (anonymous
>>>> namespace)::AArch64AsmPrinter::runOnMachineFunction(llvm::MachineFunction&)
>>>> ./llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp:89:0
>>>> #31 0x1661c9d llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
>>>> ./llvm/lib/CodeGen/MachineFunctionPass.cpp:34:0
>>>> #32 0x198a476 llvm::FPPassManager::runOnFunction(llvm::Function&)
>>>> ./llvm/lib/IR/LegacyPassManager.cpp:1530:0
>>>> #33 0x198a5e6 llvm::FPPassManager::runOnModule(llvm::Module&)
>>>> ./llvm/lib/IR/LegacyPassManager.cpp:1550:0
>>>> #34 0x198a904 (anonymous
>>>> namespace)::MPPassManager::runOnModule(llvm::Module&)
>>>> ./llvm/lib/IR/LegacyPassManager.cpp:1608:0
>>>> #35 0x198afa8 llvm::legacy::PassManagerImpl::run(llvm::Module&)
>>>> ./llvm/lib/IR/LegacyPassManager.cpp:1715:0
>>>> #36 0x198b1c7 llvm::legacy::PassManager::run(llvm::Module&)
>>>> ./llvm/lib/IR/LegacyPassManager.cpp:1749:0
>>>> #37 0x2292b3b (anonymous
>>>> namespace)::EmitAssemblyHelper::EmitAssembly(clang::BackendAction,
>>>> llvm::raw_ostream*) ./llvm/tools/clang/lib/CodeGen/BackendUtil.cpp:634:0
>>>> #38 0x2292c0a clang::EmitBackendOutput(clang::DiagnosticsEngine&,
>>>> clang::CodeGenOptions const&, clang::TargetOptions const&,
>>>> clang::LangOptions const&, llvm::StringRef, llvm::Module*,
>>>> clang::BackendAction, llvm::raw_ostream*)
>>>> ./llvm/tools/clang/lib/CodeGen/BackendUtil.cpp:650:0
>>>> #39 0x22785ec
>>>> clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&)
>>>> ./llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp:178:0
>>>> #40 0x2caa57a clang::ParseAST(clang::Sema&, bool, bool)
>>>> ./llvm/tools/clang/lib/Parse/ParseAST.cpp:153:0
>>>> #41 0x1f24938 clang::ASTFrontendAction::ExecuteAction()
>>>> ./llvm/tools/clang/lib/Frontend/FrontendAction.cpp:528:0
>>>> #42 0x227aab7 clang::CodeGenAction::ExecuteAction()
>>>> ./llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp:728:0
>>>> #43 0x1f24413 clang::FrontendAction::Execute()
>>>> ./llvm/tools/clang/lib/Frontend/FrontendAction.cpp:432:0
>>>> #44 0x1eeda94 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)
>>>> ./llvm/tools/clang/lib/Frontend/CompilerInstance.cpp:812:0
>>>> #45 0x20356b5 clang::ExecuteCompilerInvocation(clang::CompilerInstance*)
>>>> ./llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:222:0
>>>> #46 0x10d8d66 cc1_main(llvm::ArrayRef<char const*>, char const*, void*)
>>>> ./llvm/tools/clang/tools/driver/cc1_main.cpp:110:0
>>>> #47 0x10d1522 ExecuteCC1Tool(llvm::ArrayRef<char const*>, llvm::StringRef) .
>>>> /llvm/tools/clang/tools/driver/driver.cpp:369:0
>>>> #48 0x10d1b04 main ./llvm/tools/clang/tools/driver/driver.cpp:415:0
>>>> #49 0x7ffaa3171ec5 __libc_start_main
>>>> /build/buildd/eglibc-2.19/csu/libc-start.c:321:0
>>>> #50 0x10ce559 _start (./llvm/2build/bin/clang-3.7+0x10ce559)
>>>> 
>>>>>> -----Original Message-----
>>>>>> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
>>>>>> bounces at cs.uiuc.edu] On Behalf Of Adrian Prantl
>>>>>> Sent: 2015年1月21日 3:42
>>>>>> To: llvm-commits at cs.uiuc.edu
>>>>>> Subject: [llvm] r226598 - Reapply: Teach SROA how to update debug info for
>>>>>> fragmented variables.
>>>>>> 
>>>>>> Author: adrian
>>>>>> Date: Tue Jan 20 13:42:22 2015
>>>>>> New Revision: 226598
>>>>>> 
>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=226598&view=rev
>>>>>> Log:
>>>>>> Reapply: Teach SROA how to update debug info for fragmented variables.
>>>>>> This reapplies r225379.
>>>>>> 
>>>>>> ChangeLog:
>>>>>> - The assertion that this commit previously ran into about the inability
>>>>>> to handle indirect variables has since been removed and the backend
>>>>>> can handle this now.
>>>>>> - Testcases were upgrade to the new MDLocation format.
>>>>>> - Instead of keeping a DebugDeclares map, we now use
>>>>>> llvm::FindAllocaDbgDeclare().
>>>>>> 
>>>>>> Original commit message follows.
>>>>>> 
>>>>>> Debug info: Teach SROA how to update debug info for fragmented variables.
>>>>>> This allows us to generate debug info for extremely advanced code such as
>>>>>> 
>>>>>> typedef struct { long int a; int b;} S;
>>>>>> 
>>>>>> int foo(S s) {
>>>>>> return s.b;
>>>>>> }
>>>>>> 
>>>>>> which at -O1 on x86_64 is codegen'd into
>>>>>> 
>>>>>> define i32 @foo(i64 %s.coerce0, i32 %s.coerce1) #0 {
>>>>>> ret i32 %s.coerce1, !dbg !24
>>>>>> }
>>>>>> 
>>>>>> with this patch we emit the following debug info for this
>>>>>> 
>>>>>> TAG_formal_parameter [3]
>>>>>> AT_location( 0x00000000
>>>>>>            0x0000000000000000 - 0x0000000000000006: rdi, piece
>>>>>> 0x00000008, rsi, piece 0x00000004
>>>>>>            0x0000000000000006 - 0x0000000000000008: rdi, piece
>>>>>> 0x00000008, rax, piece 0x00000004 )
>>>>>>            AT_name( "s" )
>>>>>>            AT_decl_file(
>>>> "/Volumes/Data/llvm/_build.ninja.release/test.c" )
>>>>>> 
>>>>>> Thanks to chandlerc, dblaikie, and echristo for their feedback on all
>>>> previous
>>>>>> iterations of this patch!
>>>>>> 
>>>>>> Added:
>>>>>> llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll
>>>>>> llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll
>>>>>> llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll
>>>>>> Modified:
>>>>>> llvm/trunk/lib/Transforms/Scalar/SROA.cpp
>>>>>> llvm/trunk/test/DebugInfo/X86/array2.ll
>>>>>> 
>>>>>> Modified: llvm/trunk/lib/Transforms/Scalar/SROA.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>> project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=226598&r1=226597
>>>>>> &r2=226598&view=diff
>>>>>> ===============================================================
>>>>>> ===============
>>>>>> --- llvm/trunk/lib/Transforms/Scalar/SROA.cpp (original)
>>>>>> +++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp Tue Jan 20 13:42:22 2015
>>>>>> @@ -1257,8 +1257,8 @@ private:
>>>>>> friend class AllocaSliceRewriter;
>>>>>> 
>>>>>> bool presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS);
>>>>>> -  bool rewritePartition(AllocaInst &AI, AllocaSlices &AS,
>>>>>> -                        AllocaSlices::Partition &P);
>>>>>> +  AllocaInst *rewritePartition(AllocaInst &AI, AllocaSlices &AS,
>>>>>> +                               AllocaSlices::Partition &P);
>>>>>> bool splitAlloca(AllocaInst &AI, AllocaSlices &AS);
>>>>>> bool runOnAlloca(AllocaInst &AI);
>>>>>> void clobberUse(Use &U);
>>>>>> @@ -3964,8 +3964,8 @@ bool SROA::presplitLoadsAndStores(Alloca
>>>>>> /// appropriate new offsets. It also evaluates how successful the rewrite
>>>> was
>>>>>> /// at enabling promotion and if it was successful queues the alloca to be
>>>> ///
>>>>>> promoted.
>>>>>> -bool SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
>>>>>> -                            AllocaSlices::Partition &P) {
>>>>>> +AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
>>>>>> +                                   AllocaSlices::Partition &P) {
>>>>>> // Try to compute a friendly type for this partition of the alloca.
>>>> This
>>>>>> // won't always succeed, in which case we fall back to a legal integer
>>>> type
>>>>>> // or an i8 array of an appropriate size.
>>>>>> @@ -4003,6 +4003,7 @@ bool SROA::rewritePartition(AllocaInst &
>>>>>> NewAI = &AI;
>>>>>> // FIXME: We should be able to bail at this point with "nothing
>>>> changed".
>>>>>> // FIXME: We might want to defer PHI speculation until after here.
>>>>>> +    // FIXME: return nullptr;
>>>>>> } else {
>>>>>> unsigned Alignment = AI.getAlignment();
>>>>>> if (!Alignment) {
>>>>>> @@ -4098,7 +4099,7 @@ bool SROA::rewritePartition(AllocaInst &
>>>>>>   PostPromotionWorklist.pop_back();
>>>>>> }
>>>>>> 
>>>>>> -  return true;
>>>>>> +  return NewAI;
>>>>>> }
>>>>>> 
>>>>>> /// \brief Walks the slices of an alloca and form partitions based on
>>>> them,
>>>>>> @@ -4137,9 +4138,24 @@ bool SROA::splitAlloca(AllocaInst &AI, A
>>>>>> if (!IsSorted)
>>>>>> std::sort(AS.begin(), AS.end());
>>>>>> 
>>>>>> +  /// \brief Describes the allocas introduced by rewritePartition  ///
>>>>>> + in order to migrate the debug info.
>>>>>> +  struct Piece {
>>>>>> +    AllocaInst *Alloca;
>>>>>> +    uint64_t Offset;
>>>>>> +    uint64_t Size;
>>>>>> +    Piece(AllocaInst *AI, uint64_t O, uint64_t S)
>>>>>> +      : Alloca(AI), Offset(O), Size(S) {}  };  SmallVector<Piece, 4>
>>>>>> + Pieces;
>>>>>> +
>>>>>> // Rewrite each partition.
>>>>>> for (auto &P : AS.partitions()) {
>>>>>> -    Changed |= rewritePartition(AI, AS, P);
>>>>>> +    if (AllocaInst *NewAI = rewritePartition(AI, AS, P)) {
>>>>>> +      Changed = true;
>>>>>> +      if (NewAI != &AI)
>>>>>> +        Pieces.push_back(Piece(NewAI, P.beginOffset(), P.size()));
>>>>>> +    }
>>>>>> ++NumPartitions;
>>>>>> }
>>>>>> 
>>>>>> @@ -4147,6 +4163,28 @@ bool SROA::splitAlloca(AllocaInst &AI, A
>>>>>> MaxPartitionsPerAlloca =
>>>>>>   std::max<unsigned>(NumPartitions, MaxPartitionsPerAlloca);
>>>>>> 
>>>>>> +  // Migrate debug information from the old alloca to the new alloca(s)
>>>>>> + // and the individial partitions.
>>>>>> +  if (DbgDeclareInst *DbgDecl = FindAllocaDbgDeclare(&AI)) {
>>>>>> +    DIVariable Var(DbgDecl->getVariable());
>>>>>> +    DIExpression Expr(DbgDecl->getExpression());
>>>>>> +    DIBuilder DIB(*AI.getParent()->getParent()->getParent(),
>>>>>> +                  /*AllowUnresolved*/ false);
>>>>>> +    bool IsSplit = Pieces.size() > 1;
>>>>>> +    for (auto Piece : Pieces) {
>>>>>> +      // Create a piece expression describing the new partition or reuse
>>>> AI's
>>>>>> +      // expression if there is only one partition.
>>>>>> +      if (IsSplit)
>>>>>> +        Expr = DIB.createPieceExpression(Piece.Offset, Piece.Size);
>>>>>> +
>>>>>> +      // Remove any existing dbg.declare intrinsic describing the same
>>>> alloca.
>>>>>> +      if (DbgDeclareInst *OldDDI = FindAllocaDbgDeclare(Piece.Alloca))
>>>>>> +        OldDDI->eraseFromParent();
>>>>>> +
>>>>>> +      Instruction *NewDDI = DIB.insertDeclare(Piece.Alloca, Var, Expr,
>>>> &AI);
>>>>>> +      NewDDI->setDebugLoc(DbgDecl->getDebugLoc());
>>>>>> +    }
>>>>>> +  }
>>>>>> return Changed;
>>>>>> }
>>>>>> 
>>>>>> @@ -4258,8 +4296,11 @@ void SROA::deleteDeadInstructions(
>>>>>>       DeadInsts.insert(U);
>>>>>>   }
>>>>>> 
>>>>>> -    if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
>>>>>> +    if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
>>>>>>   DeletedAllocas.insert(AI);
>>>>>> +      if (DbgDeclareInst *DbgDecl = FindAllocaDbgDeclare(AI))
>>>>>> +        DbgDecl->eraseFromParent();
>>>>>> +    }
>>>>>> 
>>>>>> ++NumDeleted;
>>>>>> I->eraseFromParent();
>>>>>> @@ -4376,9 +4417,10 @@ bool SROA::runOnFunction(Function &F) {
>>>>>> 
>>>>>> BasicBlock &EntryBB = F.getEntryBlock();
>>>>>> for (BasicBlock::iterator I = EntryBB.begin(), E =
>>>> std::prev(EntryBB.end());
>>>>>> -       I != E; ++I)
>>>>>> +       I != E; ++I) {
>>>>>> if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
>>>>>>   Worklist.insert(AI);
>>>>>> +  }
>>>>>> 
>>>>>> bool Changed = false;
>>>>>> // A set of deleted alloca instruction pointers which should be removed
>>>> from
>>>>>> 
>>>>>> Modified: llvm/trunk/test/DebugInfo/X86/array2.ll
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>> project/llvm/trunk/test/DebugInfo/X86/array2.ll?rev=226598&r1=226597&r2
>>>>>> =226598&view=diff
>>>>>> ===============================================================
>>>>>> ===============
>>>>>> --- llvm/trunk/test/DebugInfo/X86/array2.ll (original)
>>>>>> +++ llvm/trunk/test/DebugInfo/X86/array2.ll Tue Jan 20 13:42:22 2015
>>>>>> @@ -13,12 +13,12 @@
>>>>>> ; }
>>>>>> ;
>>>>>> ; RUN: opt %s -O2 -S -o - | FileCheck %s -; Test that we do not lower
>>>>>> dbg.declares for arrays.
>>>>>> +; Test that we correctly lower dbg.declares for arrays.
>>>>>> ;
>>>>>> ; CHECK: define i32 @main
>>>>>> -; CHECK: call void @llvm.dbg.value
>>>>>> -; CHECK: call void @llvm.dbg.value
>>>>>> -; CHECK: call void @llvm.dbg.declare
>>>>>> +; CHECK: call void @llvm.dbg.value(metadata i32 42, i64 0, metadata
>>>>>> +![[ARRAY:[0-9]+]], metadata ![[EXPR:[0-9]+]]) ; CHECK: ![[ARRAY]] =
>>>>>> +{{.*}}; [ DW_TAG_auto_variable ] [array] [line 6] ; CHECK: ![[EXPR]] =
>>>>>> +{{.*}}; [ DW_TAG_expression ] [DW_OP_piece offset=0, size=4]
>>>>>> target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>>> target triple = "x86_64-apple-macosx10.9.0"
>>>>>> 
>>>>>> 
>>>>>> Added: llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>> project/llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll?rev=226598&view=auto
>>>>>> ===============================================================
>>>>>> ===============
>>>>>> --- llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll (added)
>>>>>> +++ llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll Tue Jan 20 13:42:22
>>>>>> +++ 2015
>>>>>> @@ -0,0 +1,97 @@
>>>>>> +; RUN: opt %s -sroa -verify -S -o - | FileCheck %s ; ; Test that we can
>>>>>> +partial emit debug info for aggregates repeatedly ; split up by SROA.
>>>>>> +;
>>>>>> +;    // Compile with -O1
>>>>>> +;    typedef struct {
>>>>>> +;      int a;
>>>>>> +;      long int b;
>>>>>> +;    } Inner;
>>>>>> +;
>>>>>> +;    typedef struct {
>>>>>> +;      Inner inner[2];
>>>>>> +;    } Outer;
>>>>>> +;
>>>>>> +;    int foo(Outer outer) {
>>>>>> +;      Inner i1 = outer.inner[1];
>>>>>> +;      return i1.a;
>>>>>> +;    }
>>>>>> +;
>>>>>> +
>>>>>> +; Verify that SROA creates a variable piece when splitting i1.
>>>>>> +; CHECK: %[[I1:.*]] = alloca [12 x i8], align 4 ; CHECK: call void
>>>>>> + at llvm.dbg.declare(metadata [12 x i8]* %[[I1]], metadata
>>>>>> +![[VAR:[0-9]+]], metadata ![[PIECE1:[0-9]+]]) ; CHECK: call void
>>>>>> + at llvm.dbg.value(metadata i32 %[[A:.*]], i64 0, metadata ![[VAR]],
>>>>>> +metadata ![[PIECE2:[0-9]+]]) ; CHECK: ret i32 %[[A]] ; Read Var and
>>>> Piece:
>>>>>> +; CHECK: ![[VAR]] = {{.*}} ; [ DW_TAG_auto_variable ] [i1] [line 11] ;
>>>>>> +CHECK: ![[PIECE1]] = {{.*}} ; [ DW_TAG_expression ] [DW_OP_piece
>>>>>> +offset=4, size=12] ; CHECK: ![[PIECE2]] = {{.*}} ; [ DW_TAG_expression
>>>>>> +] [DW_OP_piece offset=0, size=4]
>>>>>> +
>>>>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>>> +target triple = "x86_64-apple-macosx10.9.0"
>>>>>> +
>>>>>> +%struct.Outer = type { [2 x %struct.Inner] } %struct.Inner = type {
>>>>>> +i32, i64 }
>>>>>> +
>>>>>> +; Function Attrs: nounwind ssp uwtable
>>>>>> +define i32 @foo(%struct.Outer* byval align 8 %outer) #0 {
>>>>>> +entry:
>>>>>> +  %i1 = alloca %struct.Inner, align 8
>>>>>> +  call void @llvm.dbg.declare(metadata %struct.Outer* %outer, metadata
>>>>>> +!25, metadata !2), !dbg !26
>>>>>> +  call void @llvm.dbg.declare(metadata %struct.Inner* %i1, metadata
>>>>>> +!27, metadata !2), !dbg !28
>>>>>> +  %inner = getelementptr inbounds %struct.Outer* %outer, i32 0, i32 0,
>>>>>> +!dbg !28
>>>>>> +  %arrayidx = getelementptr inbounds [2 x %struct.Inner]* %inner, i32
>>>>>> +0, i64 1, !dbg !28
>>>>>> +  %0 = bitcast %struct.Inner* %i1 to i8*, !dbg !28
>>>>>> +  %1 = bitcast %struct.Inner* %arrayidx to i8*, !dbg !28
>>>>>> +  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 16, i32 8,
>>>>>> +i1 false), !dbg !28
>>>>>> +  %a = getelementptr inbounds %struct.Inner* %i1, i32 0, i32 0, !dbg
>>>>>> +!29
>>>>>> +  %2 = load i32* %a, align 4, !dbg !29
>>>>>> +  ret i32 %2, !dbg !29
>>>>>> +}
>>>>>> +
>>>>>> +; Function Attrs: nounwind readnone
>>>>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>>>>> +
>>>>>> +; Function Attrs: nounwind
>>>>>> +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture
>>>>>> +readonly, i64, i32, i1) #2
>>>>>> +
>>>>>> +attributes #0 = { nounwind ssp uwtable } attributes #1 = { nounwind
>>>>>> +readnone } attributes #2 = { nounwind }
>>>>>> +
>>>>>> +!llvm.dbg.cu = !{!0}
>>>>>> +!llvm.module.flags = !{!22, !23}
>>>>>> +!llvm.ident = !{!24}
>>>>>> +
>>>>>> +!0 = !{!"0x11\0012\00clang version 3.5.0 \000\00\000\00\001", !1, !2,
>>>>>> +!2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [ DW_TAG_compile_unit ]
>>>>>> +[sroasplit-1.c] [DW_LANG_C99]
>>>>>> +!1 = !{!"sroasplit-1.c", !""}
>>>>>> +!2 = !{}
>>>>>> +!3 = !{!4}
>>>>>> +!4 = !{!"0x2e\00foo\00foo\00\0010\000\001\000\006\00256\000\0010", !1,
>>>>>> +!5, !6, null, i32 (%struct.Outer*)* @foo, null, null, !2} ; [
>>>>>> +DW_TAG_subprogram ] [ DW_TAG_subprogram ] [line 10] [def] [foo]
>>>>>> +!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [ DW_TAG_file_type ]
>>>>>> +[sroasplit-1.c]
>>>>>> +!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null,
>>>>>> +null, null} ; [ DW_TAG_subroutine_type ] [ DW_TAG_subroutine_type ]
>>>>>> +[line 0, size 0, align 0, offset 0] [from ]
>>>>>> +!7 = !{!8, !9}
>>>>>> +!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [
>>>>>> +DW_TAG_base_type ] [ DW_TAG_base_type ] [int] [line 0, size 32, align
>>>>>> +32, offset 0, enc DW_ATE_signed]
>>>>>> +!9 = !{!"0x16\00Outer\008\000\000\000\000", !1, null, !10} ; [
>>>>>> +DW_TAG_typedef ] [ DW_TAG_typedef ] [Outer] [line 8, size 0, align 0,
>>>>>> +offset 0] [from ]
>>>>>> +!10 = !{!"0x13\00\006\00256\0064\000\000\000", !1, null, null, !11,
>>>>>> +null, null, null} ; [ DW_TAG_structure_type ] [line 6, size 256, align
>>>>>> +64, offset 0] [def] [from ]
>>>>>> +!11 = !{!12}
>>>>>> +!12 = !{!"0xd\00inner\007\00256\0064\000\000", !1, !10, !13} ; [
>>>>>> +DW_TAG_member ] [inner] [line 7, size 256, align 64, offset 0] [from ]
>>>>>> +!13 = !{!"0x1\00\000\00256\0064\000\000", null, null, !14, !20, i32 0,
>>>>>> +null, null, null} ; [ DW_TAG_array_type ] [line 0, size 256, align 64,
>>>>>> +offset 0] [from Inner]
>>>>>> +!14 = !{!"0x16\00Inner\004\000\000\000\000", !1, null, !15} ; [
>>>>>> +DW_TAG_typedef ] [ DW_TAG_typedef ] [Inner] [line 4, size 0, align 0,
>>>>>> +offset 0] [from ]
>>>>>> +!15 = !{!"0x13\00\001\00128\0064\000\000\000", !1, null, null, !16,
>>>>>> +null, null, null} ; [ DW_TAG_structure_type ] [line 1, size 128, align
>>>>>> +64, offset 0] [def] [from ]
>>>>>> +!16 = !{!17, !18}
>>>>>> +!17 = !{!"0xd\00a\002\0032\0032\000\000", !1, !15, !8} ; [
>>>>>> +DW_TAG_member ] [a] [line 2, size 32, align 32, offset 0] [from int]
>>>>>> +!18 = !{!"0xd\00b\003\0064\0064\0064\000", !1, !15, !19} ; [
>>>>>> +DW_TAG_member ] [b] [line 3, size 64, align 64, offset 64] [from long
>>>>>> +int]
>>>>>> +!19 = !{!"0x24\00long int\000\0064\0064\000\000\005", null, null} ; [
>>>>>> +DW_TAG_base_type ] [ DW_TAG_base_type ] [long int] [line 0, size 64,
>>>>>> +align 64, offset 0, enc DW_ATE_signed]
>>>>>> +!20 = !{!21}
>>>>>> +!21 = !{!"0x21\000\002"}        ; [ DW_TAG_subrange_type ] [0, 1]
>>>>>> +!22 = !{i32 2, !"Dwarf Version", i32 2}
>>>>>> +!23 = !{i32 1, !"Debug Info Version", i32 2}
>>>>>> +!24 = !{!"clang version 3.5.0 "}
>>>>>> +!25 = !{!"0x101\00outer\0016777226\000", !4, !5, !9} ; [
>>>>>> +DW_TAG_arg_variable ] [ DW_TAG_arg_variable ] [outer] [line 10]
>>>>>> +!26 = !MDLocation(line: 10, scope: !4)
>>>>>> +!27 = !{!"0x100\00i1\0011\000", !4, !5, !14} ; [ DW_TAG_auto_variable ]
>>>>>> +[ DW_TAG_auto_variable ] [i1] [line 11]
>>>>>> +!28 = !MDLocation(line: 11, scope: !4)
>>>>>> +!29 = !MDLocation(line: 12, scope: !4)
>>>>>> 
>>>>>> Added: llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>> project/llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll?rev=226598&view=auto
>>>>>> ===============================================================
>>>>>> ===============
>>>>>> --- llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll (added)
>>>>>> +++ llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll Tue Jan 20 13:42:22
>>>>>> +++ 2015
>>>>>> @@ -0,0 +1,102 @@
>>>>>> +; RUN: opt %s -sroa -verify -S -o - | FileCheck %s ; ; Test that we can
>>>>>> +partial emit debug info for aggregates repeatedly ; split up by SROA.
>>>>>> +;
>>>>>> +;    // Compile with -O1
>>>>>> +;    typedef struct {
>>>>>> +;      int a;
>>>>>> +;      int b;
>>>>>> +;    } Inner;
>>>>>> +;
>>>>>> +;    typedef struct {
>>>>>> +;      Inner inner[2];
>>>>>> +;    } Outer;
>>>>>> +;
>>>>>> +;    int foo(Outer outer) {
>>>>>> +;      Inner i1 = outer.inner[1];
>>>>>> +;      return i1.a;
>>>>>> +;    }
>>>>>> +;
>>>>>> +
>>>>>> +; Verify that SROA creates a variable piece when splitting i1.
>>>>>> +; CHECK:  call void @llvm.dbg.value(metadata i64 %outer.coerce0, i64 0,
>>>>>> +metadata ![[O:[0-9]+]], metadata ![[PIECE1:[0-9]+]]), ; CHECK:  call
>>>>>> +void @llvm.dbg.value(metadata i64 %outer.coerce1, i64 0, metadata
>>>>>> +![[O]], metadata ![[PIECE2:[0-9]+]]), ; CHECK:  call void
>>>>>> + at llvm.dbg.value({{.*}}, i64 0, metadata ![[I1:[0-9]+]], metadata
>>>>>> +![[PIECE3:[0-9]+]]), ; CHECK-DAG: ![[O]] = {{.*}} [ DW_TAG_arg_variable
>>>>>> +] [outer] [line 10] ; CHECK-DAG: ![[PIECE1]] = {{.*}} [
>>>>>> +DW_TAG_expression ] [DW_OP_piece offset=0, size=8] ; CHECK-DAG:
>>>>>> +![[PIECE2]] = {{.*}} [ DW_TAG_expression ] [DW_OP_piece offset=8,
>>>>>> +size=8] ; CHECK-DAG: ![[I1]] = {{.*}} [ DW_TAG_auto_variable ] [i1]
>>>>>> +[line 11] ; CHECK-DAG: ![[PIECE3]] = {{.*}} [ DW_TAG_expression ]
>>>>>> +[DW_OP_piece offset=0, size=4]
>>>>>> +
>>>>>> +; ModuleID = 'sroasplit-2.c'
>>>>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>>> +target triple = "x86_64-apple-macosx10.9.0"
>>>>>> +
>>>>>> +%struct.Outer = type { [2 x %struct.Inner] } %struct.Inner = type {
>>>>>> +i32, i32 }
>>>>>> +
>>>>>> +; Function Attrs: nounwind ssp uwtable
>>>>>> +define i32 @foo(i64 %outer.coerce0, i64 %outer.coerce1) #0 {
>>>>>> +  %outer = alloca %struct.Outer, align 8
>>>>>> +  %i1 = alloca %struct.Inner, align 4
>>>>>> +  %1 = bitcast %struct.Outer* %outer to { i64, i64 }*
>>>>>> +  %2 = getelementptr { i64, i64 }* %1, i32 0, i32 0
>>>>>> +  store i64 %outer.coerce0, i64* %2
>>>>>> +  %3 = getelementptr { i64, i64 }* %1, i32 0, i32 1
>>>>>> +  store i64 %outer.coerce1, i64* %3
>>>>>> +  call void @llvm.dbg.declare(metadata %struct.Outer* %outer, metadata
>>>>>> +!24, metadata !2), !dbg !25
>>>>>> +  call void @llvm.dbg.declare(metadata %struct.Inner* %i1, metadata
>>>>>> +!26, metadata !2), !dbg !27
>>>>>> +  %4 = getelementptr inbounds %struct.Outer* %outer, i32 0, i32 0, !dbg
>>>>>> +!27
>>>>>> +  %5 = getelementptr inbounds [2 x %struct.Inner]* %4, i32 0, i64 1,
>>>>>> +!dbg !27
>>>>>> +  %6 = bitcast %struct.Inner* %i1 to i8*, !dbg !27
>>>>>> +  %7 = bitcast %struct.Inner* %5 to i8*, !dbg !27
>>>>>> +  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %6, i8* %7, i64 8, i32 4, i1
>>>>>> +false), !dbg !27
>>>>>> +  %8 = getelementptr inbounds %struct.Inner* %i1, i32 0, i32 0, !dbg
>>>>>> +!28
>>>>>> +  %9 = load i32* %8, align 4, !dbg !28
>>>>>> +  ret i32 %9, !dbg !28
>>>>>> +}
>>>>>> +
>>>>>> +; Function Attrs: nounwind readnone
>>>>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>>>>> +
>>>>>> +; Function Attrs: nounwind
>>>>>> +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture
>>>>>> +readonly, i64, i32, i1) #2
>>>>>> +
>>>>>> +attributes #0 = { nounwind ssp uwtable "no-frame-pointer-elim"="true" }
>>>>>> +attributes #1 = { nounwind readnone } attributes #2 = { nounwind }
>>>>>> +
>>>>>> +!llvm.dbg.cu = !{!0}
>>>>>> +!llvm.module.flags = !{!21, !22}
>>>>>> +!llvm.ident = !{!23}
>>>>>> +
>>>>>> +!0 = !{!"0x11\0012\00clang version 3.5.0 \000\00\000\00\001", !1, !2,
>>>>>> +!2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [ DW_TAG_compile_unit ]
>>>>>> +[sroasplit-2.c] [DW_LANG_C99]
>>>>>> +!1 = !{!"sroasplit-2.c", !""}
>>>>>> +!2 = !{}
>>>>>> +!3 = !{!4}
>>>>>> +!4 = !{!"0x2e\00foo\00foo\00\0010\000\001\000\006\00256\000\0010", !1,
>>>>>> +!5, !6, null, i32 (i64, i64)* @foo, null, null, !2} ; [
>>>>>> +DW_TAG_subprogram ] [ DW_TAG_subprogram ] [line 10] [def] [foo]
>>>>>> +!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [ DW_TAG_file_type ]
>>>>>> +[sroasplit-2.c]
>>>>>> +!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null,
>>>>>> +null, null} ; [ DW_TAG_subroutine_type ] [ DW_TAG_subroutine_type ]
>>>>>> +[line 0, size 0, align 0, offset 0] [from ]
>>>>>> +!7 = !{!8, !9}
>>>>>> +!8 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [
>>>>>> +DW_TAG_base_type ] [ DW_TAG_base_type ] [int] [line 0, size 32, align
>>>>>> +32, offset 0, enc DW_ATE_signed]
>>>>>> +!9 = !{!"0x16\00Outer\008\000\000\000\000", !1, null, !10} ; [
>>>>>> +DW_TAG_typedef ] [ DW_TAG_typedef ] [Outer] [line 8, size 0, align 0,
>>>>>> +offset 0] [from ]
>>>>>> +!10 = !{!"0x13\00\006\00128\0032\000\000\000", !1, null, null, !11,
>>>>>> +null, null, null} ; [ DW_TAG_structure_type ] [line 6, size 128, align
>>>>>> +32, offset 0] [def] [from ]
>>>>>> +!11 = !{!12}
>>>>>> +!12 = !{!"0xd\00inner\007\00128\0032\000\000", !1, !10, !13} ; [
>>>>>> +DW_TAG_member ] [inner] [line 7, size 128, align 32, offset 0] [from ]
>>>>>> +!13 = !{!"0x1\00\000\00128\0032\000\000", null, null, !14, !19, i32 0,
>>>>>> +null, null, null} ; [ DW_TAG_array_type ] [line 0, size 128, align 32,
>>>>>> +offset 0] [from Inner]
>>>>>> +!14 = !{!"0x16\00Inner\004\000\000\000\000", !1, null, !15} ; [
>>>>>> +DW_TAG_typedef ] [ DW_TAG_typedef ] [Inner] [line 4, size 0, align 0,
>>>>>> +offset 0] [from ]
>>>>>> +!15 = !{!"0x13\00\001\0064\0032\000\000\000", !1, null, null, !16,
>>>>>> +null, null, null} ; [ DW_TAG_structure_type ] [line 1, size 64, align
>>>>>> +32, offset 0] [def] [from ]
>>>>>> +!16 = !{!17, !18}
>>>>>> +!17 = !{!"0xd\00a\002\0032\0032\000\000", !1, !15, !8} ; [
>>>>>> +DW_TAG_member ] [a] [line 2, size 32, align 32, offset 0] [from int]
>>>>>> +!18 = !{!"0xd\00b\003\0032\0032\0032\000", !1, !15, !8} ; [
>>>>>> +DW_TAG_member ] [b] [line 3, size 32, align 32, offset 32] [from int]
>>>>>> +!19 = !{!20}
>>>>>> +!20 = !{!"0x21\000\002"}        ; [ DW_TAG_subrange_type ] [0, 1]
>>>>>> +!21 = !{i32 2, !"Dwarf Version", i32 2}
>>>>>> +!22 = !{i32 1, !"Debug Info Version", i32 2}
>>>>>> +!23 = !{!"clang version 3.5.0 "}
>>>>>> +!24 = !{!"0x101\00outer\0016777226\000", !4, !5, !9} ; [
>>>>>> +DW_TAG_arg_variable ] [ DW_TAG_arg_variable ] [outer] [line 10]
>>>>>> +!25 = !MDLocation(line: 10, scope: !4)
>>>>>> +!26 = !{!"0x100\00i1\0011\000", !4, !5, !14} ; [ DW_TAG_auto_variable ]
>>>>>> +[ DW_TAG_auto_variable ] [i1] [line 11]
>>>>>> +!27 = !MDLocation(line: 11, scope: !4)
>>>>>> +!28 = !MDLocation(line: 12, scope: !4)
>>>>>> 
>>>>>> Added: llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>> project/llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll?rev=226598&view=auto
>>>>>> ===============================================================
>>>>>> ===============
>>>>>> --- llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll (added)
>>>>>> +++ llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll Tue Jan 20 13:42:22
>>>>>> +++ 2015
>>>>>> @@ -0,0 +1,63 @@
>>>>>> +; RUN: opt %s -sroa -verify -S -o - | FileCheck %s ; ModuleID =
>>>>>> +'test.c'
>>>>>> +; Test that SROA updates the debug info correctly if an alloca was
>>>>>> +rewritten but ; not partitioned into multiple allocas.
>>>>>> +;
>>>>>> +; CHECK: call void @llvm.dbg.value(metadata float %s.coerce, i64 0,
>>>>>> +metadata ![[VAR:[0-9]+]], metadata ![[EXPR:[0-9]+]]) ; CHECK: ![[VAR]]
>>>>>> += {{.*}} [ DW_TAG_arg_variable ] [s] [line 3] ; CHECK: ![[EXPR]] =
>>>>>> +{{.*}} [ DW_TAG_expression ] ; CHECK-NOT: DW_OP_piece
>>>>>> +
>>>>>> +;
>>>>>> +; struct S { float f; };
>>>>>> +;
>>>>>> +; float foo(struct S s) {
>>>>>> +;   return s.f;
>>>>>> +; }
>>>>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>>> +target triple = "x86_64-apple-macosx10.10.0"
>>>>>> +
>>>>>> +%struct.S = type { float }
>>>>>> +
>>>>>> +; Function Attrs: nounwind ssp uwtable
>>>>>> +define float @foo(float %s.coerce) #0 {
>>>>>> +entry:
>>>>>> +  %s = alloca %struct.S, align 4
>>>>>> +  %coerce.dive = getelementptr %struct.S* %s, i32 0, i32 0
>>>>>> +  store float %s.coerce, float* %coerce.dive, align 1
>>>>>> +  call void @llvm.dbg.declare(metadata %struct.S* %s, metadata !16,
>>>>>> +metadata !17), !dbg !18
>>>>>> +  %f = getelementptr inbounds %struct.S* %s, i32 0, i32 0, !dbg !19
>>>>>> +  %0 = load float* %f, align 4, !dbg !19
>>>>>> +  ret float %0, !dbg !19
>>>>>> +}
>>>>>> +
>>>>>> +; Function Attrs: nounwind readnone
>>>>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>>>>> +
>>>>>> +attributes #0 = { nounwind ssp uwtable } attributes #1 = { nounwind
>>>>>> +readnone }
>>>>>> +
>>>>>> +!llvm.dbg.cu = !{!0}
>>>>>> +!llvm.module.flags = !{!12, !13, !14}
>>>>>> +!llvm.ident = !{!15}
>>>>>> +
>>>>>> +!0 = !{!"0x11\0012\00clang version 3.6.0 \000\00\000\00\001", !1, !2,
>>>>>> +!2, !3, !2, !2} ; [ DW_TAG_compile_unit ]
>>>>>> +[/Volumes/Data/llvm/_build.ninja.debug/test.c] [DW_LANG_C99]
>>>>>> +!1 = !{!"test.c", !"/Volumes/Data/llvm/_build.ninja.debug"}
>>>>>> +!2 = !{}
>>>>>> +!3 = !{!4}
>>>>>> +!4
>>>>>> = !{!"0x2e\00foo\00foo\00\003\000\001\000\000\00256\000\003", !1, !5, !6,
>>>>>> null, float (float)* @foo, null, null, !2} ; [ DW_TAG_subprogram ] [line
>>>> 3] [def]
>>>>>> [foo]
>>>>>> +!5 = !{!"0x29", !1}                               ; [ DW_TAG_file_type ]
>>>>>> [/Volumes/Data/llvm/_build.ninja.debug/test.c]
>>>>>> +!6 = !{!"0x15\00\000\000\000\000\000\000", null, null, null, !7, null,
>>>>>> +null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0,
>>>>>> +offset 0] [from ]
>>>>>> +!7 = !{!8, !9}
>>>>>> +!8 = !{!"0x24\00float\000\0032\0032\000\000\004", null, null} ; [
>>>>>> +DW_TAG_base_type ] [float] [line 0, size 32, align 32, offset 0, enc
>>>>>> +DW_ATE_float]
>>>>>> +!9 = !{!"0x13\00S\001\0032\0032\000\000\000", !1, null, null, !10,
>>>>>> +null, null, null} ; [ DW_TAG_structure_type ] [S] [line 1, size 32,
>>>>>> +align 32, offset 0] [def] [from ]
>>>>>> +!10 = !{!11}
>>>>>> +!11 = !{!"0xd\00f\001\0032\0032\000\000", !1, !9, !8} ; [ DW_TAG_member
>>>>>> +] [f] [line 1, size 32, align 32, offset 0] [from float]
>>>>>> +!12 = !{i32 2, !"Dwarf Version", i32 2}
>>>>>> +!13 = !{i32 2, !"Debug Info Version", i32 2}
>>>>>> +!14 = !{i32 1, !"PIC Level", i32 2}
>>>>>> +!15 = !{!"clang version 3.6.0 "}
>>>>>> +!16 = !{!"0x101\00s\0016777219\000", !4, !5, !9}  ; [ DW_TAG_arg_variable
>>>> ]
>>>>>> [s] [line 3]
>>>>>> +!17 = !{!"0x102"}                                 ; [ DW_TAG_expression ]
>>>>>> +!18 = !MDLocation(line: 3, column: 20, scope: !4)
>>>>>> +!19 = !MDLocation(line: 4, column: 2, scope: !4)
>>>>>> 
>>>>>> 
>>>>>> _______________________________________________
>>>>>> llvm-commits mailing list
>>>>>> llvm-commits at cs.uiuc.edu
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>> 
>>>> 
>>>> 
>>>> 
>>> 
>>> 
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>> 
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 194 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150123/477fe0cf/attachment.sig>


More information about the llvm-commits mailing list