Previously, GEPOp relies on findKnownStructIndices to check if a GEP index should be static. The truth is, findKnownStructIndices can only tell you a GEP index _might_ be indexing into a struct (which should use a static GEP index). But GEPOp::build and GEPOp::verify are falsely taking this information as a certain answer. Here is a counter example:
%sub_struct = type { i32, i8 } %my_struct = type { %sub_struct, [4 x i32] } define void @foo(%my_struct* %arg, i32 %idx) { %1 = getelementptr %my_struct, %my_struct* %arg, i32 0, i32 1, i32 %idx ret void }
Which is a legit GEP, but the current verifier will bail out with error message "expected index 2 indexing a struct to be constant". One of the GEPOp::build functions also bailed out with a similar error message.
The solution presented here adopts a new verification scheme: When we're recursively checking the child element types of a struct type, instead of checking every child types, we only check the one dictated by the (static) GEP index value. We also combine "refinement" logics --refine/promote struct index mlir::Value into constants -- into the very
verification process since they have lots of logics in common. The resulting code is more concise and less brittle.
We also hide GEPOp::findKnownStructIndices since most of the aforementioned logics are already encapsulated within GEPOp::build and GEPOp::verify, we found little reason for findKnownStructIndices (or the
new findStructIndices) to be public.
Nit: please add documentation to these classes.