[LLVMdev] need to store the address of a variable

Nick Lewycky nicholas at mxc.ca
Sat Jun 28 09:57:40 PDT 2008

Paul Arndt wrote:
> Hello everybody,
> my problem is, that  I want to get an array of pointers to all local variables 
> in a function. This array will be used for transfering these Variables to 
> another execution engine. 
> I've code which generates this array, and a pointer to the target field of the 
> array.
> name = variables.fname + "_pointerArray";
> Instruction* pointerArray = new 		
> 		AllocaInst(PointerType::get(Type::Int32Ty,NULL),
> 		ConstantInt::get(Type::Int32Ty, variables.inst.size()),
> 		name,
> 		alloca_point);
> 		// fill array with the addresses of the functions
> 		for(unsigned int i = 0; i < variables.inst.size(); i++) {
> 			name = "store_" + variables.inst[i]->getName();
> 			Value* GEP = new GetElementPtrInst(pointerArray, 
> 							   ConstantInt::get(Type::Int32Ty, i),
> 							   name, 
> 	   						   alloca_point);
> 		}
> the result of this is:
> %minPos_pointerArray = alloca i32*, i32 26              ; <i32**> [#uses=26]
> %store_tmp1 = getelementptr i32** %minPos_pointerArray, i32 1    ; <i32**> ... 
> But I could not find a way to get a pointer to a given variable.
You probably already know this, but I want to state it just in case. 
LLVM has no address-of operator, so if you see an instruction like "%sum 
= add i32 %x, %y" you can't get the address of %sum (it's a register, 
after all).

The C frontend doesn't interpret "int32_t i;" as creating an LLVM 
variable of type i32; it actually does "i32* %i_addr = alloca i32". 
LLVM's optimizers will remove the alloca and lower it to registers if 
nobody takes its address.

I think what you're saying is that you want a pointer to a given C 
variable, not a given LLVM variable, which is certainly possible.
> When I translate the following C Code with llvm-gcc 
> int a;
> int* d;
> d = &a;
> to LLVM I get the following LLVM Code
> %a_addr = alloca i32    ; <i32*> [#uses=2]
> %d = alloca i32*    ; <i32**> [#uses=2]
> store i32 %a, i32* %a_addr
> store i32* %a_addr, i32** %d, align 4							
> how can I generate such an Instruction?
In general, what you can do is take that code:

define void @foo(i32 %a) {
  %a_addr = alloca i32    ; <i32*> [#uses=2]
  %d = alloca i32*    ; <i32**> [#uses=2]
  store i32 %a, i32* %a_addr
  store i32* %a_addr, i32** %d, align 4
  ret void

then run "llc -march=cpp arndt.bc -f -o -" to see the C++ code that 
constructs the module from the input bytecode. In your case, the 
relevant section looks like this:

AllocaInst* ptr_a_addr = new AllocaInst(IntegerType::get(32), "a_addr", 
AllocaInst* ptr_d = new AllocaInst(PointerTy_1, "d", label_4);
StoreInst* void_5 = new StoreInst(int32_a /* argument %a */, ptr_a_addr, 
false, label_4);
StoreInst* void_6 = new StoreInst(ptr_a_addr, ptr_d, false, label_4);

void_5 is putting the argument %a into the locally allocated %a_addr.
void_6 is taking %a_addr and storing it into %d.
> When I use
> name = variables.inst[i]->getName() + "address_";
> Instruction *AD = new AllocaInst(Type::Int32Ty, 
> ConstantInt::get(Type::Int32Ty, 1), name, alloca_point);
> StoreInst *SI = new StoreInst(variables.inst[i], AD, alloca_point);
> StoreInst(SI, GEP, alloca_point);
That looks wrong. The last line, "StoreInst(SI, GEP, alloca_point)" is 
trying to store the result of your first store (which is void) to the 
place pointed to by GEP.

> the compiler is happy, but I get the following error at run time:
> Instructions.cpp:904: void llvm::StoreInst::AssertOK(): Assertion 
> `getOperand(0)->getType() == 
> cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be 
> a pointer to Val type!"' failed.
> I hope you understand what I want, and someone knows the right way to do that.
> Many thanks for your time.
> Paul
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

More information about the llvm-dev mailing list