diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-12-13 11:20:48 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-12-13 11:20:48 +0000 |
commit | 77fc551d1aba7765a29f0b31790e5aebe5380ea5 (patch) | |
tree | 4ebbfaa7e6605926bfcacc572baf257dd46dd3d6 /llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | |
parent | fe3015d1642db94edb8b953fa2b98704930cc477 (diff) | |
download | bcm5719-llvm-77fc551d1aba7765a29f0b31790e5aebe5380ea5.tar.gz bcm5719-llvm-77fc551d1aba7765a29f0b31790e5aebe5380ea5.zip |
[TargetLowering] Add ISD::ROTL/ROTR vector expansion
Move existing rotation expansion code into TargetLowering and set it up for vectors as well.
Ideally this would share more of the funnel shift expansion, but we handle the shift amount modulo quite differently at the moment.
Begun removing x86 vector rotate custom lowering to use the expansion.
llvm-svn: 349025
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 45 |
1 files changed, 5 insertions, 40 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index f1c6d63982e..9d6a6939fba 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3275,6 +3275,11 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) { if (TLI.expandFunnelShift(Node, Tmp1, DAG)) Results.push_back(Tmp1); break; + case ISD::ROTL: + case ISD::ROTR: + if (TLI.expandROT(Node, Tmp1, DAG)) + Results.push_back(Tmp1); + break; case ISD::SADDSAT: case ISD::UADDSAT: case ISD::SSUBSAT: @@ -3725,46 +3730,6 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) { ReplaceNode(SDValue(Node, 0), Result); break; } - case ISD::ROTL: - case ISD::ROTR: { - bool IsLeft = Node->getOpcode() == ISD::ROTL; - SDValue Op0 = Node->getOperand(0), Op1 = Node->getOperand(1); - EVT ResVT = Node->getValueType(0); - EVT OpVT = Op0.getValueType(); - assert(OpVT == ResVT && - "The result and the operand types of rotate should match"); - EVT ShVT = Op1.getValueType(); - SDValue Width = DAG.getConstant(OpVT.getScalarSizeInBits(), dl, ShVT); - - // If a rotate in the other direction is legal, use it. - unsigned RevRot = IsLeft ? ISD::ROTR : ISD::ROTL; - if (TLI.isOperationLegal(RevRot, ResVT)) { - SDValue Sub = DAG.getNode(ISD::SUB, dl, ShVT, Width, Op1); - Results.push_back(DAG.getNode(RevRot, dl, ResVT, Op0, Sub)); - break; - } - - // Otherwise, - // (rotl x, c) -> (or (shl x, (and c, w-1)), (srl x, (and w-c, w-1))) - // (rotr x, c) -> (or (srl x, (and c, w-1)), (shl x, (and w-c, w-1))) - // - assert(isPowerOf2_32(OpVT.getScalarSizeInBits()) && - "Expecting the type bitwidth to be a power of 2"); - unsigned ShOpc = IsLeft ? ISD::SHL : ISD::SRL; - unsigned HsOpc = IsLeft ? ISD::SRL : ISD::SHL; - SDValue Width1 = DAG.getNode(ISD::SUB, dl, ShVT, - Width, DAG.getConstant(1, dl, ShVT)); - SDValue NegOp1 = DAG.getNode(ISD::SUB, dl, ShVT, Width, Op1); - SDValue And0 = DAG.getNode(ISD::AND, dl, ShVT, Op1, Width1); - SDValue And1 = DAG.getNode(ISD::AND, dl, ShVT, NegOp1, Width1); - - SDValue Or = DAG.getNode(ISD::OR, dl, ResVT, - DAG.getNode(ShOpc, dl, ResVT, Op0, And0), - DAG.getNode(HsOpc, dl, ResVT, Op0, And1)); - Results.push_back(Or); - break; - } - case ISD::GLOBAL_OFFSET_TABLE: case ISD::GlobalAddress: case ISD::GlobalTLSAddress: |