[PowerPC] Generate VSX permutations for v2[fi]64 vectors

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204873 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hal Finkel 2014-03-26 22:58:37 +00:00
parent 7c38741035
commit ee5f4bb6b3
4 changed files with 110 additions and 5 deletions

View File

@ -1335,6 +1335,43 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
return CurDAG->SelectNodeTo(N, PPC::XXSEL, N->getValueType(0), Ops, 3);
}
break;
case ISD::VECTOR_SHUFFLE:
if (PPCSubTarget.hasVSX() && (N->getValueType(0) == MVT::v2f64 ||
N->getValueType(0) == MVT::v2i64)) {
ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N);
SDValue Op1 = N->getOperand(SVN->getMaskElt(0) < 2 ? 0 : 1),
Op2 = N->getOperand(SVN->getMaskElt(1) < 2 ? 0 : 1);
unsigned DM[2];
for (int i = 0; i < 2; ++i)
if (SVN->getMaskElt(i) <= 0 || SVN->getMaskElt(i) == 2)
DM[i] = 0;
else
DM[i] = 1;
SDValue DMV = CurDAG->getTargetConstant(DM[0] | (DM[1] << 1), MVT::i32);
if (Op1 == Op2 && DM[0] == 0 && DM[1] == 0 &&
Op1.getOpcode() == ISD::SCALAR_TO_VECTOR &&
isa<LoadSDNode>(Op1.getOperand(0))) {
LoadSDNode *LD = cast<LoadSDNode>(Op1.getOperand(0));
SDValue Base, Offset;
if (LD->isUnindexed() &&
SelectAddrIdxOnly(LD->getBasePtr(), Base, Offset)) {
SDValue Chain = LD->getChain();
SDValue Ops[] = { Base, Offset, Chain };
return CurDAG->SelectNodeTo(N, PPC::LXVDSX,
N->getValueType(0), Ops, 3);
}
}
SDValue Ops[] = { Op1, Op2, DMV };
return CurDAG->SelectNodeTo(N, PPC::XXPERMDI, N->getValueType(0), Ops, 3);
}
break;
case PPCISD::BDNZ:
case PPCISD::BDZ: {

View File

@ -570,6 +570,8 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
setOperationAction(ISD::LOAD, MVT::v2f64, Legal);
setOperationAction(ISD::STORE, MVT::v2f64, Legal);
setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2f64, Legal);
addRegisterClass(MVT::f64, &PPC::VSRCRegClass);
addRegisterClass(MVT::v4f32, &PPC::VSRCRegClass);
@ -584,6 +586,8 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
setOperationAction(ISD::STORE, MVT::v2i64, Promote);
AddPromotedToType (ISD::STORE, MVT::v2i64, MVT::v2f64);
setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2i64, Legal);
setOperationAction(ISD::SINT_TO_FP, MVT::v2i64, Legal);
setOperationAction(ISD::UINT_TO_FP, MVT::v2i64, Legal);
setOperationAction(ISD::FP_TO_SINT, MVT::v2i64, Legal);
@ -872,8 +876,8 @@ bool PPC::isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, bool isUnary) {
///
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize,
unsigned LHSStart, unsigned RHSStart) {
assert(N->getValueType(0) == MVT::v16i8 &&
"PPC only supports shuffles by bytes!");
if (N->getValueType(0) != MVT::v16i8)
return false;
assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
"Unsupported merge size!");
@ -910,8 +914,8 @@ bool PPC::isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize,
/// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
/// amount, otherwise return -1.
int PPC::isVSLDOIShuffleMask(SDNode *N, bool isUnary) {
assert(N->getValueType(0) == MVT::v16i8 &&
"PPC only supports shuffles by bytes!");
if (N->getValueType(0) != MVT::v16i8)
return false;
ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);

View File

@ -53,7 +53,6 @@ let Uses = [RM] in {
def LXVDSX : XForm_1<31, 332,
(outs vsrc:$XT), (ins memrr:$src),
"lxvdsx $XT, $src", IIC_LdStLFD, []>;
// TODO: match load + splat to lxvdsx.
def LXVW4X : XForm_1<31, 780,
(outs vsrc:$XT), (ins memrr:$src),

View File

@ -422,3 +422,68 @@ define <2 x i64> @test47(<2 x float> %a) {
; CHECK: blr
}
define <2 x double> @test50(double* %a) {
%v = load double* %a, align 8
%w = insertelement <2 x double> undef, double %v, i32 0
%x = insertelement <2 x double> %w, double %v, i32 1
ret <2 x double> %x
; CHECK-LABEL: @test50
; CHECK: lxvdsx 34, 0, 3
; CHECK: blr
}
define <2 x double> @test51(<2 x double> %a, <2 x double> %b) {
%v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 0, i32 0>
ret <2 x double> %v
; CHECK-LABEL: @test51
; CHECK: xxpermdi 34, 34, 34, 0
; CHECK: blr
}
define <2 x double> @test52(<2 x double> %a, <2 x double> %b) {
%v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 0, i32 2>
ret <2 x double> %v
; CHECK-LABEL: @test52
; CHECK: xxpermdi 34, 34, 35, 0
; CHECK: blr
}
define <2 x double> @test53(<2 x double> %a, <2 x double> %b) {
%v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 2, i32 0>
ret <2 x double> %v
; CHECK-LABEL: @test53
; CHECK: xxpermdi 34, 35, 34, 0
; CHECK: blr
}
define <2 x double> @test54(<2 x double> %a, <2 x double> %b) {
%v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 2>
ret <2 x double> %v
; CHECK-LABEL: @test54
; CHECK: xxpermdi 34, 34, 35, 1
; CHECK: blr
}
define <2 x double> @test55(<2 x double> %a, <2 x double> %b) {
%v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 3>
ret <2 x double> %v
; CHECK-LABEL: @test55
; CHECK: xxpermdi 34, 34, 35, 3
; CHECK: blr
}
define <2 x i64> @test56(<2 x i64> %a, <2 x i64> %b) {
%v = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
ret <2 x i64> %v
; CHECK-LABEL: @test56
; CHECK: xxpermdi 34, 34, 35, 3
; CHECK: blr
}