1

I'm building LLVM-IR with the C API and have a pointer to the following struct type:

{ i8*, i8*, i8*, i8*, i8*, i8*, i8*, [1 x i64] }

That is, several i8 pointers and an array of long integers, currently of size one but this will change in the future.

I want to access the element in the array at index 7, and my current understanding is that I should be able to do this with a call to LLVMBuildStructGEP on the pointer to the struct, passing index 7, and then a call to LLVMBuildGEP2 on the returned address with i64 as the type and 0 as the index.

This method doesn't flag up any problems when passing the module to LLVMAnalyseModule, but if I dump the bitcode of the module and then run llvm-dis on the file, I get the error:

llvm-dis: error: Explicit gep type does not match pointee type of pointer operand

Which I've isolated down to the second GEP on the address of the array returned from the first struct GEP.

For some additional information, I've noticed that if I replace the first struct GEP with a regular GEP taking the struct type as an argument, and then pass the struct type to the second GEP on what should be the i64 array address, llvm-dis will not complain, but then subsequent loads or stores will be working with the wrong types so this is obviously not a real solution.

4
  • 2
    Looks like you are taking these indexes for GEP: [7, 0]. But imho you need to take such indexes: [0, 7, 0]. llvm.org/docs/… Commented Mar 21, 2021 at 9:28
  • 1
    If issue is not fixed somehow still, can you give some code to reproduce? My knowledge of C API is terrible:( With code it will be easier :) Commented Mar 21, 2021 at 10:10
  • Using a single GEP with 0,7,0 works, although I'm unable to get separate GEP's or struct GEP's to work in the same index order, but I guess it doesn't matter too much. I would had posted code but this is actually part of a wider project and being used through python bindings, so it's not so straight forward to glance at! Thanks for the help. Commented Mar 22, 2021 at 5:29
  • The way GEPs work can feel a bit unintuitive. To split [0, 7, 0] you would need to add an extra 0 at the start of the new GEPs, as I understand it. Commented Mar 22, 2021 at 18:20

1 Answer 1

2

Okay. So, answering here. As you see, you need to first get zero index, after than indexes 7 and 0. The reason is simple to explain. Let's see an example why extra zero is needed:

char A *a = new A[123];

First index which is zero in your case can be used in arrays, but in your case it is a pointer to single element. In the case of array it can be not zero.

Anyway, I am not so clever about LLVM C APIs. Please don't kill me for that :D

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.