0

I have a stack allocated value, created via an alloca instruction, as a Value* v.

I want to write the C++ llvm builder code that will assign the address of v, which lives on the stack, to a new variable p.

That is, for the equivalent in C, if I have a local variable v, I want to get its address into p, like:

int c = 10;
int* p = &c;

I put some code into GodBolt, and I found out this is apparently the equivalent LLVM IR - so I want to produce IR like this:

  %2 = alloca i32, align 4
  %3 = alloca i32*, align 8
  store i32 %0, i32* %2, align 4
  store i32* %2, i32** %3, align 8, !dbg !18
  %4 = load i32*, i32** %3, align 8, !dbg !19

I should add that the above llvm IR doesn't make sense to me. Why do we need the first store? It seems like a redundant copy of %0 to %2 to me. Why couldn't i take the address of $0 directly? And in the second store, it looks like we're casting the value into a pointer top... Is that just a trick of the light, and that instruction actually means "please copy the address of %2" even though it doesn't say that directly? Is this actually the right IR that I want to generate? Is there a better way to write this? Thanks, apologies for my ignorance of LLVM IR.

Possibly related questions:

NHDaly
  • 7,390
  • 4
  • 40
  • 45
  • What is your problem exactly? Use Builder to create two `alloca`s, two `store`s and one `load` instruction. – arrowd Jul 14 '23 at 11:44
  • 1
    The `alloca` instruction is the address you want, just like an `add` instruction is the result of the addition. – arnt Jul 14 '23 at 12:31
  • Thanks. @arrowd you're right: by the time I arrived at the IR above, I think I was close to the answer. But I don't exactly understand that IR itself, so I wasn't sure if that's even the right way to go about it. I've updated my question to clarify my confusion. Thanks! – NHDaly Jul 17 '23 at 10:27

1 Answers1

2

I think just picking up the llvm::Value from the return of the alloca (which represents the register holding the address) is enough for further use including assignments later on.

  std::string x = "x";
  llvm::Value *alloca_x =
      builder.CreateAlloca(llvm::Type::getInt32Ty(context), nullptr, x);

  llvm::Value *ten =
      llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), 10);
  llvm::Value *assign_x = builder.CreateStore(ten, alloca_x);

  std::string p = "p";
  llvm::Value *alloca_p =
      builder.CreateAlloca(llvm::Type::getInt32PtrTy(context), nullptr, p);

  llvm::Value *assign_p = builder.CreateStore(alloca_x, alloca_p);

A more complete example generates the following for me:

  %x = alloca i32, align 4      ; x = alloca
  store i32 10, ptr %x, align 4 ; x := 10
  %p = alloca ptr, align 8      ; p = alloca
  store ptr %x, ptr %p, align 8 ; *p := &x
jerin
  • 91
  • 1
  • 6