This is an archive of the discontinued LLVM Phabricator instance.

Emit a left-shift instead of a power-of-two multiply for jump-tables
ClosedPublic

Authored by arichardson on Apr 18 2018, 3:23 AM.

Details

Summary

SelectionDAGLegalize::ExpandNode() inserts an ISD::MUL when lowering a
BR_JT opcode. While many backends optimize this multiply into a shift, e.g.
the MIPS backend currently always lowers this into a sequence of
load-immediate+multiply+mflo in MipsSETargetLowering::lowerMulDiv().

I initially changed the multiply to a shift in the MIPS backend but it
turns out that would not have handled the MIPSR6 case and was a lot more
code than doing it in LegalizeDAG.
I believe performing this simple optimization in LegalizeDAG instead of
each individual backend is the better solution since this also fixes other
backeds such as MSP430 which calls the multiply runtime function
__mspabi_mpyi without this patch.

Diff Detail

Event Timeline

arichardson created this revision.Apr 18 2018, 3:23 AM
sdardis requested changes to this revision.Apr 19 2018, 2:14 AM

I think we need to modify LegalizeDAG .cpp here directly to eliminate the multiplication, as the legalizer has legalized the ISD::BR_JT into an address synthesis, load and multiplication. The legalizer then recursively legalizes the multiplication into a mult/mflo pair.

Another option would be to provide a MipsPat to match the case of multiplication by a constant followed by a mflo, and where the constant is a power of 2 replace it with a shift of the variable operand to multiplication. That approach would be private to the MIPS backend.

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
3692–3694

If you look at DAGCombine.cpp:2667, you'll see the folding of

fold (mul x, (1 << c)) -> x << c

so, if the jump table entry size is a power of two, Index can become a left shift of the log2 of size of the jump table entry, otherwise the multiplication is ok.

lib/Target/Mips/MipsSEISelLowering.cpp
1230–1242

This isn't particularly great as it misses the case where we have a MIPSR6 target, as we don't use this function to perform lowering for that target.

test/CodeGen/Mips/jump-table-mul.ll
3

Spurious RUN: line. If you mean to test the output of -debug, this test also needs: "REQUIRES: asserts", and a FileCheck invocation with a unique prefix.

6

You can remove this.

7

local_unnamed_addr #0 is spurious.

72

this can be dropped.

This revision now requires changes to proceed.Apr 19 2018, 2:14 AM
arichardson marked 3 inline comments as done.
arichardson retitled this revision from [MIPS] Emit a left-shift instead of a power-of-two multiply for jump-tables to Emit a left-shift instead of a power-of-two multiply for jump-tables.
arichardson edited the summary of this revision. (Show Details)
arichardson added reviewers: pftbest, asl.

Perform the optimization in LegalizeDAG instead. Turns out this also fixes MSP430

sdardis added inline comments.Apr 24 2018, 5:53 AM
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
3700–3707

You drop the braces for this if/else pair as they're each a single statement.

arichardson marked an inline comment as done.
arichardson edited the summary of this revision. (Show Details)

Address review comment

sdardis accepted this revision.May 15 2018, 8:58 AM

LGTM.

This revision is now accepted and ready to land.May 15 2018, 8:58 AM
This revision was automatically updated to reflect the committed changes.