forked from OSchip/llvm-project
[AVX] Support VSINSERTF128 with more patterns and appropriate
infrastructure. This makes lowering 256-bit vectors to 128-bit vectors simple when 256-bit vector support is not available. llvm-svn: 124868
This commit is contained in:
parent
a522693f66
commit
653f1eed2d
|
@ -3281,6 +3281,25 @@ bool X86::isVEXTRACTF128Index(SDNode *N) {
|
|||
return Result;
|
||||
}
|
||||
|
||||
/// isVINSERTF128Index - Return true if the specified INSERT_SUBVECTOR
|
||||
/// operand specifies a subvector insert that is suitable for input to
|
||||
/// VINSERTF128.
|
||||
bool X86::isVINSERTF128Index(SDNode *N) {
|
||||
if (!isa<ConstantSDNode>(N->getOperand(2).getNode()))
|
||||
return false;
|
||||
|
||||
// The index should be aligned on a 128-bit boundary.
|
||||
uint64_t Index =
|
||||
cast<ConstantSDNode>(N->getOperand(2).getNode())->getZExtValue();
|
||||
|
||||
unsigned VL = N->getValueType(0).getVectorNumElements();
|
||||
unsigned VBits = N->getValueType(0).getSizeInBits();
|
||||
unsigned ElSize = VBits / VL;
|
||||
bool Result = (Index * ElSize) % 128 == 0;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle
|
||||
/// the specified VECTOR_SHUFFLE mask with PSHUF* and SHUFP* instructions.
|
||||
unsigned X86::getShuffleSHUFImmediate(SDNode *N) {
|
||||
|
@ -3367,6 +3386,24 @@ unsigned X86::getExtractVEXTRACTF128Immediate(SDNode *N) {
|
|||
return Index / NumElemsPerChunk;
|
||||
}
|
||||
|
||||
/// getInsertVINSERTF128Immediate - Return the appropriate immediate
|
||||
/// to insert at the specified INSERT_SUBVECTOR index with VINSERTF128
|
||||
/// instructions.
|
||||
unsigned X86::getInsertVINSERTF128Immediate(SDNode *N) {
|
||||
if (!isa<ConstantSDNode>(N->getOperand(2).getNode()))
|
||||
llvm_unreachable("Illegal insert subvector for VINSERTF128");
|
||||
|
||||
uint64_t Index =
|
||||
cast<ConstantSDNode>(N->getOperand(2).getNode())->getZExtValue();
|
||||
|
||||
EVT VecVT = N->getValueType(0);
|
||||
EVT ElVT = VecVT.getVectorElementType();
|
||||
|
||||
unsigned NumElemsPerChunk = 128 / ElVT.getSizeInBits();
|
||||
|
||||
return Index / NumElemsPerChunk;
|
||||
}
|
||||
|
||||
/// isZeroNode - Returns true if Elt is a constant zero or a floating point
|
||||
/// constant +0.0.
|
||||
bool X86::isZeroNode(SDValue Elt) {
|
||||
|
|
|
@ -413,6 +413,11 @@ namespace llvm {
|
|||
/// suitable for input to VEXTRACTF128.
|
||||
bool isVEXTRACTF128Index(SDNode *N);
|
||||
|
||||
/// isVINSERTF128Index - Return true if the specified
|
||||
/// INSERT_SUBVECTOR operand specifies a subvector insert that is
|
||||
/// suitable for input to VINSERTF128.
|
||||
bool isVINSERTF128Index(SDNode *N);
|
||||
|
||||
/// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle
|
||||
/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP*
|
||||
/// instructions.
|
||||
|
@ -435,6 +440,11 @@ namespace llvm {
|
|||
/// with VEXTRACTF128 instructions.
|
||||
unsigned getExtractVEXTRACTF128Immediate(SDNode *N);
|
||||
|
||||
/// getInsertVINSERTF128Immediate - Return the appropriate
|
||||
/// immediate to insert at the specified INSERT_SUBVECTOR index
|
||||
/// with VINSERTF128 instructions.
|
||||
unsigned getInsertVINSERTF128Immediate(SDNode *N);
|
||||
|
||||
/// isZeroNode - Returns true if Elt is a constant zero or a floating point
|
||||
/// constant +0.0.
|
||||
bool isZeroNode(SDValue Elt);
|
||||
|
|
|
@ -348,6 +348,12 @@ def EXTRACT_get_vextractf128_imm : SDNodeXForm<extract_subvector, [{
|
|||
return getI8Imm(X86::getExtractVEXTRACTF128Immediate(N));
|
||||
}]>;
|
||||
|
||||
// INSERT_get_vinsertf128_imm xform function: convert insert_subvector index to
|
||||
// VINSERTF128 imm.
|
||||
def INSERT_get_vinsertf128_imm : SDNodeXForm<insert_subvector, [{
|
||||
return getI8Imm(X86::getInsertVINSERTF128Immediate(N));
|
||||
}]>;
|
||||
|
||||
def splat_lo : PatFrag<(ops node:$lhs, node:$rhs),
|
||||
(vector_shuffle node:$lhs, node:$rhs), [{
|
||||
ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);
|
||||
|
@ -444,3 +450,10 @@ def vextractf128_extract : PatFrag<(ops node:$bigvec, node:$index),
|
|||
node:$index), [{
|
||||
return X86::isVEXTRACTF128Index(N);
|
||||
}], EXTRACT_get_vextractf128_imm>;
|
||||
|
||||
def vinsertf128_insert : PatFrag<(ops node:$bigvec, node:$smallvec,
|
||||
node:$index),
|
||||
(insert_subvector node:$bigvec, node:$smallvec,
|
||||
node:$index), [{
|
||||
return X86::isVINSERTF128Index(N);
|
||||
}], INSERT_get_vinsertf128_imm>;
|
||||
|
|
|
@ -5436,6 +5436,23 @@ def : Pat<(int_x86_avx_vinsertf128_ps_256 VR256:$src1, VR128:$src2, imm:$src3),
|
|||
def : Pat<(int_x86_avx_vinsertf128_si_256 VR256:$src1, VR128:$src2, imm:$src3),
|
||||
(VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
|
||||
|
||||
def : Pat<(vinsertf128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
|
||||
(i32 imm)),
|
||||
(VINSERTF128rr VR256:$src1, VR128:$src2,
|
||||
(INSERT_get_vinsertf128_imm VR256:$ins))>;
|
||||
def : Pat<(vinsertf128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
|
||||
(i32 imm)),
|
||||
(VINSERTF128rr VR256:$src1, VR128:$src2,
|
||||
(INSERT_get_vinsertf128_imm VR256:$ins))>;
|
||||
def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
|
||||
(i32 imm)),
|
||||
(VINSERTF128rr VR256:$src1, VR128:$src2,
|
||||
(INSERT_get_vinsertf128_imm VR256:$ins))>;
|
||||
def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
|
||||
(i32 imm)),
|
||||
(VINSERTF128rr VR256:$src1, VR128:$src2,
|
||||
(INSERT_get_vinsertf128_imm VR256:$ins))>;
|
||||
|
||||
def : Pat<(int_x86_avx_vextractf128_pd_256 VR256:$src1, imm:$src2),
|
||||
(VEXTRACTF128rr VR256:$src1, imm:$src2)>;
|
||||
def : Pat<(int_x86_avx_vextractf128_ps_256 VR256:$src1, imm:$src2),
|
||||
|
|
Loading…
Reference in New Issue