mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Lower CONCAT_VECTOR during legalization instead of matching it during isel.
Add a testcase. llvm-svn: 77992
This commit is contained in:
parent
1b274fd5f0
commit
eb3b616a7e
@ -1267,27 +1267,6 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
|
||||
MVT::Other, Ops, 3);
|
||||
}
|
||||
|
||||
case ISD::CONCAT_VECTORS: {
|
||||
MVT VT = Op.getValueType();
|
||||
assert(VT.is128BitVector() && Op.getNumOperands() == 2 &&
|
||||
"unexpected CONCAT_VECTORS");
|
||||
SDValue N0 = Op.getOperand(0);
|
||||
SDValue N1 = Op.getOperand(1);
|
||||
SDNode *Result =
|
||||
CurDAG->getTargetNode(TargetInstrInfo::IMPLICIT_DEF, dl, VT);
|
||||
if (N0.getOpcode() != ISD::UNDEF)
|
||||
Result = CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG, dl, VT,
|
||||
SDValue(Result, 0), N0,
|
||||
CurDAG->getTargetConstant(arm_dsubreg_0,
|
||||
MVT::i32));
|
||||
if (N1.getOpcode() != ISD::UNDEF)
|
||||
Result = CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG, dl, VT,
|
||||
SDValue(Result, 0), N1,
|
||||
CurDAG->getTargetConstant(arm_dsubreg_1,
|
||||
MVT::i32));
|
||||
return Result;
|
||||
}
|
||||
|
||||
case ISD::VECTOR_SHUFFLE: {
|
||||
MVT VT = Op.getValueType();
|
||||
|
||||
|
@ -2312,10 +2312,24 @@ static SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
|
||||
return DAG.getNode(ISD::TRUNCATE, dl, VT, Op);
|
||||
}
|
||||
|
||||
static SDValue LowerCONCAT_VECTORS(SDValue Op) {
|
||||
if (Op.getValueType().is128BitVector() && Op.getNumOperands() == 2)
|
||||
return Op;
|
||||
return SDValue();
|
||||
static SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) {
|
||||
// The only time a CONCAT_VECTORS operation can have legal types is when
|
||||
// two 64-bit vectors are concatenated to a 128-bit vector.
|
||||
assert(Op.getValueType().is128BitVector() && Op.getNumOperands() == 2 &&
|
||||
"unexpected CONCAT_VECTORS");
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
SDValue Val = DAG.getUNDEF(MVT::v2f64);
|
||||
SDValue Op0 = Op.getOperand(0);
|
||||
SDValue Op1 = Op.getOperand(1);
|
||||
if (Op0.getOpcode() != ISD::UNDEF)
|
||||
Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
|
||||
DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, Op0),
|
||||
DAG.getIntPtrConstant(0));
|
||||
if (Op1.getOpcode() != ISD::UNDEF)
|
||||
Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val,
|
||||
DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, Op1),
|
||||
DAG.getIntPtrConstant(1));
|
||||
return DAG.getNode(ISD::BIT_CONVERT, dl, Op.getValueType(), Val);
|
||||
}
|
||||
|
||||
SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||
@ -2351,7 +2365,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||
case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
|
||||
case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG);
|
||||
case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG);
|
||||
case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op);
|
||||
case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
|
||||
}
|
||||
return SDValue();
|
||||
}
|
||||
|
36
test/CodeGen/ARM/vcombine.ll
Normal file
36
test/CodeGen/ARM/vcombine.ll
Normal file
@ -0,0 +1,36 @@
|
||||
; RUN: llvm-as < %s | llc -march=arm -mattr=+neon
|
||||
|
||||
define <16 x i8> @vcombine8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
|
||||
%tmp1 = load <8 x i8>* %A
|
||||
%tmp2 = load <8 x i8>* %B
|
||||
%tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
|
||||
ret <16 x i8> %tmp3
|
||||
}
|
||||
|
||||
define <8 x i16> @vcombine16(<4 x i16>* %A, <4 x i16>* %B) nounwind {
|
||||
%tmp1 = load <4 x i16>* %A
|
||||
%tmp2 = load <4 x i16>* %B
|
||||
%tmp3 = shufflevector <4 x i16> %tmp1, <4 x i16> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
|
||||
ret <8 x i16> %tmp3
|
||||
}
|
||||
|
||||
define <4 x i32> @vcombine32(<2 x i32>* %A, <2 x i32>* %B) nounwind {
|
||||
%tmp1 = load <2 x i32>* %A
|
||||
%tmp2 = load <2 x i32>* %B
|
||||
%tmp3 = shufflevector <2 x i32> %tmp1, <2 x i32> %tmp2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
||||
ret <4 x i32> %tmp3
|
||||
}
|
||||
|
||||
define <4 x float> @vcombinefloat(<2 x float>* %A, <2 x float>* %B) nounwind {
|
||||
%tmp1 = load <2 x float>* %A
|
||||
%tmp2 = load <2 x float>* %B
|
||||
%tmp3 = shufflevector <2 x float> %tmp1, <2 x float> %tmp2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
||||
ret <4 x float> %tmp3
|
||||
}
|
||||
|
||||
define <2 x i64> @vcombine64(<1 x i64>* %A, <1 x i64>* %B) nounwind {
|
||||
%tmp1 = load <1 x i64>* %A
|
||||
%tmp2 = load <1 x i64>* %B
|
||||
%tmp3 = shufflevector <1 x i64> %tmp1, <1 x i64> %tmp2, <2 x i32> <i32 0, i32 1>
|
||||
ret <2 x i64> %tmp3
|
||||
}
|
Loading…
Reference in New Issue
Block a user