<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 说“注意:此函数不会将位广播添加到基本块,这是调用者的责任。”
我不知道为什么,但来电者是你。
我正在尝试为类似于以下 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 说“注意:此函数不会将位广播添加到基本块,这是调用者的责任。”
我不知道为什么,但来电者是你。