Does a transform exist to breakdown the GEP?

You mean, something along the lines of the GEPSplitterPass?

// GEPSplitter - Split complex GEPs into simple ones



No I think I misunderstood you, I actually want the GEP broken down into it’s arithmetic instructions, I don’t want any GEP instructions in my code at all. Is there a way to do that?

Do you think I could use the SelectionDAGBuilder in a pass to accomplish this for me? if there is already code that does this I don’t really think I should have to do this again, unless it’s not possible to access that code from the stage where I want to use it?

So basically, is it possible to initialize the SelectionDAG and extract the lowering of getelementptr from it within a pass?

Why would you want to remove all GEP instructions? inttoptr+math+ptrtoint don’t have the exact same semantics in LLVM IR. GEP instructions have certain guarantees about what addresses can be computed with them that straight pointer arithmetic doesn’t.


There is no support for gep, it’s my understanding that it’s target-independent, so there’s no reason to put the lowering in the target lowering portion is there?

Eventually the GEP has to be lowered correctly, to the target architecture, but the docs state that it’s target-independent, so given that it should be possible to lower it without knowing any specifics about the target, correct?

Or is it in the docs such that when you use the word “independent”, you really mean “independent of a particular target” and not actually “target independent”?

After some thought, to put this more simply (more direct), it would be fine if the getelementptr is lowered into IR assuming an x86 architecture. The real problem is that I don’t want the x86 code generation, I still want to deal in LLVM IR just with the GEP lowered, and it lowered for the x86 architecture is fine.

Is there any way to do this?

It should be straightforward to write, but I don't think there's any
existing code to do this. You can grab the necessary information
about the target out of TargetData.


It is target-independent in the sense that a frontend can generate
code using GEP's without worrying about how a given target actually
lays out structures. It isn't target-independent in the sense that
the actual computed offset in bytes isn't the same for every target.
See also


Ok, thanks, this makes sense. But there is no way to get the SelectionDAG to do it for me via something like visitGetElementrPtr?

Ok, thanks, this makes sense. But there is no way to get the SelectionDAG to
do it for me via something like visitGetElementrPtr?

SelectionDAGBuilder::visitGetElementPtr uses the same algorithm you
want to use, but it is specialized for building a SelectionDAG, which
is lower level than LLVM IR.



Ok, thanks, this is a big help. So how can I use the TargetData (or get the TargetData) without having a DAG?

If you're writing a transformation pass, just write
"getAnalysisIfAvailable<TargetData>()" to get a TargetData*.


For the gep:

%idx1 = getelementptr i32* %MyVar, i32 0

i32* is the type that MyVar is pointing to and i32 is the type of the offset value, or what? If it's the type of offset value, then 
the size of the pointer shouldn't be less than i32, correct?

The index is 0, so in this example, the address computation is idx1 = &MyVar+0. 

What I want to know is the size in bits of the values above, it looks like 0 is 32 bits in size, which would make the pointer size also 32?

LLVM will sign-extend or truncate the index to the size of the
pointer; the pointer type could have any width.


By LLVM do you mean the backend? I’m not using the backend, so is that i32 on the 0 index the type of the index value or the type of the value to which exists at that index?

it seems the pointer itself has no width, it’s arbitrary and is handled in the lowering and is target dependent on the bus width.

Basically, when I am computing offset I need to know the sizes for add. The size of the pointer (dedicated by bus width) and the size of the index.

A less confusing example (for me) might be this:

%idx2 = getelementptr i32* %MyVar, i64 1

The pointer type size is 32 bits (let's say int pointer), why is the index of size 64?