This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel][AArch64] Fold G_SUB into G_ICMP when it's safe to do so
ClosedPublic

Authored by paquette on Jun 11 2019, 1:23 PM.

Details

Summary

Basically porting over the behaviour in AArch64ISelLowering to GISel. See emitComparison for reference.

When we have something like this:

lhs = G_SUB 0, y
...
G_ICMP lhs, rhs

We can fold away the G_SUB and produce a cmn instead, given that we produce the same value in NZCV.

Add a test showing that the transformation works, and also showing that we don't perform the transformation when it's unsafe.

Diff Detail

Event Timeline

paquette created this revision.Jun 11 2019, 1:23 PM
arsenm added a subscriber: arsenm.Jun 11 2019, 1:26 PM

I thought PeepholeOptimizer took care of this sort of thing?

llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
3033–3034

No else after return

aemerson added inline comments.Jun 11 2019, 2:12 PM
llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
2967

This function generates semantically incorrect GMIR and then relies on the caller to fix and select it. I would rather we also modify the opcode in this function to ANDS[WX]rr and then have the caller check the return value to see if it needs to modify the opc. That way, on entry and exit we have semantically correct, if only partially selected, MIR.

paquette updated this revision to Diff 204849.Jun 14 2019, 2:26 PM
  • tryFoldCMN -> tryOptCMN
  • Make tryOptCMN single-exit
  • Make tryOptCMN not leave the G_ICMP in a half-selected state; now it selects the CMN entirely.
  • Factor out cset emission into emitCSet.

I thought PeepholeOptimizer took care of this sort of thing?

In AArch64, these sorts of things are also explicitly matched and selected in AArch64ISelLowering.cpp.

I guess that it's a pain to match past ISel, so I guess SDAG tries to do some of the work early in.

aemerson accepted this revision.Jun 14 2019, 4:10 PM

LGTM with a further change.

llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
3076

I think this predicate inversion is always needed when using CSINC right? So it can be folded into the emitCSet() function which can take the predicate.

This revision is now accepted and ready to land.Jun 14 2019, 4:10 PM
This revision was automatically updated to reflect the committed changes.