getelementptr in LLVM IR

Viewed 356

I don't understand the following code written for LLVM IR. I hope, you can give me a hint.

%struct.foo_struct = type {[3 x i32], i16*, i32}

;struct foo_struct {
;  [3 x i32] f0;
;  i16*      f1;
;  i32       f2;
; };

define i32 @foo(%struct.foo_struct* %P) {
entry:
  ; &P[0].f1
  %tmp0 = getelementptr inbounds %struct.foo_struct, %struct.foo_struct* %P, i64 0, i32 1
  ; P[0].f1
  %tmp1 = load i16*, i16** %tmp0 
  ; &P[0].f1[0]
  %tmp2 = getelementptr inbounds i16, i16* %tmp1, i64 0 

Specifically, in the first code line in entry, we have at the end i32 1. Why i32? Since we want to jump to the next field, namely f1, we have to jump over an array (f0), which 3xi32. So what is this i32? What would be there if we want to have e.g. &P[0].f2?

Thank you for any help

1 Answers

Since we want to jump to the next field, namely f1, we have to jump over an array (f0), which 3xi32. So what is this i32?

1 is the index of the member in the struct and i32 is the type of this index.

The fact that we're jumping over a 3xi32 to get to f1 or that we're thus jumping by 12 bytes is not directly encoded in the instruction. All we're specifying is that we want the second member (i.e. the member at index 1) and how that translates to an offset in bytes is calculated by LLVM based on the types involved. We don't spell this out in the instruction.

What would be there if we want to have e.g. &P[0].f2?

i32 2

Why i32?

Struct indices always have the type i32. Since struct indices must always be constants, there wasn't really a need to allow different types and i32 is large enough for all practical purposes (i.e. you won't have a struct with more than 2^32 members).

Related