diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-02-09 20:34:59 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-02-09 20:34:59 +0000 |
| commit | 6bf7b30b10f5c75c26617d183ade28558b4e3ffc (patch) | |
| tree | f5234f0b698ade4d313a13163fedd26bc0646da2 /llvm/lib | |
| parent | 586ad01fb68c793a766f10257fe2b2ddc2fba5dd (diff) | |
| download | bcm5719-llvm-6bf7b30b10f5c75c26617d183ade28558b4e3ffc.tar.gz bcm5719-llvm-6bf7b30b10f5c75c26617d183ade28558b4e3ffc.zip | |
[X86] CombineOr - fold to generic funnel shifts
As discussed on D57389, this is a first step towards moving the SHLD/SHRD matching code to DAGCombiner using FSHL/FSHR instead.
There's a bit of work to do before I can do that, so this just folds to FSHL/FSHR in the existing code (handling the different SHRD/FSHR argument ordering), which fixes the issue we had with i16 shift amounts not being correctly masked.
llvm-svn: 353626
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 635407112cf..d96645f4433 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -37277,23 +37277,30 @@ static SDValue combineOr(SDNode *N, SelectionDAG &DAG, ShAmt1 = ShAmt1.getOperand(0); SDLoc DL(N); - unsigned Opc = X86ISD::SHLD; + unsigned Opc = ISD::FSHL; SDValue Op0 = N0.getOperand(0); SDValue Op1 = N1.getOperand(0); - if (ShAmt0.getOpcode() == ISD::SUB || - ShAmt0.getOpcode() == ISD::XOR) { - Opc = X86ISD::SHRD; + if (ShAmt0.getOpcode() == ISD::SUB || ShAmt0.getOpcode() == ISD::XOR) { + Opc = ISD::FSHR; std::swap(Op0, Op1); std::swap(ShAmt0, ShAmt1); std::swap(ShMsk0, ShMsk1); } - // OR( SHL( X, C ), SRL( Y, 32 - C ) ) -> SHLD( X, Y, C ) - // OR( SRL( X, C ), SHL( Y, 32 - C ) ) -> SHRD( X, Y, C ) - // OR( SHL( X, C ), SRL( SRL( Y, 1 ), XOR( C, 31 ) ) ) -> SHLD( X, Y, C ) - // OR( SRL( X, C ), SHL( SHL( Y, 1 ), XOR( C, 31 ) ) ) -> SHRD( X, Y, C ) - // OR( SHL( X, AND( C, 31 ) ), SRL( Y, AND( 0 - C, 31 ) ) ) -> SHLD( X, Y, C ) - // OR( SRL( X, AND( C, 31 ) ), SHL( Y, AND( 0 - C, 31 ) ) ) -> SHRD( X, Y, C ) + auto GetFunnelShift = [&DAG, &DL, VT, Opc](SDValue Op0, SDValue Op1, + SDValue Amt) { + if (Opc == ISD::FSHR) + std::swap(Op0, Op1); + return DAG.getNode(Opc, DL, VT, Op0, Op1, + DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, Amt)); + }; + + // OR( SHL( X, C ), SRL( Y, 32 - C ) ) -> FSHL( X, Y, C ) + // OR( SRL( X, C ), SHL( Y, 32 - C ) ) -> FSHR( Y, X, C ) + // OR( SHL( X, C ), SRL( SRL( Y, 1 ), XOR( C, 31 ) ) ) -> FSHL( X, Y, C ) + // OR( SRL( X, C ), SHL( SHL( Y, 1 ), XOR( C, 31 ) ) ) -> FSHR( Y, X, C ) + // OR( SHL( X, AND( C, 31 ) ), SRL( Y, AND( 0 - C, 31 ) ) ) -> FSHL( X, Y, C ) + // OR( SRL( X, AND( C, 31 ) ), SHL( Y, AND( 0 - C, 31 ) ) ) -> FSHR( Y, X, C ) if (ShAmt1.getOpcode() == ISD::SUB) { SDValue Sum = ShAmt1.getOperand(0); if (auto *SumC = dyn_cast<ConstantSDNode>(Sum)) { @@ -37303,20 +37310,16 @@ static SDValue combineOr(SDNode *N, SelectionDAG &DAG, if ((SumC->getAPIntValue() == Bits || (SumC->getAPIntValue() == 0 && ShMsk1)) && ShAmt1Op1 == ShAmt0) - return DAG.getNode(Opc, DL, VT, Op0, Op1, - DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, ShAmt0)); + return GetFunnelShift(Op0, Op1, ShAmt0); } } else if (auto *ShAmt1C = dyn_cast<ConstantSDNode>(ShAmt1)) { auto *ShAmt0C = dyn_cast<ConstantSDNode>(ShAmt0); if (ShAmt0C && (ShAmt0C->getSExtValue() + ShAmt1C->getSExtValue()) == Bits) - return DAG.getNode(Opc, DL, VT, - N0.getOperand(0), N1.getOperand(0), - DAG.getNode(ISD::TRUNCATE, DL, - MVT::i8, ShAmt0)); + return GetFunnelShift(Op0, Op1, ShAmt0); } else if (ShAmt1.getOpcode() == ISD::XOR) { SDValue Mask = ShAmt1.getOperand(1); if (auto *MaskC = dyn_cast<ConstantSDNode>(Mask)) { - unsigned InnerShift = (X86ISD::SHLD == Opc ? ISD::SRL : ISD::SHL); + unsigned InnerShift = (ISD::FSHL == Opc ? ISD::SRL : ISD::SHL); SDValue ShAmt1Op0 = ShAmt1.getOperand(0); if (ShAmt1Op0.getOpcode() == ISD::TRUNCATE) ShAmt1Op0 = ShAmt1Op0.getOperand(0); @@ -37325,14 +37328,12 @@ static SDValue combineOr(SDNode *N, SelectionDAG &DAG, if (Op1.getOpcode() == InnerShift && isa<ConstantSDNode>(Op1.getOperand(1)) && Op1.getConstantOperandVal(1) == 1) { - return DAG.getNode(Opc, DL, VT, Op0, Op1.getOperand(0), - DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, ShAmt0)); + return GetFunnelShift(Op0, Op1.getOperand(0), ShAmt0); } // Test for ADD( Y, Y ) as an equivalent to SHL( Y, 1 ). if (InnerShift == ISD::SHL && Op1.getOpcode() == ISD::ADD && Op1.getOperand(0) == Op1.getOperand(1)) { - return DAG.getNode(Opc, DL, VT, Op0, Op1.getOperand(0), - DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, ShAmt0)); + return GetFunnelShift(Op0, Op1.getOperand(0), ShAmt0); } } } |

