This is an archive of the discontinued LLVM Phabricator instance.

[TableGen] Warn when patterns are ignored due to impossible types
Needs ReviewPublic

Authored by tlively on Jul 13 2021, 11:53 AM.

Details

Reviewers
kparzysz
Summary

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.

Diff Detail

Event Timeline

tlively created this revision.Jul 13 2021, 11:53 AM
tlively requested review of this revision.Jul 13 2021, 11:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 13 2021, 11:53 AM

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.

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)>;

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?

No, it doesn't.