diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-08-17 22:12:20 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-08-17 22:12:20 +0000 |
commit | 1a87fcb9ba5189dc1702140eb3e152d6aa1d66e5 (patch) | |
tree | 9401cb99518c56036188c91a74e5fd50340d2b5a | |
parent | 5500ef27be0b033bef6bd0703be4807d61df0f70 (diff) | |
download | bcm5719-llvm-1a87fcb9ba5189dc1702140eb3e152d6aa1d66e5.tar.gz bcm5719-llvm-1a87fcb9ba5189dc1702140eb3e152d6aa1d66e5.zip |
Fix PR10688. Add support for spliting 256-bit vector shifts when the
shift amount is variable
llvm-svn: 137885
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 31 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/avx-shift.ll | 11 |
2 files changed, 31 insertions, 11 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index b330a4f9809..d1c71a86a08 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -9449,17 +9449,26 @@ SDValue X86TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) const { DAG, dl); // Recreate the shift amount vectors - SmallVector<SDValue, 4> Amt1Csts; - SmallVector<SDValue, 4> Amt2Csts; - for (int i = 0; i < NumElems/2; ++i) - Amt1Csts.push_back(Amt->getOperand(i)); - for (int i = NumElems/2; i < NumElems; ++i) - Amt2Csts.push_back(Amt->getOperand(i)); - - SDValue Amt1 = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, - &Amt1Csts[0], NumElems/2); - SDValue Amt2 = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, - &Amt2Csts[0], NumElems/2); + SDValue Amt1, Amt2; + if (Amt.getOpcode() == ISD::BUILD_VECTOR) { + // Constant shift amount + SmallVector<SDValue, 4> Amt1Csts; + SmallVector<SDValue, 4> Amt2Csts; + for (int i = 0; i < NumElems/2; ++i) + Amt1Csts.push_back(Amt->getOperand(i)); + for (int i = NumElems/2; i < NumElems; ++i) + Amt2Csts.push_back(Amt->getOperand(i)); + + Amt1 = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, + &Amt1Csts[0], NumElems/2); + Amt2 = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, + &Amt2Csts[0], NumElems/2); + } else { + // Variable shift amount + Amt1 = Extract128BitVector(Amt, DAG.getConstant(0, MVT::i32), DAG, dl); + Amt2 = Extract128BitVector(Amt, DAG.getConstant(NumElems/2, MVT::i32), + DAG, dl); + } // Issue new vector shifts for the smaller types V1 = DAG.getNode(Op.getOpcode(), dl, NewVT, V1, Amt1); diff --git a/llvm/test/CodeGen/X86/avx-shift.ll b/llvm/test/CodeGen/X86/avx-shift.ll index 791194fc1c7..3ea39a2358e 100644 --- a/llvm/test/CodeGen/X86/avx-shift.ll +++ b/llvm/test/CodeGen/X86/avx-shift.ll @@ -62,3 +62,14 @@ define <16 x i16> @vshift07(<16 x i16> %a) nounwind readnone { ret <16 x i16> %s } +;;; Support variable shifts +; CHECK: _vshift08 +; CHECK: vextractf128 $1 +; CHECK: vpslld $23 +; CHECK: vextractf128 $1 +; CHECK: vpslld $23 +define <8 x i32> @vshift08(<8 x i32> %a) nounwind { + %bitop = shl <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>, %a + ret <8 x i32> %bitop +} + |