This is an archive of the discontinued LLVM Phabricator instance.

[mlir][LLVM] Add `SplitGEP` type-consistency pattern
ClosedPublic

Authored by zero9178 on Jul 7 2023, 2:04 AM.

Details

Summary

The goal of this pattern is to eliminate all GEPs that have more than two indices by splitting it into multiple GEPs.
The advantage of this change is that the resulting GEPs only ever index into one aggregate at the time. This enables handling sub-aggregates in other patterns and also creates IR with easier to deduce pointer element types.

As a minor note, getResultPtrElementType for GEPOp was rewritten since it did not properly handle dynamic indices. The way GEPOp is specified, the resulting pointer element type can *always* be deduced from its base type and indices.

Diff Detail

Event Timeline

zero9178 created this revision.Jul 7 2023, 2:04 AM
Herald added a reviewer: dcaballe. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
zero9178 requested review of this revision.Jul 7 2023, 2:04 AM
gysit added a comment.Jul 9 2023, 8:44 AM

Can you add a test for the pattern or is the result always consumed by a follow up pattern?

mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
787–788

IRC we introduced the loop above since using drop_begin on getIndices resulted in strange crashes depending on the machine etc. Maybe copying the indices on the line above actually fixes the problem. Was this the reason for the additional copy?

789

nit: which can be structs or arrays.

800

Is it possibly that we can continue to use the destructible type interface here? Also are we sure we want to simplify anything if the indices are dynamic. SROA and Mem2Reg will anyways fail in these cases?

mlir/lib/Dialect/LLVMIR/Transforms/TypeConsistency.cpp
561

nit: getOp?

591–593

I would probably fill a vector directly?

SmallVector<GEPArg> newIndices = {0};
newIndices.append(splitIter, indices.end());

or similar?

gysit added inline comments.Jul 9 2023, 8:45 AM
mlir/lib/Dialect/LLVMIR/Transforms/TypeConsistency.cpp
561

gepOp of course...

zero9178 added inline comments.Jul 10 2023, 12:00 AM
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
787–788

Yes. The iterators of GEPIndicesAdaptor keep a pointer to the instance. When writing llvm::drop_begin(getIndices()) one creates a temporary instance that gets deleted after the call to llvm::drop_begin (the value returned by llvm::drop_begin stays alive and llvm::drop_begin only copies the iterators of the range passed to it, not the range).

800

I think at the very least we should have getResultPtrElementType always return a correct result. If we want type consistency purely for SROA and Mem2Reg then dynamic indices would just cause useless GEP splits. For type consistency for the purpose of lifting, this would create nice and easy to work with GEPs.

That said, if for now we want to do it purely for the purpose of SROA and Mem2Reg then I think it'd make more sense to disable the dynamic indices case in the pattern rather than here.

zero9178 updated this revision to Diff 538521.Jul 10 2023, 12:11 AM
zero9178 marked 5 inline comments as done and an inline comment as not done.

Address style comments

zero9178 updated this revision to Diff 538525.EditedJul 10 2023, 12:23 AM

add pure static GEP splitting test

gysit accepted this revision.Jul 10 2023, 12:50 AM

LGTM!

mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
800

True I was worried there may be a follow up pattern applying that should not apply. But you are right it is better to prevent this in these patterns!

This revision is now accepted and ready to land.Jul 10 2023, 12:50 AM
This revision was automatically updated to reflect the committed changes.