This is an archive of the discontinued LLVM Phabricator instance.

[x86] reassociate integer multiplies using machine combiner pass
ClosedPublic

Authored by spatel on Jul 30 2015, 1:20 PM.

Details

Summary

If I've done this correctly, then the patch is nearly trivial. :)
Is MachineOperand.isDead() the proper predicate for the EFLAGS operand of an integer math op that we want to reassociate?

This is part of fixing:
https://llvm.org/bugs/show_bug.cgi?id=21768

Diff Detail

Repository
rL LLVM

Event Timeline

spatel updated this revision to Diff 31066.Jul 30 2015, 1:20 PM
spatel retitled this revision from to [x86] reassociate integer multiplies using machine combiner pass.
spatel updated this object.
spatel added reviewers: Gerolf, qcolombet, mkuper.
spatel added a subscriber: llvm-commits.
Gerolf edited edge metadata.Jul 30 2015, 2:29 PM

The machine code verifier used the isDead flag, so my assumption would be that it is safe to assume it is set correctly at the point of use in this code. If there is a way to assert this that would be even better.

lib/Target/X86/X86InstrInfo.cpp
6309 ↗(On Diff #31066)

The intention of the code is checking for a binary operator with EFLAG. When the flag is dead the function returns false.
I see two things to think about: first, why not having a function that makes it explicit incl. an assertion that the third operand actually is an eflag? In the current implementation the assumptions are implicit, so a function would make them more explicit/clear.
Second, the host function checks whether or not a virtual register is defined in \param Inst. It returns true when that is the case. Why doesn't the code check for virtual defs when eflags is dead? So I think its purpose is to eliminate dead instructions in general and binary operators with eflags is perhaps just a special case.

spatel added inline comments.Jul 30 2015, 3:39 PM
lib/Target/X86/X86InstrInfo.cpp
6309 ↗(On Diff #31066)

Thanks, Gerolf. I agree that I should make this more clear by splitting off the check and adding an assert.

To make my intention for this check more clear: if the EFLAGS operand on an integer math op is *not* dead, then I was thinking that those ops are involved in some kind of overflow or other exception-checking sequence, so it's not safe to rearrange the math. If the EFLAGS operands *are* dead, then the ops are part of normal integer math, so it is safe to do the reassociation.

kbsmith1 edited edge metadata.Jul 30 2015, 4:38 PM

Test LGTM. Slight comment on the code.

lib/Target/X86/X86InstrInfo.cpp
6312 ↗(On Diff #31066)

Is there any possibility of 4 operand instructions where operand number 3 is dead, but is not EFLAGS? It seems like a check for (Inst.getOperand(3).isReg && Inst.getOperand(3).getReg() == X86::EFLAGS && !Inst.getOperand(3).isDead()) would be safer and more future proof.

Slight correction to my comment on the code.

lib/Target/X86/X86InstrInfo.cpp
6312 ↗(On Diff #31066)

My proposed code isn't really quite correct. I think the correct formulation would be:
if (!Inst.getOperand(3).isReg() || Inst.getOperand(3).getReg() != X86::EFLAGS || !Inst.getOperand(3).isDead()) return false.

spatel updated this revision to Diff 31089.Jul 30 2015, 4:49 PM
spatel edited edge metadata.

Patch updated based on feedback from Gerolf and Kevin (thanks!):

  1. Rename hasVirtualRegDefsInBasicBlock -> hasReassociableOperands (the function is more general now)
  2. Update comment on EFLAGS check to make it clearer (I hope)
  3. Add asserts about that 3rd operand which we assume must be EFLAGS
kbsmith1 accepted this revision.Jul 30 2015, 4:55 PM
kbsmith1 edited edge metadata.

LGTM

This revision is now accepted and ready to land.Jul 30 2015, 4:55 PM
spatel added inline comments.Jul 30 2015, 4:56 PM
lib/Target/X86/X86InstrInfo.cpp
6506 ↗(On Diff #31089)

Is it ok that I'm not explicitly adding a dead EFLAGS operand (if this is an integer instruction)? I see that the operand gets added later anyway based on the instruction type, but I wonder if it's poor form to not do it right here.

Gerolf accepted this revision.Jul 30 2015, 6:53 PM
Gerolf edited edge metadata.

The machine code verifier used the isDead flag, so my assumption would be that it is safe to assume it is set correctly at the point of use in this code. If there is a way to assert this that would be even better.

lib/Target/X86/X86InstrInfo.cpp
6309 ↗(On Diff #31089)

Thanks for the clarification.

spatel added inline comments.Jul 31 2015, 8:51 AM
lib/Target/X86/X86InstrInfo.cpp
6506 ↗(On Diff #31089)

For future reference: I stepped through this in the debugger, and the EFLAGS implicit operand is added when the instruction is created, so there does not appear to be any need to do this explicitly.

This revision was automatically updated to reflect the committed changes.