This is an archive of the discontinued LLVM Phabricator instance.

[ARM] Check for correct HW div when lowering divmod
ClosedPublic

Authored by rovka on Apr 13 2017, 4:14 AM.

Details

Summary

For subtargets that use the custom lowering for divmod, e.g. gnueabi,
we used to check if the subtarget has hardware divide and then lower to
a div-mul-sub sequence if true, or to a libcall if false.

However, judging by the usage of hasDivide vs hasDivideInARMMode, it
seems that hasDivide only refers to Thumb. For instance, in the
ARMTargetLowering constructor, the code that specifies whether to use
libcalls for (S|U)DIV looks like this:

bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivide()
                                      : Subtarget->hasDivideInARMMode();

In the case of divmod for arm-gnueabi, using only hasDivide() to
determine what to do means that instead of lowering to _aeabi_idivmod
to get the remainder, we lower to div-mul-sub and then further lower the
div to _aeabi_idiv. Even worse, if we have hardware divide in ARM but
not in Thumb, we generate a libcall instead of using it (this is not an
issue in practice since AFAICT none of the cores that we support have
hardware divide in ARM but not Thumb).

This patch fixes the code dealing with custom lowering to take into
account the mode (Thumb or ARM) when deciding whether or not hardware
division is available.

Diff Detail

Repository
rL LLVM

Event Timeline

rovka created this revision.Apr 13 2017, 4:14 AM
rovka edited the summary of this revision. (Show Details)Apr 13 2017, 4:17 AM
compnerd accepted this revision.Apr 13 2017, 8:01 AM

Minor comments on the test, but LGTM otherwise.

test/CodeGen/ARM/divmod-hwdiv.ll
7 ↗(On Diff #95101)

I'm not sure I understand what the duplication here is for. The compilation mode is identical to the ones above. We should remove these I believe.

This revision is now accepted and ready to land.Apr 13 2017, 8:01 AM
rovka added a comment.Apr 13 2017, 8:59 AM

Thanks for the review

test/CodeGen/ARM/divmod-hwdiv.ll
7 ↗(On Diff #95101)

The difference is hwdiv (hardware divide in thumb) vs hwdiv-arm (hardware divide in arm). The first 4 lines check that hwdiv influences thumb, but not arm, and the last 4 check that hwdiv-arm influences arm, but not thumb.

This revision was automatically updated to reflect the committed changes.