Yes, it’s legal, in opaque pointer mode, for a GEP of a GEP instruction to have the source element type of the second GEP not match the result element type of the first GEP.
For opaque pointers, the type of a, b and c in your example are all of type “ptr”. Not float or anything else.
For your examples, it might be easier to understand if you create some C source code, and the compile it with clang-15 and the see what sort of gep expressions happen.
%x = getelementptr inbounds [2 x [1 x float]], ptr @aaa, i64 0, i64 %in1, i64 %in2
@jcranmer Thanks for clarifying.
since %c has only one index, %a and %c could be merged to %x, single GEP instruction ?
This optimisation happens if we didn’t have opaque pointers: link
The GEPs can be merged only if GEP2->getSourceElementType() == GEP1->getResultElementType(). With typed pointers, this is true for every gep-of-gep, but this is not the case for opaque pointers, and a few optimizations have had to be fixed to make sure that they check for this precondition.