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

Adrian Prantl aprantl at apple.com
Thu Jan 8 08:56:01 PST 2015


> On Jan 7, 2015, at 6:19 PM, Alexey Samsonov <vonosmas at gmail.com> wrote:
> 
> Right, I will update this thread once I scrape the file from the bot and creduce it (should be soon).

Thanks; I found a fairly short reproduction meanwhile:

// -O2
struct B {
  long a, b, c;
  void operator!=(B);
};
long fn3();
static B fn1() {
  B i;
  i.c = fn3();
  return i;
}
void fn2() {
  B b, e = fn1();
  b != e;
}

-- adrian

> 
> On Wed, Jan 7, 2015 at 2:15 PM, Adrian Prantl <aprantl at apple.com <mailto:aprantl at apple.com>> wrote:
>> On Jan 7, 2015, at 2:10 PM, Alexey Samsonov <vonosmas at gmail.com <mailto:vonosmas at gmail.com>> wrote:
>> 
>> I still observe a crash, this time on our internal buildbot, and not on LLVM sources.
>> This is a heads up, I will work on reduction/reproducer.
> 
> Thanks! This is actually a different assertion as last time, so this is going to be quite interesting. For starters, the type of the variable and the IR around the dbg.value() might be enough to understand what’s going on.
> 
> -- adrian
> 
>> 
>> clang: slave/linux/build/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:1687: void llvm::DwarfDebug::emitLocPieces(llvm::ByteStreamer&, const DITypeIdentifierMap&, llvm::ArrayRef<llvm::DebugLocEntry::Value>): Assertion `!Var.isIndirect() && "indirect address for piece"' failed.
>> #0 0x2842782 llvm::sys::PrintStackTrace(_IO_FILE*) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x2842782)
>> #1 0x2840911 SignalHandler(int) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x2840911)
>> #2 0x2b90dd1cc340 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10340)
>> #3 0x2b90de05dbb9 gsignal /build/buildd/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0
>> #4 0x2b90de060fc8 abort /build/buildd/eglibc-2.19/stdlib/abort.c:91:0
>> #5 0x2b90de056a76 __assert_fail_base /build/buildd/eglibc-2.19/assert/assert.c:92:0
>> #6 0x2b90de056b22 (/lib/x86_64-linux-gnu/libc.so.6+0x2fb22)
>> #7 0x206b660 llvm::DwarfDebug::emitLocPieces(llvm::ByteStreamer&, llvm::DenseMap<llvm::MDString const*, llvm::MDNode*, llvm::DenseMapInfo<llvm::MDString const*>, llvm::detail::DenseMapPair<llvm::MDString const*, llvm::MDNode*> > const&, llvm::ArrayRef<llvm::DebugLocEntry::Value>) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x206b660)
>> #8 0x206b8b6 llvm::DwarfDebug::emitDebugLocEntry(llvm::ByteStreamer&, llvm::DebugLocEntry const&) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x206b8b6)
>> #9 0x206b9b4 llvm::DwarfDebug::emitDebugLocEntryLocation(llvm::DebugLocEntry const&) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x206b9b4)
>> #10 0x206baba llvm::DwarfDebug::emitDebugLoc() (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x206baba)
>> #11 0x2074a96 llvm::DwarfDebug::endModule() (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x2074a96)
>> #12 0x2058cf0 llvm::AsmPrinter::doFinalization(llvm::Module&) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x2058cf0)
>> #13 0x27c257b llvm::FPPassManager::doFinalization(llvm::Module&) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x27c257b)
>> #14 0x27cbd27 llvm::legacy::PassManagerImpl::run(llvm::Module&) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x27cbd27)
>> #15 0xadc027 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::raw_ostream*) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0xadc027)
>> #16 0xace2d6 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0xace2d6)
>> #17 0xc7d633 clang::ParseAST(clang::Sema&, bool, bool) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0xc7d633)
>> #18 0xacefee clang::CodeGenAction::ExecuteAction() (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0xacefee)
>> #19 0x92b976 clang::FrontendAction::Execute() (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x92b976)
>> #20 0x908bd9 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x908bd9)
>> #21 0x8f0cae clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x8f0cae)
>> #22 0x8e9198 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x8e9198)
>> #23 0x8c4b4b main (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x8c4b4b)
>> #24 0x2b90de048ec5 __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:321:0
>> #25 0x8e7efa _start (slave/linux/build/llvm-build/Release+Asserts/bin/clang+0x8e7efa)
>> 
>> 
>> On Wed, Jan 7, 2015 at 12:52 PM, Adrian Prantl <aprantl at apple.com <mailto:aprantl at apple.com>> wrote:
>> Author: adrian
>> Date: Wed Jan  7 14:52:22 2015
>> New Revision: 225379
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=225379&view=rev <http://llvm.org/viewvc/llvm-project?rev=225379&view=rev>
>> Log:
>> Reapply: Teach SROA how to update debug info for fragmented variables.
>> 
>> The two buildbot failures were addressed in LLVM r225378 and CFE r225359.
>> 
>> This rapplies commit 225272 without modifications.
>> 
>> 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=225379&r1=225378&r2=225379&view=diff <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=225379&r1=225378&r2=225379&view=diff>
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Scalar/SROA.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp Wed Jan  7 14:52:22 2015
>> @@ -1240,6 +1240,10 @@ class SROA : public FunctionPass {
>>    /// currently in the promotable queue.
>>    SetVector<SelectInst *, SmallVector<SelectInst *, 2>> SpeculatableSelects;
>> 
>> +  /// Debug intrinsics do not show up as regular uses in the
>> +  /// IR. This side-table holds the missing use edges.
>> +  DenseMap<AllocaInst *, DbgDeclareInst *> DbgDeclares;
>> +
>>  public:
>>    SROA(bool RequiresDomTree = true)
>>        : FunctionPass(ID), RequiresDomTree(RequiresDomTree), C(nullptr),
>> @@ -1257,8 +1261,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 +3968,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 +4007,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 +4103,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 +4142,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 +4167,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 = DbgDeclares.lookup(&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);
>> +      Instruction *NewDDI = DIB.insertDeclare(Piece.Alloca, Var, Expr, &AI);
>> +      NewDDI->setDebugLoc(DbgDecl->getDebugLoc());
>> +      assert((!DbgDeclares.count(Piece.Alloca) ||
>> +              DbgDeclares[Piece.Alloca] == cast<DbgDeclareInst>(NewDDI)
>> +             ) && "alloca already described");
>> +      DbgDeclares.insert(std::make_pair(Piece.Alloca,
>> +                                        cast<DbgDeclareInst>(NewDDI)));
>> +    }
>> +  }
>>    return Changed;
>>  }
>> 
>> @@ -4258,8 +4300,13 @@ 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 = DbgDeclares.lookup(AI)) {
>> +        DbgDecl->eraseFromParent();
>> +        DbgDeclares.erase(AI);
>> +      }
>> +    }
>> 
>>      ++NumDeleted;
>>      I->eraseFromParent();
>> @@ -4374,11 +4421,16 @@ bool SROA::runOnFunction(Function &F) {
>>    DT = DTWP ? &DTWP->getDomTree() : nullptr;
>>    AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
>> 
>> +  DbgDeclares.clear();
>>    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);
>> +    else if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I))
>> +      if (auto AI = dyn_cast_or_null<AllocaInst>(DDI->getAddress()))
>> +        DbgDeclares.insert(std::make_pair(AI, DDI));
>> +  }
>> 
>>    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=225379&r1=225378&r2=225379&view=diff <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/array2.ll?rev=225379&r1=225378&r2=225379&view=diff>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/X86/array2.ll (original)
>> +++ llvm/trunk/test/DebugInfo/X86/array2.ll Wed Jan  7 14:52: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=225379&view=auto <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll?rev=225379&view=auto>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll (added)
>> +++ llvm/trunk/test/DebugInfo/X86/sroasplit-1.ll Wed Jan  7 14:52: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 @llvm.dbg.declare(metadata [12 x i8]* %[[I1]], metadata ![[VAR:[0-9]+]], metadata ![[PIECE1:[0-9]+]])
>> +; CHECK: call void @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 <http://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 = !{i32 10, i32 0, !4, null}
>> +!27 = !{!"0x100\00i1\0011\000", !4, !5, !14} ; [ DW_TAG_auto_variable ] [ DW_TAG_auto_variable ] [i1] [line 11]
>> +!28 = !{i32 11, i32 0, !4, null}
>> +!29 = !{i32 12, i32 0, !4, null}
>> 
>> 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=225379&view=auto <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll?rev=225379&view=auto>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll (added)
>> +++ llvm/trunk/test/DebugInfo/X86/sroasplit-2.ll Wed Jan  7 14:52: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 @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 <http://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 = !{i32 10, i32 0, !4, null}
>> +!26 = !{!"0x100\00i1\0011\000", !4, !5, !14} ; [ DW_TAG_auto_variable ] [ DW_TAG_auto_variable ] [i1] [line 11]
>> +!27 = !{i32 11, i32 0, !4, null}
>> +!28 = !{i32 12, i32 0, !4, null}
>> 
>> 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=225379&view=auto <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll?rev=225379&view=auto>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll (added)
>> +++ llvm/trunk/test/DebugInfo/X86/sroasplit-3.ll Wed Jan  7 14:52: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 <http://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 = !{i32 3, i32 20, !4, null}
>> +!19 = !{i32 4, i32 2, !4, null}
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu <mailto:llvm-commits at cs.uiuc.edu>
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits <http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits>
>> 
>> 
>> 
>> -- 
>> Alexey Samsonov
>> vonosmas at gmail.com <mailto:vonosmas at gmail.com>
> 
> 
> 
> -- 
> Alexey Samsonov
> vonosmas at gmail.com <mailto:vonosmas at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150108/3af7ac52/attachment.html>


More information about the llvm-commits mailing list