From 0b4ab0cfe028bfab50a711316bdda89918c776b9 Mon Sep 17 00:00:00 2001 From: Kalle Raiskila Date: Wed, 8 Sep 2010 11:53:38 +0000 Subject: [PATCH] Fix CellSPU vector shuffles, again. Some cases of lowering to rotate were miscompiled. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113355 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/CellSPU/SPUISelLowering.cpp | 14 +++++++------- test/CodeGen/CellSPU/shuffles.ll | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index 46f31899be0..7bac3f5552a 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -1735,9 +1735,9 @@ static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { unsigned CurrElt = 0; unsigned MaxElts = VecVT.getVectorNumElements(); unsigned PrevElt = 0; - unsigned V0Elt = 0; bool monotonic = true; bool rotate = true; + int rotamt; EVT maskVT; // which of the c?d instructions to use if (EltVT == MVT::i8) { @@ -1781,14 +1781,13 @@ static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { if (PrevElt > 0 && SrcElt < MaxElts) { if ((PrevElt == SrcElt - 1) || (PrevElt == MaxElts - 1 && SrcElt == 0)) { + rotamt = SrcElt-i; PrevElt = SrcElt; - if (SrcElt == 0) - V0Elt = i; } else { rotate = false; } - } else if (i == 0) { - // First time through, need to keep track of previous element + } else if (i == 0 || (PrevElt==0 && SrcElt==1)) { + // First time or after a "wrap around" PrevElt = SrcElt; } else { // This isn't a rotation, takes elements from vector 2 @@ -1813,8 +1812,9 @@ static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V2, V1, ShufMaskOp); } else if (rotate) { - int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8; - + if (rotamt < 0) + rotamt +=MaxElts; + rotamt *= EltVT.getSizeInBits()/8; return DAG.getNode(SPUISD::ROTBYTES_LEFT, dl, V1.getValueType(), V1, DAG.getConstant(rotamt, MVT::i16)); } else { diff --git a/test/CodeGen/CellSPU/shuffles.ll b/test/CodeGen/CellSPU/shuffles.ll index f37d2ae89b0..94b5fbd6baa 100644 --- a/test/CodeGen/CellSPU/shuffles.ll +++ b/test/CodeGen/CellSPU/shuffles.ll @@ -39,3 +39,29 @@ define <4 x float> @test_insert_1(<4 x float> %vparam, float %eltparam) { ret <4 x float> %rv } +define <2 x i32> @test_v2i32(<4 x i32>%vec) +{ +;CHECK: rotqbyi $3, $3, 4 +;CHECK: bi $lr + %rv = shufflevector <4 x i32> %vec, <4 x i32> undef, <2 x i32> + ret <2 x i32> %rv +} + +define <4 x i32> @test_v4i32_rot8(<4 x i32>%vec) +{ +;CHECK: rotqbyi $3, $3, 8 +;CHECK: bi $lr + %rv = shufflevector <4 x i32> %vec, <4 x i32> undef, + <4 x i32> + ret <4 x i32> %rv +} + +define <4 x i32> @test_v4i32_rot4(<4 x i32>%vec) +{ +;CHECK: rotqbyi $3, $3, 4 +;CHECK: bi $lr + %rv = shufflevector <4 x i32> %vec, <4 x i32> undef, + <4 x i32> + ret <4 x i32> %rv +} +