This is an archive of the discontinued LLVM Phabricator instance.

[DAGCombiner] Recognise vector rotations with non-splat constants
ClosedPublic

Authored by andrew.zhogin on Jul 13 2017, 1:24 PM.

Details

Summary

Fix for bug 33691: https://bugs.llvm.org/show_bug.cgi?id=33691 .
Such code now will be converted into vector rotate operation:

%1 = lshr <4 x i32> %x, <i32 1, i32 2, i32 3, i32 4>
%2 = shl <4 x i32> %x, <i32 31, i32 30, i32 29, i32 28>
%3 = or <4 x i32> %1, %2

Diff Detail

Repository
rL LLVM

Event Timeline

andrew.zhogin created this revision.Jul 13 2017, 1:24 PM
RKSimon edited edge metadata.Jul 14 2017, 1:54 AM
RKSimon added a subscriber: llvm-commits.

Always add llvm-commits as a subscriber for llvm patches so that it has visibility on the mailing list (clang patches should subscribe cfe-commits instead)

There are a number of existing tests in files that should have been improved by this:

  • llvm\test\CodeGen\X86\combine-rotates.ll
  • llvm\test\CodeGen\X86\vector-rotate-128.ll
  • llvm\test\CodeGen\X86\vector-rotate-256.ll
RKSimon added inline comments.Jul 14 2017, 2:06 AM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
4708 ↗(On Diff #106507)

It would be tidier to merge this into the scalar/splat version above. Adding a predicate to pattern match all constants would be useful (and possibly reusable elsewhere - @majnemer has suggested a DAGCombiner equivalent of llvm::PatternMatch in the past).

The bitmasks should be creatable using SelectionDAG::FoldConstantArithmetic from logical shifts of the all ones mask and LHSShiftAmt/RHSShiftAmt.

Updated related CodeGen tests.
Implemented unified code for scalar/vector rotr combining.

RKSimon added inline comments.Jul 15 2017, 12:28 PM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
4672 ↗(On Diff #106781)

This can be done with

SDValue RHSBits = DAG.getNode(ISD::SRL, DL, VT, AllOnes, RHSShiftAmt);

(Taking AllOnes from the value initially assigned to Mask).

4677 ↗(On Diff #106781)

This can be done with

SDValue LHSBits = DAG.getNode(ISD::SHL, DL, VT, AllOnes, LHSShiftAmt);

(Taking AllOnes from the value initially assigned to Mask).

buildLoHiRotateVecBitmask helper function deleted, code inlined.

andrew.zhogin added inline comments.Jul 15 2017, 1:18 PM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
4677 ↗(On Diff #106781)

FoldConstantArithmetic is not necessary here?

RKSimon added inline comments.Jul 15 2017, 1:23 PM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
4672 ↗(On Diff #106781)

Probably safer to use getNode instead of FoldConstantArithmetic, same for below

4591 ↗(On Diff #106783)

There's no need for this to be part of DAGCombiner - just make it static and pass SelectionDAG& as an argument

4655 ↗(On Diff #106783)

Probably better to call this AllOnes not One

matchRotateSub converted into static function. getNode() instead of FoldConstantArithmetic for shift masks. "AllOnes" instead of "One".

andrew.zhogin marked 7 inline comments as done.Jul 15 2017, 1:42 PM
RKSimon accepted this revision.Jul 15 2017, 2:22 PM

LGTM - thanks

This revision is now accepted and ready to land.Jul 15 2017, 2:22 PM
This revision was automatically updated to reflect the committed changes.