This is an archive of the discontinued LLVM Phabricator instance.

[X86] 8bit divrem: Improve codegen for AH register extraction.
ClosedPublic

Authored by ab on Oct 31 2014, 1:30 PM.

Details

Summary

For 8-bit divrems where the remainder is used, we used to generate:

divb  %sil
shrw  $8, %ax
movzbl  %al, %eax

That was to avoid an H-reg access, which is problematic mainly because
it isn't possible in REX-prefixed instructions.

This patch optimizes that to:

divb  %sil
movzbl  %ah, %eax

To do that, we explicitly extend AH, and extract the L-subreg in the
resulting register. The extension is done using the NOREX variants of
MOVZX. To support signed operations, MOVSX_NOREX is also added.
Further, this introduces a new SDNode type, [us]divrem_ext_hreg, which is
then lowered to a sequence containing a single zext (rather than 2).

The new node isn't ideal, but I'm not aware of any alternatives to avoid redundant extensions.

Diff Detail

Repository
rL LLVM

Event Timeline

ab updated this revision to Diff 15643.Oct 31 2014, 1:30 PM
ab retitled this revision from to [X86] 8bit divrem: Improve codegen for AH register extraction..
ab updated this object.
ab edited the test plan for this revision. (Show Details)
ab added reviewers: lhames, qcolombet.
ab added a subscriber: Unknown Object (MLST).
ab updated this revision to Diff 15668.Nov 1 2014, 11:47 AM

Remove support for 64-bit sexts: those are impossible from h-regs.

I had previously added a subreg_to_reg to also support i64 extensions for free. But I just had a flash where I remembered that we still need to explicitly movsx to a 64-bit register.

While there, remove useless ops vectors.

qcolombet edited edge metadata.Nov 3 2014, 10:32 AM

Hi Ahmed,

I am wondering if you did not miss to include some files in the diff. I may be wrong but I would have expected to see some definitions of DAG nodes for SDIVREM8_SEXT_HREG and UDIVREM8_ZEXT_HREG.

Other comments inlined.

Thanks,
-Quentin

lib/Target/X86/X86ISelDAGToDAG.cpp
2545 ↗(On Diff #15668)

You slightly change the condition here by removing Subtarget->is64Bit().
I believe this is correct, but you need to add a test case for that.

2574 ↗(On Diff #15668)

Now that you are done, does this debug line still make sense?

test/CodeGen/X86/divrem8_ext.ll
1 ↗(On Diff #15668)

Do a x86_64 run and a i386 to test the change in the condition of the lowering of U/SREM.

ab updated this revision to Diff 15721.Nov 3 2014, 11:20 AM
ab edited edge metadata.

Also test i386 codegen.

ab updated this revision to Diff 15722.Nov 3 2014, 11:22 AM

Remove .td node definition.

ab added a comment.Nov 3 2014, 11:25 AM

Hi Quentin,

I added 32-bit checks.
However, for the node definitions, are you talking about TableGen? If so, I didn't add those because I don't expect the added node types to be ever referenced in TableGen. I can still add them for consistency though, if you'd like.

Thanks for the review!

-Ahmed

lib/Target/X86/X86ISelDAGToDAG.cpp
2545 ↗(On Diff #15668)

Right, I didn't explicitly check 32-bit. Added in the test file.

2574 ↗(On Diff #15668)

This is modeled after the debug outputs in the other parts of the code (for instance line 2582).

qcolombet accepted this revision.Nov 3 2014, 11:34 AM
qcolombet edited edge metadata.

I added 32-bit checks.

Thanks.

However, for the node definitions, are you talking about TableGen?

Yes, I was talking about that.

If so, I didn't add those because I don't expect the added node types to be ever referenced in TableGen. I can still add them for consistency though, if you'd like.

Fair enough, that is fine :).

LGTM then.

Thanks,
-Quentin

This revision is now accepted and ready to land.Nov 3 2014, 11:34 AM
ab closed this revision.Nov 3 2014, 12:37 PM
ab updated this revision to Diff 15727.

Closed by commit rL221176 (authored by @ab).