2016-01-20 124 views
1

我调试了两天!搜索官方文档和谷歌后,找不到任何原因或信息。在LLVM中调用CreatePHI()时出错

是LLVM的bug吗?请帮帮我。

(LLVM版本:3.7.1)

错误信息:

Assertion failed: HasHungOffUses && "alloc must have hung off uses", , file I:\GitHub\Def\llvm\lib\IR\User.cpp, line 44 

代码:

see the screenshot of call stack

Value* ASTIf::codegen(Gen & gen) 
{ 
    // if 
    Value *v_ret(nullptr); 
    auto *thefunc = gen.builder.GetInsertBlock()->getParent(); 

    Value *v_cond = cond->codegen(gen); 
    auto *b_then = BasicBlock::Create(gen.context, "then", thefunc); 
    auto *b_else = BasicBlock::Create(gen.context, "else", thefunc); 
    auto *b_merge = BasicBlock::Create(gen.context, "ifcont", thefunc); 

    // 跳转分支 
    gen.builder.CreateCondBr(v_cond, b_then, b_else); 

    // then block 
    gen.builder.SetInsertPoint(b_then); 
    Value *v_then = pthen->codegen(gen); 
    gen.builder.CreateBr(b_merge); 
    b_then = gen.builder.GetInsertBlock(); 

    // else block 
    gen.builder.SetInsertPoint(b_else); 
    Value *v_else = pelse ? pelse->codegen(gen) : nullptr; 
    gen.builder.CreateBr(b_merge); 
    b_else = gen.builder.GetInsertBlock(); 

    // merge block 
    gen.builder.SetInsertPoint(b_merge); 
    // if error: HasHungOffUses 
    if (canphi) { 

     PHINode *phi = gen.builder.CreatePHI( ////////// error line ///////// 
      v_then->getType(), 2, "iftmp"); 
     phi->addIncoming(v_then, b_then); 
     phi->addIncoming(v_else, b_else); 
     v_ret = phi; 
    } 

    return v_ret; 
} 

征求意见的通知加调用堆栈

+0

我想我们需要知道触发该断言的条件是什么?什么是callstack? –

+0

什么是你的情况下的'pelse'?我认为给addIncoming一个nullptr不是一个好主意。 –

+0

看着代码使用强大的接缝我,也许你有堆腐败在你的非llvm代码的某处。 –

回答

0

请关闭VS的sdl。 断言检查由运算符new设置的位标志HasHungOffUses,当sdl打开时可能会覆盖它。

gen.builder.CreatePHI调用User :: operator new(size_t Size),它在分配的内存中分配了HasHungOffUses但未初始化。它应该保持它在ctor调用之前的状态。下面

代码来自LLVM SVN 266960(3.9.0开发中)

void *User::operator new(size_t Size) { 
    // Allocate space for a single Use* 
    void *Storage = ::operator new(Size + sizeof(Use *)); 
    Use **HungOffOperandList = static_cast<Use **>(Storage); 
    User *Obj = reinterpret_cast<User *>(HungOffOperandList + 1); 
    Obj->NumUserOperands = 0; 
    Obj->HasHungOffUses = true; 
    Obj->HasDescriptor = false; 
    *HungOffOperandList = nullptr; 
    return Obj; 
} 

通知Obj-> HasHungOffUses = TRUE;

然后谈到PHINode的男星

explicit PHINode(Type *Ty, unsigned NumReservedValues, 
      const Twine &NameStr = "", 
      Instruction *InsertBefore = nullptr) 
    : Instruction(Ty, Instruction::PHI, nullptr, 0, InsertBefore), 
    ReservedSpace(NumReservedValues) { 
setName(NameStr); 
allocHungoffUses(ReservedSpace); 
} 

void User::allocHungoffUses(unsigned N, bool IsPhi) { 
assert(HasHungOffUses && "alloc must have hung off uses"); 
static_assert(AlignOf<Use>::Alignment >= AlignOf<Use::UserRef>::Alignment, 
       "Alignment is insufficient for 'hung-off-uses' pieces"); 
static_assert(AlignOf<Use::UserRef>::Alignment >= 
       AlignOf<BasicBlock *>::Alignment, 
       "Alignment is insufficient for 'hung-off-uses' pieces"); 
// Allocate the array of Uses, followed by a pointer (with bottom bit set) to 
// the User. 
size_t size = N * sizeof(Use) + sizeof(Use::UserRef); 
if (IsPhi) 
    size += N * sizeof(BasicBlock *); 
Use *Begin = static_cast<Use*>(::operator new(size)); 
Use *End = Begin + N; 
(void) new(End) Use::UserRef(const_cast<User*>(this), 1); 
setOperandList(Use::initTags(Begin, End)); 

} 

如果STL开启时,由运新分配的内存似乎男星之前memset的为0,这给HasHungOffUses一个错误的值,所以断言失败。