This is an archive of the discontinued LLVM Phabricator instance.

[globalisel][tablegen] Add several GINodeEquiv's for operators that do not require additional support.
ClosedPublic

Authored by dsanders on Apr 20 2017, 12:42 AM.

Event Timeline

dsanders created this revision.Apr 20 2017, 12:42 AM

One thing to mention for this patch is that G_ICMP and G_FCMP are not included due to a difference in operand order between G_ICMP/G_FCMP in GlobalISel and setcc in SelectionDAG (predicate, lhs, rhs vs lhs, rhs, predicate). I can support those in a later patch by adding more information to GINodeEquiv or by changing G_ICMP/G_FCMP. I don't see a particularly strong argument either way on that point but I'm expecting to need to convert the predicate operand too so I'm leaning towards making GINodeEquiv more descriptive.

Does anyone else have a preference?

dsanders added inline comments.Apr 20 2017, 2:44 AM
include/llvm/Target/GlobalISel/SelectionDAGCompat.td
36–37

It turns out these two lines aren't entirely true. In AArch64 they're used as operators in some contexts and operands in others. I'll drop these lines.

ab accepted this revision.Apr 20 2017, 10:52 AM

LGTM

One thing to mention for this patch is that G_ICMP and G_FCMP are not included due to a difference in operand order between G_ICMP/G_FCMP in GlobalISel and setcc in SelectionDAG (predicate, lhs, rhs vs lhs, rhs, predicate). I can support those in a later patch by adding more information to GINodeEquiv or by changing G_ICMP/G_FCMP.

Eh, I mildly prefer changing G_ICMP, to avoid making tablegen even more complicated. But that's not the main issue ...

I don't see a particularly strong argument either way on that point but I'm expecting to need to convert the predicate operand too so I'm leaning towards making GINodeEquiv more descriptive.

... because the predicates are different, right? In general, setcc/br_cc and friends are IMO at the limit of what we should support in the importer, but I suppose it could be worth it if it's not too involved.

I'm *terrified* by the lack of testing: we have no idea what changes and what's covered. But that's true for all tablegen changes, and I'm even more worried about sdag pattern changes affecting gisel.
We should really at least generate the test inputs for the covered patterns, and also have a test that fails when we add more (maybe something trivial like the number of emitted patterns?)

This revision is now accepted and ready to land.Apr 20 2017, 10:52 AM
In D32275#732358, @ab wrote:

LGTM

Thanks.

One thing to mention for this patch is that G_ICMP and G_FCMP are not included due to a difference in operand order between G_ICMP/G_FCMP in GlobalISel and setcc in SelectionDAG (predicate, lhs, rhs vs lhs, rhs, predicate). I can support those in a later patch by adding more information to GINodeEquiv or by changing G_ICMP/G_FCMP.

Eh, I mildly prefer changing G_ICMP, to avoid making tablegen even more complicated. But that's not the main issue ...

I don't see a particularly strong argument either way on that point but I'm expecting to need to convert the predicate operand too so I'm leaning towards making GINodeEquiv more descriptive.

... because the predicates are different, right? In general, setcc/br_cc and friends are IMO at the limit of what we should support in the importer, but I suppose it could be worth it if it's not too involved.

That's right. LLVM-IR uses CmpInst::Predicate and SelectionDAG uses ISD::CondCode. MIR may differ from both or may use something else like opcodes.

On the br_cc side of things, there's also an operator mismatch between GlobalISel and SelectionDAG on some targets caused by the lowering of BRCOND+SETCC to BR_CC. The rules are still importable but tablegen would have to undo the lowering and it's probably not worth it.

I'm *terrified* by the lack of testing: we have no idea what changes and what's covered. But that's true for all tablegen changes,

We could potentially diff code coverage reports to find out which parts of the C++ implementation are ignored because of new tablegenerated rules.

and I'm even more worried about sdag pattern changes affecting gisel.

It would be fairly easy to add a way to disable the importer for some patterns. Eventually, I'd expect to dump the imported rules in whatever format GlobalISel defines its rules and use that as the input with the importer disabled.

We should really at least generate the test inputs for the covered patterns,

This is on my todo list. I had some experimental patches a while back but they'll need a lot of work.

and also have a test that fails when we add more (maybe something trivial like the number of emitted patterns?)

I'm not sure I understand this bit. Is the intent to prompt us to look at the new rules?

ab added a comment.Apr 20 2017, 12:01 PM
In D32275#732358, @ab wrote:

and also have a test that fails when we add more (maybe something trivial like the number of emitted patterns?)

I'm not sure I understand this bit. Is the intent to prompt us to look at the new rules?

Yeah, otherwise I'm guessing the generated tests stop covering everything as soon as something else is added, unless we automate it somehow. (so the main actionable thing would really be "generate tests for the new stuff")

I decided to have a look at code coverage differences before committing this. This patch made no difference to the code coverage. On closer inspection it turns out beginFunction() isn't being executed so no rules with rule predicates can match. I'll take a look at this, maybe something from the rule-predicates patch didn't make it into the final commit.

A few other notable things in the coverage information:

  • There's no coverage for 64-bit shifts.
  • There's no coverage for 8 or 16-bit FPU stores. That's not particularly surprising but I am surprised that there's an implementation for those sizes.
  • There's no coverage of 128-bit FPU copies
  • Most integer and FPU comparison predicates aren't covered.
  • There's no coverage for LOAD_STACK_GUARD
  • There's no coverage for G_TRUNC in the FPU register bank.
rovka edited edge metadata.Apr 25 2017, 3:46 AM

I decided to have a look at code coverage differences before committing this. This patch made no difference to the code coverage. On closer inspection it turns out beginFunction() isn't being executed so no rules with rule predicates can match. I'll take a look at this, maybe something from the rule-predicates patch didn't make it into the final commit.

I literally just ran into this while trying to enable TableGen for ARM. I'm wondering if it's really a good idea to have beginFunction in the first place. There's a related FIXME in TargetSubtargetInfo.h around getInstructionSelector. Maybe we should have an instruction selector per MachineFunction?

A few other notable things in the coverage information:

  • There's no coverage for 64-bit shifts.
  • There's no coverage for 8 or 16-bit FPU stores. That's not particularly surprising but I am surprised that there's an implementation for those sizes.
  • There's no coverage of 128-bit FPU copies
  • Most integer and FPU comparison predicates aren't covered.
  • There's no coverage for LOAD_STACK_GUARD
  • There's no coverage for G_TRUNC in the FPU register bank.

I decided to have a look at code coverage differences before committing this. This patch made no difference to the code coverage. On closer inspection it turns out beginFunction() isn't being executed so no rules with rule predicates can match. I'll take a look at this, maybe something from the rule-predicates patch didn't make it into the final commit.

I literally just ran into this while trying to enable TableGen for ARM. I'm wondering if it's really a good idea to have beginFunction in the first place. There's a related FIXME in TargetSubtargetInfo.h around getInstructionSelector. Maybe we should have an instruction selector per MachineFunction?

I'm having another go at that approach at the moment. Last time I had some trouble with it using the wrong instruction selector during instruction selection but hopefully I'll figure that one out this time. The tricky predicate is NotWin64WithoutFP from X86 which needs access to the MachineFunction that getSubtargetImpl() doesn't have.

dsanders closed this revision.May 4 2017, 7:37 AM