LLVM: Very simple question

Hi, guys. I’m a newbie to LLVM and have a very simple question.

Which instructions should I use (in terms of IRBuilder calls) to allocate an array of bytes in stack (alloca?), then to work with it (from a given offset) as with integer (bitcast?). I mean something like that:

unsigned char var[8];
unsigned int offset = 3;
int val = (int)(&var+offset); /* read /
(int)(&var+offset) = 12; /
write */

Yes, I can convert the code above to assembly language using LLVM online demo, but how can I perform that programmatically using IRBuilder?

Are there some LLVM code examples less trivial than Kaleidoscope?

Thanks in advance.

Hi,

Have you tried using the “Show LLVM C++ API code” option on the online demo?

I could explain what to do to you, but you might understand it better with the interactive example. For your code snippet, it spits out

… snip …

AllocaInst* ptr_retval = new AllocaInst(IntegerType::get(mod->getContext(), 32), “retval”, label_entry);

ptr_retval->setAlignment(4);

AllocaInst* ptr_var = new AllocaInst(ArrayTy_3, “var”, label_entry);

ptr_var->setAlignment(1);

AllocaInst* ptr_offset = new AllocaInst(IntegerType::get(mod->getContext(), 32), “offset”, label_entry);

ptr_offset->setAlignment(4);

AllocaInst* ptr_val = new AllocaInst(IntegerType::get(mod->getContext(), 32), “val”, label_entry);

ptr_val->setAlignment(4);

new StoreInst(const_int32_5, ptr_offset, false, label_entry);

LoadInst* int32_tmp = new LoadInst(ptr_offset, “tmp”, false, label_entry);

CastInst* int64_idx_ext = new ZExtInst(int32_tmp, IntegerType::get(mod->getContext(), 64), “idx.ext”, label_entry);

GetElementPtrInst* ptr_add_ptr = GetElementPtrInst::Create(ptr_var, int64_idx_ext, “add.ptr”, label_entry);

CastInst* ptr_8 = new BitCastInst(ptr_add_ptr, PointerTy_1, “”, label_entry);

LoadInst* int32_tmp1 = new LoadInst(ptr_8, “tmp1”, false, label_entry);

new StoreInst(int32_tmp1, ptr_val, false, label_entry);

LoadInst* int32_tmp2 = new LoadInst(ptr_offset, “tmp2”, false, label_entry);

CastInst* int64_idx_ext3 = new ZExtInst(int32_tmp2, IntegerType::get(mod->getContext(), 64), “idx.ext3”, label_entry);

GetElementPtrInst* ptr_add_ptr4 = GetElementPtrInst::Create(ptr_var, int64_idx_ext3, “add.ptr4”, label_entry);

CastInst* ptr_10 = new BitCastInst(ptr_add_ptr4, PointerTy_1, “”, label_entry);

new StoreInst(const_int32_6, ptr_10, false, label_entry);

LoadInst* int32_12 = new LoadInst(ptr_retval, “”, false, label_entry);

ReturnInst::Create(mod->getContext(), int32_12, label_entry);

… snip …

With the important bits being the AllocaInst, StoreInsts, LoadInsts and BitCasts. With simpler code you’d get more obvious output.

You can ignore the ->setAlignment()’s and just use the native alignment.

If this doesn’t help any then I’d be happy to explain more.

Cheers,

James