How to get data stored in memory pointed to by an llvm pointer

  alloca, armv7, c++, lifting, llvm

I am building a lifter that translates armv7m assembly instructions into llvm IR. A sample of my C++ code is:

IRBuilder<> builder(TheContext); //line 0

llvm::ConstantInt* I_0 = llvm::ConstantInt::get(TheContext, llvm::APInt(/nbits/32, 0, true)); //line 1

V = builder.CreateAlloca(Type::getInt32Ty(TheContext), nullptr, "V"); //line 2

Value* s3 = builder.CreateStore(I_0, V, /isVolatile=/false); //line 3

Value* loaded_V = builder.CreateLoad(V); //line 4

Value* result_V = builder.CreateICmpEQ(I_0, loaded_V); //line 5

result_V->print(errs()); //line 6

The result I get is:

%22 = icmp eq i32 0, %18

The result I want is:

i1 true

So my question is, even though I stored an Immediate value of 0 at the memory location pointed to by the ptr V in line 3. When I load this value from memory using memory load from ptr V in line 4 and then compare it to an immediate value of 0 in the icmpEq in line 5, why dont I get a true result in line 6 but instead it seems that the loaded_V doesnt evaluate to an immediate value of 0, its just represented by the variable %18.

1- How can I get the value stored inside the llvm variable %18 ?.

2- Is there a way to get the data stored in the memory address pointed to by the ptr V directly without having to load.

As you can see in another sample of my code where I am trying to translate the assembly instruction add DST, SRC1, SRC2 to an equivalent llvm IR:

            llvm::Value* SRC1 = builder.CreateAlloca(Type::getInt32Ty(TheContext), nullptr);
        
            llvm::Value* SRC2 = builder.CreateAlloca(Type::getInt32Ty(TheContext), nullptr);
            
            llvm::Value* s = builder.CreateStore(register1_val, SRC1,  /*isVolatile=*/false);
            
            llvm::Value* s2 = builder.CreateStore(register2_val, SRC2,  /*isVolatile=*/false);
            
            llvm::Value* LHS = builder.CreateLoad(SRC1, register1);
            
            llvm::Value* RHS = builder.CreateLoad(SRC2, register2);
            
            llvm::Value* add_ll = builder.CreateAdd(LHS, RHS, output_register);

            llvm::Value* DST = builder.CreateAlloca(Type::getInt32Ty(TheContext), nullptr);

            llvm::Value* s3 = builder.CreateStore(add_ll, DST,  /*isVolatile=*/false);

I represent an operand as a ptr to a memory address by using an alloca instruction and then loading from that memory address when using the operand in an llvm instruction creation.

3- Is there perhaps a better way of representing operands (virtual registers?!, instead of ptrs to memory).

Source: Windows Questions C++

LEAVE A COMMENT