<badref> 当对结构类型使用 CallInst::CreateMalloc 时

<badref> when using CallInst::CreateMalloc for a struct type

我正在尝试为类似于以下 C++ 代码的代码(使用玩具语言)生成 LLVM IR:

struct test {
  int a;
  int b;
  int c;
};
int main() {
  tempVar *a;
  a = new test();
}

不幸的是,当我 运行 verifyModule 时,我收到以下错误消息:

Instruction referencing instruction not embedded in a basic block!
  %malloccall = tail call i8* @malloc(i64 mul nuw (i64 ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64), i64 3))
  <badref> = bitcast i8* %malloccall to %test*

以下 MWE 重现了该问题:

#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <vector>
using namespace llvm;

std::map<std::string, StructType *> allocatedClasses;
std::map<std::string, std::vector<Type *>> classSizes;

static LLVMContext TheContext;
static IRBuilder<> Builder(TheContext);
static std::map<std::string, AllocaInst *> NamedValues;

int main() {
  static std::unique_ptr<Module> TheModule;

  TheModule = std::make_unique<Module>("inputFile", TheContext);

  allocatedClasses["test"] = StructType::create(TheContext, "test");
  classSizes["test"] = std::vector<Type *>(3, Type::getInt32Ty(TheContext));
  allocatedClasses["test"]->setBody(classSizes["test"]);

  FunctionType *mainType = FunctionType::get(Builder.getInt32Ty(), false);
  Function *main = Function::Create(mainType, Function::ExternalLinkage, "main",
                                    TheModule.get());
  BasicBlock *entry = BasicBlock::Create(TheContext, "entry", main);
  Builder.SetInsertPoint(entry);

  std::string tV = "tempVar";
  NamedValues[tV] = Builder.CreateAlloca(
      PointerType::get(allocatedClasses["test"], 0), nullptr, tV);
  auto typeSize = ConstantExpr::getSizeOf(allocatedClasses["test"]);
  typeSize =
      ConstantExpr::getTruncOrBitCast(typeSize, Type::getInt64Ty(TheContext));

  CallInst::CreateMalloc(Builder.GetInsertBlock(), Type::getInt64Ty(TheContext),
                         allocatedClasses["test"], typeSize, nullptr, nullptr,
                         "");
  Builder.CreateRet(ConstantInt::get(TheContext, APInt(32, 0)));

  TheModule->print(outs(), nullptr);
  Module *test = TheModule.get();
  verifyModule(*test, &errs());
}

我用 clang++ `llvm-config --cxxflags --ldflags --system-libs --libs all` -g ex.cpp,在 x86 上使用 clang 版本 10.0.0-4ubuntu1。执行时,程序输出:

; ModuleID = 'inputFile'
source_filename = "inputFile"

%test = type { i32, i32, i32 }

define i32 @main() {
entry:
  %tempVar = alloca %test*
  %malloccall = tail call i8* @malloc(i64 mul nuw (i64 ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64), i64 3))
  ret i32 0
}

declare noalias i8* @malloc(i64)

和上面的错误信息。

我做错了什么?

documentation for the function you call 说“注意:此函数不会将位广播添加到基本块,这是调用者的责任。”

我不知道为什么,但来电者是你。