diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td --- a/llvm/include/llvm/Target/TargetSelectionDAG.td +++ b/llvm/include/llvm/Target/TargetSelectionDAG.td @@ -268,6 +268,10 @@ SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3> ]>; +def SDTSubVecExtract2 : SDTypeProfile<1, 2, [// subvector extract + SDTCisVec<0>, SDTCisVec<1>, SDTCisInt<2> +]>; + def SDTPrefetch : SDTypeProfile<0, 4, [ // prefetch SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisInt<1> ]>; @@ -690,6 +694,9 @@ def extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>; def insert_subvector : SDNode<"ISD::INSERT_SUBVECTOR", SDTSubVecInsert, []>; +// Extract/Insert fixed length subvector form scalable vector. +def extract_subvector2 : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract2, []>; + // Nodes for intrinsics, you should use the intrinsic itself and let tblgen use // these internally. Don't reference these directly. def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID", diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -3522,6 +3522,11 @@ if (VT.isScalableVector() || InVT.isFixedLengthVector()) break; + // Bail when extracting from unpacked vector types. + if (InVT.isScalableVector() && + InVT.getSizeInBits().getKnownMinValue() != AArch64::SVEBitsPerBlock) + break; + // NOTE: We can only get here when doing fixed length SVE code generation. // We do manual selection because the types involved are not linked to real // registers (despite being legal) and must be coerced into SVE registers. diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -11403,7 +11403,7 @@ if (InVT.isScalableVector()) { // This will be matched by custom code during ISelDAGToDAG. - if (Idx == 0 && isPackedVectorType(InVT, DAG)) + if (Idx == 0)// && isPackedVectorType(InVT, DAG)) return Op; return SDValue(); diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -7940,22 +7940,22 @@ (v16i8 (REV16v16i8 FPR128:$src))>; } -def : Pat<(v4i16 (extract_subvector V128:$Rn, (i64 0))), - (EXTRACT_SUBREG V128:$Rn, dsub)>; -def : Pat<(v8i8 (extract_subvector V128:$Rn, (i64 0))), - (EXTRACT_SUBREG V128:$Rn, dsub)>; -def : Pat<(v2f32 (extract_subvector V128:$Rn, (i64 0))), - (EXTRACT_SUBREG V128:$Rn, dsub)>; -def : Pat<(v4f16 (extract_subvector V128:$Rn, (i64 0))), - (EXTRACT_SUBREG V128:$Rn, dsub)>; -def : Pat<(v4bf16 (extract_subvector V128:$Rn, (i64 0))), - (EXTRACT_SUBREG V128:$Rn, dsub)>; -def : Pat<(v2i32 (extract_subvector V128:$Rn, (i64 0))), - (EXTRACT_SUBREG V128:$Rn, dsub)>; -def : Pat<(v1i64 (extract_subvector V128:$Rn, (i64 0))), - (EXTRACT_SUBREG V128:$Rn, dsub)>; -def : Pat<(v1f64 (extract_subvector V128:$Rn, (i64 0))), - (EXTRACT_SUBREG V128:$Rn, dsub)>; +//def : Pat<(v4i16 (extract_subvector V128:$Rn, (i64 0))), +// (EXTRACT_SUBREG V128:$Rn, dsub)>; +//def : Pat<(v8i8 (extract_subvector V128:$Rn, (i64 0))), +// (EXTRACT_SUBREG V128:$Rn, dsub)>; +//def : Pat<(v2f32 (extract_subvector V128:$Rn, (i64 0))), +// (EXTRACT_SUBREG V128:$Rn, dsub)>; +//def : Pat<(v4f16 (extract_subvector V128:$Rn, (i64 0))), +// (EXTRACT_SUBREG V128:$Rn, dsub)>; +//def : Pat<(v4bf16 (extract_subvector V128:$Rn, (i64 0))), +// (EXTRACT_SUBREG V128:$Rn, dsub)>; +//def : Pat<(v2i32 (extract_subvector V128:$Rn, (i64 0))), +// (EXTRACT_SUBREG V128:$Rn, dsub)>; +//def : Pat<(v1i64 (extract_subvector V128:$Rn, (i64 0))), +// (EXTRACT_SUBREG V128:$Rn, dsub)>; +//def : Pat<(v1f64 (extract_subvector V128:$Rn, (i64 0))), +// (EXTRACT_SUBREG V128:$Rn, dsub)>; def : Pat<(v8i8 (extract_subvector (v16i8 FPR128:$Rn), (i64 1))), (EXTRACT_SUBREG (DUPv2i64lane FPR128:$Rn, 1), dsub)>; diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -1422,6 +1422,10 @@ def : Pat<(nxv2bf16 (extract_subvector (nxv8bf16 ZPR:$Zs), (i64 6))), (UUNPKHI_ZZ_D (UUNPKHI_ZZ_S ZPR:$Zs))>; + // Extract fixed length subvector from FP SVE vectors + def : Pat<(v2f32 (extract_subvector2 (nxv2f32 ZPR:$Zs), (i64 0))), + (XTNv2i32 (v2f64 (EXTRACT_SUBREG ZPR:$Zs, zsub)))>; + // Concatenate two predicates. def : Pat<(nxv4i1 (concat_vectors nxv2i1:$p1, nxv2i1:$p2)), (UZP1_PPP_S $p1, $p2)>;