Understanding TargetLowering::LowerCall

For CallSites that contains a GlobalValue as one of the arguments, where exactly does the lowering from GlobalAddress to iPTR took place?.

I’m assuming it should be handled in TargetLowering::LowerCall where target-dependent DAG Nodes got created depending on CCValAssign::isRegLoc() but from my testing it seems like isRegLoc() is true even for GlobalAddress arguments.

What am I misunderstanding here?


It's generally no different for a callsite than any other GlobalValue
user. The generic SelectionDAGBuilder code will create a GlobalAddress
SDNode with iPTR type because the type of a GlobalValue is actually a
pointer to the type of the underlying object.

The call lowering code will get this iPTR node, and may well decide to
pass it to the callee in a register.

As for the GlobalAddress node, that goes through normal lowering to a
target-specific instruction sequence to materialize the address of the
global object. Often this is via custom C++ in LegalizeDAG (i.e.
`setOperationAction(ISD::GlobalValue, MVT::i64, Custom)`).



Hi Tim,
I had similar problem a couple of weeks ago but I somehow circumvented it. However, I dont understand much from the description. Can you please provide some example of backend which does this? probably what functions in X86 backend handle this lowering? If I look at the code I will be able to understand more clearly.

On X86 it's X86TargetLowering::LowerGlobalOrExternal.


Thanks Tim.
One more thing I’m still not quite clear is how to differ GlobalAddress from registers when selection instructions.
Say the Initial DAG is :

load<(dereferenceable load 4 from @gv)> t0, TargetGlobalAddress:i64<i32* @gv> 0, undef:i64

And in our ISA we have:

LOAD_RM reg1,reg2 which basically means reg1 = *reg2

However when I use [(set (i32 GP32:$dst),(load GP64:$reg))] as the pattern for this ISA. the aforementioned DAGNode got matched as well.
How do I prevent such nodes from being matched since in our ISA GlobalAddress requires custom lowering

The initial DAG shouldn't have a *Target*GlobalAddress. That's an
already-selected machine node and so it won't be further processed by
instruction selection. So you probably need to find whatever code you
have that's turning the original GlobalAddress into a
TargetGlobalAddress and modify that to actually insert the correct
instructions too.