How to generate getelementptr instruction right

I am trying to instrument LLVM IR generated by the swift compiler and in particular, I want to record at runtime the read and write operations to an array. Since in Swift the actual read does not happen in the IR through a load instruction but rather through a call to the stdlib my idea was to generate some instructions that should obtain this information. In particular:

types: 

%TSa = type <{ %Ts22_ContiguousArrayBufferV }>
%Ts22_ContiguousArrayBufferV = type <{ %Ts28__ContiguousArrayStorageBaseC* }>
%Ts28__ContiguousArrayStorageBaseC = type opaque


Instructions for reading from array: 

 %20 = load %Ts28__ContiguousArrayStorageBaseC*, %Ts28__ContiguousArrayStorageBaseC** getelementptr inbounds (%TSa, %TSa* @"$array", i32 0, i32 0, i32 0), align 8, !dbg !40

 %21 = call swiftcc i64 @"$sSayxSicigSi_Tg5"(i64 0,%Ts28__ContiguousArrayStorageBaseC* %20), !dbg !40


the first instruction loads the base of the array into register 20, the a call to the stdlib with the index 0 as argument reads the value into register 21. My idea is to issue a getelementptr instruction that calculates the actual index and then passes it to a function that calls my own runtime lib to record the access like so:

%20 = load %Ts28__ContiguousArrayStorageBaseC*, %Ts28__ContiguousArrayStorageBaseC** getelementptr inbounds (%TSa, %TSa* @"$array", i32 0, i32 0, i32 0), align 8, !dbg !40

 %21 = call swiftcc i64 @"$sSayxSicigSi_Tg5"(i64 0,%Ts28__ContiguousArrayStorageBaseC* %20), !dbg !40

%22 = getelementptr % Ts28__ContiguousArrayStorageBaseC, % Ts28__ContiguousArrayStorageBaseC* 28, i64 0, i64 0


however I am getting the error
**llvm::Type llvm::checkGEPType(llvm::Type): Assertion Ty && “Invalid GetElementPtrInst indices for type!”’ failed

The arguments I give to GetElementPtrInst::Create look like this when I print them:

%Ts28__ContiguousArrayStorageBaseC = type opaque


%26 = load %Ts28__ContiguousArrayStorageBaseC*
%Ts28__ContiguousArrayStorageBaseC** getelementptr inbounds (%TSa, %TSa* @"$s9reduction3arrSaySiGvp", i32 0, i32 0, i32 0), align 8


i64 0


i64 0

did I mess up with the typing or something? As I understand it, the base type of my getelementptr instruction is now TSa but I think it should be Ts28__ContiguousArrayStorageBaseC but then I do not understand what exactly type opaque means… My LLVM understanding is not that great yet as I am just starting to learn it.

thanks!

edit:

so I solved it with an add instruction and a cast for now but I think a getelementptr instruction would be more appropriate? this is what I came up with:

%26 = load %Ts28__ContiguousArrayStorageBaseC*, %Ts28__ContiguousArrayStorageBaseC** getelementptr inbounds (%TSa, %TSa* @"$s9reduction3arrSaySiGvp", i32 0, i32 0, i32 0), align 8

%28 = call swiftcc i64 @"$sSayxSicigSi_Tg5"(i64 0, %Ts28__ContiguousArrayStorageBaseC* %26)

%27 = ptrtoint %Ts28__ContiguousArrayStorageBaseC* %26 to i64

%idxadd = add i64 0, %27

call void @read(i32 16388, i64 %idxadd, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.1, i32 0, i32 0))

with the read call being to my library for recording the read operation.

1 Like