c++ - 在 LLVM 中调用 CreatePHI() 时出错

标签 c++ llvm

我调试了两天!查了官方文档和google也没找到任何原因或信息。

这是 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

代码:

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;
}

添加评论通知的调用堆栈:

see the screenshot of call stack

最佳答案

请关闭 VS 的 SDL 检查(配置属性 -> C/C++ -> 常规 -> SDL 检查)。 该断言检查由 operator 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的ctor

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));

}

如果sdl开启,op-new分配的内存似乎在ctor之前memset为0,这给了HasHungOffUses一个false值,所以断言失败.

关于c++ - 在 LLVM 中调用 CreatePHI() 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34892732/

相关文章:

c++ - 什么是 undefined reference /未解析的外部符号错误以及如何修复它?

c++ - 如何将 Vulkan 与 MinGW 一起使用? (R_X86_64_32 错误)

c++ - 如何检查 llvm callInst 是否包含位播?

ios - LLVM、GCC 4.2 和 Apple LLVM 编译器 3.1 之间的区别

llvm - 在 centos 7 上安装 LLVM/Clang 6+

c++ - 如何组合许多连续图像来模拟逼真的运动模糊?

C++ - 从结束地址获取函数的起始地址/获取函数的大小

c++ - boost::asio::io_service 在 win_mutex 锁中崩溃

c++ - LLVM builder::GetInsertBlock,这个函数的作用是什么?

c++ - LLVM:如何将 IR 写入文件并运行它?