Search code examples
c++arraysllvm-c++-api

How to use CreateInBoundsGEP in cpp api of llvm to access the element of an array?


I am new to llvm programming, and I am trying to write cpp to generate llvm ir for a simple C code like this:

int a[10];
a[0] = 1;

I want to generate something like this to store 1 into a[0]

%3 = getelementptr inbounds [10 x i32], [10 x i32]* %2, i64 0, i64 0
store i32 1, i32* %3, align 16

And I tried CreateGEP: auto arrayPtr = builder.CreateInBoundsGEP(var, num); where var and num are both of type llvm::Value*

but I only get

  %1 = getelementptr inbounds [10 x i32], [10 x i32]* %0, i32 0
  store i32 1, [10 x i32]* %1

I searched google for a long time and looked the llvm manual but still don't know what Cpp api to use and how to use it.

Really appreciate it if you can help!


Solution

  • Note that the 2nd argument to IRBuilder::CreateInBoundsGEP (1st overload) is actually ArrayRef<Value *>, which means it accepts an array of Value * values (including C-style array, std::vector<Value *> and std::array<Value *, LEN> and others).

    To generate a GEP instruction with multiple (child) addresses, pass an array of Value * to the second argument:

    Value *i32zero = ConstantInt::get(contexet, APInt(32, 0));
    Value *indices[2] = {i32zero, i32zero};
    builder.CreateInBoundsGEP(var, ArrayRef<Value *>(indices, 2));
    

    Which will yield

    %1 = getelementptr inbounds [10 x i32], [10 x i32]* %0, i32 0, i32 0
    

    You can correctly identify that %1 is of type i32*, pointing to the first item in the array pointed to by %0.

    LLVM documentation on GEP instruction: https://llvm.org/docs/GetElementPtr.html