Hello, I am a llvm beginner. I recently try to run my own toy-c-compiler project but the executable file has unexpected results.
Here are my test codes, LLVM IR codes and assembly codes.
TEST CODE
extern void printi(int n);
extern void scanfi(int* intaddr);
int main(){
int a = 1;
int b = 2;
if(a<b)
{
a=a+1;
printi(a);
}
else{
b=b+1;
}
return 0;
}
LLVM IR CODE
define i32 @main() {
entry:
%a = alloca i32, align 4, addrspace(4)
store i32 1, ptr addrspace(4) %a, align 4
%b = alloca i32, align 4, addrspace(4)
store i32 2, ptr addrspace(4) %b, align 4
%a1 = load i32, ptr addrspace(4) %a, align 4
%b2 = load i32, ptr addrspace(4) %b, align 4
%lttmp = icmp slt i32 %a1, %b2
br i1 %lttmp, label %then, label %else
then: ; preds = %entry
%a3 = load i32, ptr addrspace(4) %a, align 4
store i32 %a3, ptr addrspace(4) %a, align 4
%addtmp = add i32 %a3, 1
%a4 = load i32, ptr addrspace(4) %a, align 4
%calltmp = call void @printi(i32 %a4)
br label %ifcont
else: ; preds = %entry
%b5 = load i32, ptr addrspace(4) %b, align 4
store i32 %b5, ptr addrspace(4) %b, align 4
%addtmp6 = add i32 %b5, 1
br label %ifcont
ifcont: ; preds = %else, %then
ret i32 0
}
ASSEMBLY CODE
And here are my codes to generate executable files.
llvm::GenericValue CodeContext::runCode() {
llvm::GenericValue err;
err.IntVal= llvm::APInt(32, 1);
std::string outputFilename = "output.o";
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargets();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmParsers();
llvm::InitializeAllAsmPrinters();
auto TargetTriple = llvm::Triple::normalize(LLVMGetDefaultTargetTriple());
std::string error;
auto target = llvm::TargetRegistry::lookupTarget(TargetTriple, error);
if (!target) {
llvm::errs() << error;
std::cout << error<< std::endl;
return err;
}
auto cpu = "generic";
auto features = "";
llvm::TargetOptions opt;
auto rm = llvm::Optional<llvm::Reloc::Model>();
auto targetMachine = target->createTargetMachine(TargetTriple, cpu, features, opt, rm);
llvm::legacy::PassManager pass;
auto fileType = llvm::CGFT_ObjectFile;
std::string filename(outputFilename);
std::error_code EC;
llvm::raw_fd_ostream dest(filename, EC, llvm::sys::fs::OF_None);
if (targetMachine->addPassesToEmitFile(pass, dest, nullptr, fileType)) {
llvm::errs() << "TargetMachine can't emit a file of this type";
std::cout << "TargetMachine can't emit a file of this type"<< std::endl;
return err;
}
pass.run(*_module);
dest.flush();
llvm::outs() << "Object file written to " << outputFilename << "\n";
llvm::ExecutionEngine* EE = llvm::EngineBuilder(std::unique_ptr<llvm::Module>(_module)).create();
EE->finalizeObject();
std::vector<llvm::GenericValue> noargs;
llvm::GenericValue v = EE->runFunction(_module->getFunction("main"), noargs);
std::cout << "Running\n";
return v;
}
And my executable file runs like this.
Object file written to output.o
1
Running
gcc -o program output.o cfuncs.o
./program
1
It seems that the executable file does not do the “a=a+1” step. I don’t know where the problem is and I want to find a solution to debug my codes. Thank you in advance!