diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -819,11 +819,15 @@ break; case WorklistEntry::MapAppendingVar: { unsigned PrefixSize = AppendingInits.size() - E.AppendingGVNumNewMembers; + // mapAppendingVariable call can change AppendingInits if initalizer for + // the variable depends on another appending global, because of that inits + // need to be extracted and updated before the call. + SmallVector NewInits( + drop_begin(AppendingInits, PrefixSize)); + AppendingInits.resize(PrefixSize); mapAppendingVariable(*E.Data.AppendingGV.GV, E.Data.AppendingGV.InitPrefix, - E.AppendingGVIsOldCtorDtor, - makeArrayRef(AppendingInits).slice(PrefixSize)); - AppendingInits.resize(PrefixSize); + E.AppendingGVIsOldCtorDtor, makeArrayRef(NewInits)); break; } case WorklistEntry::MapGlobalIndirectSymbol: diff --git a/llvm/test/Linker/appending-global-crash.ll b/llvm/test/Linker/appending-global-crash.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Linker/appending-global-crash.ll @@ -0,0 +1,10 @@ +; RUN: llvm-link %s -S -o - | FileCheck %s + +; Check that llvm-link does not crash when materializing appending global with +; initializer depending on another appending global. + +; CHECK-DAG: @use = appending global [1 x i8*] [i8* bitcast ([1 x i8*]* @var to i8*)] +; CHECK-DAG: @var = appending global [1 x i8*] undef + +@use = appending global [1 x i8*] [i8* bitcast ([1 x i8*]* @var to i8*)] +@var = appending global [1 x i8*] undef