Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LLVM GEP and store vs load and insertvalue: Storing value to a pointer to an aggregate

What is the difference between getelementptr and store vs. load and insertvalue when storing a value to a pointer to an aggregate type? Is one preferred in certain circumstances? And if so why? Or am I headed entirely in the wrong direction?

Example:

; A contrived example
%X = type {i32, i64}

define i32 @main(i32 %argc, i8** %argv) {
entry:
  %sX.0 = alloca %X

  ; change the first value with GEP + store
  %val1 = getelementptr %X, %X* %sX.0, i32 0, i32 0
  store i32 42, i32* %val1

  ; change the second value with load + insertvalue
  %sX.1 = load %X, %X* %sX.0
  %sX.2 = insertvalue %X %sX.1, i64 42, 1
  store %X %sX.2, %X* %sX.0 ; I suppose this could be considered less than ideal
                            ; however in some cases it is nice to have the
                            ; struct `load`ed
  ret i32 0
}

Interestingly using llc -O=0 ... they both compile to the the same instructions. What amounts to the following, which is what I had hoped.

movl $42, -16(%rsp) # GEP + store
movq $42, -8(%rsp)  # load + insertvalue

Background:

I was reading the LLVM Language Reference and I was reading about insertvalue. The reference notes the extractvalue instructions similarity with GEP and the following differences.

The major differences to getelementptr indexing are:

  • Since the value being indexed is not a pointer, the first index is omitted and assumed to be zero.

  • At least one index must be specified.

  • Not only struct indices but also array indices must be in bounds.

The following question on StackOverflow also mentions the use of getelementptr and insertvalue, but for different reasons. LLVM insertvalue bad optimized?

like image 684
Daniel Robertson Avatar asked Feb 05 '16 22:02

Daniel Robertson


1 Answers

Semantically, loading and later storeing the entire object is more wasteful. What if it's a huge struct? What if it's an array of structs? GEP allows you to access an exact location in memory where you want to load/store, without the need to load/store anything else.

While the two forms were lowered to the same instructions in your example, it isn't generally guaranteed.

like image 70
Oak Avatar answered Jan 02 '23 22:01

Oak