Problems in the transformation from LLVM IR code to x86-64 executable file (original) (raw)

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

微信图片_20230527140052

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!