There are some typing problems that cause TableGen to silently ignore CodeGen
patterns, which makes for a surprising and frustrating development workflow. To
clue developers in when their patterns are being ignored, emit a warning.
Details
- Reviewers
kparzysz
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
I have to admit that I don't understand what situations the comment is describing where we would want to ignore an impossibly-typed pattern. This new warning is not emitted by any of the upstream backends, so I'm wondering if we should update the comment and make this a hard error instead.
Suppose that you have an architecture that can be either 32- or 64-bit with mostly the same instruction/register sets for both. This is the kind of a scenario that this "HW mode" thing was invented for: it allows you to write a single set of patterns that will work in either mode. However, in practice it can happen that there are instructions that don't exist in some modes. Let's assume that this imaginary architecture has a 32-bit add instruction ADD, but not a 64-bit one. Let's say that GR is the register class (parameterized by the 32-/64-bit hw mode). If you write
def: Pat<(add (i32 GR:$a), (i32 GR:$b)), (ADD $a $b)>;
it will be expanded into the two modes, but in the 64-bit variant it will create a contradiction, since in (i32 GR:$a) the GR class will hold i64.
This shouldn't emit a warning by default, because in this case there is nothing to be corrected here. In cases like that the user will always get the warning, which is not a desired behavior.
RISCV uses HW mode and has a bunch of i64 patterns that should be ignored for the 32-bit mode. Does the RISCV build produce warnings from this patch?
Is there a way we could make this behavior more specifically targeted to when the typing issue involves an HW Mode? I've never used an HW Mode (although perhaps I should), but I've had my patterns silently ignored multiple times now and it is always a painful debugging experience. Most recently was when I wrote something like this:
def load8_lane : PatFrag<(ops node:$ptr, node:$vec, node:$idx), (vector_insert $vec, (extloadi8 $ptr), $idx)>;
The pattern that used this fragment was silently dropped until I fixed it to be
def load8_lane : PatFrag<(ops node:$ptr, node:$vec, node:$idx), (vector_insert $vec, (i32 (extloadi8 $ptr)), $idx)>;