This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Check LLT size matches memory size for non-truncating stores.
ClosedPublic

Authored by aemerson on Jul 16 2019, 6:52 PM.

Details

Diff Detail

Event Timeline

aemerson created this revision.Jul 16 2019, 6:52 PM
arsenm added inline comments.Jul 16 2019, 7:03 PM
llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-store-flat.mir
106 ↗(On Diff #210230)

This is breaking this, producing a non-truncating store instead of the correct trunc store

llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-store-private.mir
55 ↗(On Diff #210230)

This is breaking this, the correct trunc store now fails to select

llvm/utils/TableGen/GlobalISelEmitter.cpp
3360

Should also continue? Could make this a select on the match type to the one addPredicate call

aemerson marked an inline comment as done.Jul 16 2019, 7:12 PM
aemerson added inline comments.
llvm/utils/TableGen/GlobalISelEmitter.cpp
3360

Yeah, just seen this doesn't work. I'm not familiar with this code, but how do non-truncstore predicates end up on trunc stores such that it breaks?

arsenm added inline comments.Jul 16 2019, 7:22 PM
llvm/utils/TableGen/GlobalISelEmitter.cpp
3360

I don't exactly understand what the expected relationship between predicate bits set on a PatFrag and the PatFrags which used it is.

It's possible something is wrong with the AMDGPU PatFrags. This system is pretty confusing, because each property is added in a different layer of PatFrags defined in TargetSelectionDAG.td. The AMDGPU PatFrags reproduce the same hierarchy, with the additional address space predicates.

There is also the extra IsTruncStore bit which needs to be manually set on the base truncstore PatFrag. For some reason the derivative PatFrags do not have it set, as it should be implied. However, they still need to set IsStore, although I would expect these to both behave the same way.

arsenm added inline comments.Jul 16 2019, 7:26 PM
llvm/utils/TableGen/GlobalISelEmitter.cpp
3360

I'm also not sure the way this loop is structured makes sense. It seems to assume too much about what different predicates can be combined. The atomic predicates also don't work correctly

aemerson marked an inline comment as done.Jul 17 2019, 11:24 AM
aemerson added inline comments.
llvm/utils/TableGen/GlobalISelEmitter.cpp
3360

@dsanders any idea what to do?

dsanders added inline comments.Jul 18 2019, 5:48 PM
llvm/utils/TableGen/GlobalISelEmitter.cpp
3360

That else is suspicious. isTruncStore() means that the predicate needs to be added but !isTruncStore() can mean either no predicate is needed or a non-trunc store predicate is needed. I believe it needs to be:

if (Predicate.isTruncStore())
  add relevant predicate for trunc store
if (Predicate.isNonTruncStore())
  add relevant predicate for non-trunc store
dsanders added inline comments.Jul 18 2019, 6:21 PM
llvm/utils/TableGen/GlobalISelEmitter.cpp
3360

don't exactly understand what the expected relationship between predicate bits set on a PatFrag and the
PatFrags which used it is.

It's possible something is wrong with the AMDGPU PatFrags. This system is pretty confusing, because
each property is added in a different layer of PatFrags defined in TargetSelectionDAG.td. The AMDGPU
PatFrags reproduce the same hierarchy, with the additional address space predicates.

The input we start with is pretty weird too and it's mostly a straight import of that.

Suppose we start with the pattern:

(truncstorei8 node:$x)

when the PatFrag is expanded, we get:

(truncstore node:$x)<<code-to-check-memvt==i8>>

where the <<some C++ code>> is tablegen's way of representing predicates (this isn't quite true, it uses a short-hand name instead of the C++ when it's printing but the data in the pattern is the C++ code). Then after further expansion we get:

(unindexedstore node:$x)<<code-to-check-memvt==i8>><<code-to-check-for-truncating>>
(st node:$x)<<code-to-check-memvt==i8>><<code-to-check-for-truncating>><<code-to-check-for-unindexed>>

That last line is how it looks on input to the GlobalISelEmitter before runOnPattern(). The first thing we needed to do was abstract out the C++ as it needed to be different for DAGISel vs GISel. To do that, each predicate was given a field in PatFrag. For these three predicates it was:

ValueType MemoryVT = ?;
bit IsTruncStore = ?;
bit IsUnindexed = ?;

Only one of these is set for each PatFrag as each one directly corresponds to the original C++ code. For example: IsTruncStore = 0 emits this code for DAGISel:

!cast<StoreSDNode>(N)->isTruncatingStore();

I'm also not sure the way this loop is structured makes sense. It seems to assume too much about what
different predicates can be combined.

Each predicate can only be one C++ fragment. If you need multiple fragments (which happens when you have PatFrags inside PatFrag expansions) you have multiple Predicates, each with a different field set corresponding to a different fragment.

The atomic predicates also don't work correctly

Could you elaborate on this?

arsenm added inline comments.Jul 19 2019, 6:48 AM
llvm/utils/TableGen/GlobalISelEmitter.cpp
3360

The atomic predicates also don't work correctly

Could you elaborate on this?

I didn't spend much time looking at it to focus on one broken thing at a time, but the AMDGPU patterns for atomic_load/atomic_store don't work. They should be easy to handle as they ignore the ordering type and just need to preserve the atomicness in the MemOperand. I think the combination of IsStore and IsAtomic wasn't behaving as expected

nhaehnle removed a subscriber: nhaehnle.Jul 22 2019, 2:15 AM
aemerson updated this revision to Diff 213137.Aug 2 2019, 3:42 PM

Use isNonTruncStore() instead.

dsanders accepted this revision.Aug 2 2019, 4:04 PM

That change LGTM. Do you have a test case for your target?

This revision is now accepted and ready to land.Aug 2 2019, 4:04 PM
aemerson marked an inline comment as done.Aug 2 2019, 4:18 PM

That change LGTM. Do you have a test case for your target?

Thanks, it's only exposed with another patch though so I can't add that test here.

llvm/test/TableGen/address-space-patfrags.td
123

Just seen this incorrect comment, will fix in the commit.

This revision was automatically updated to reflect the committed changes.