@@ -7348,6 +7348,37 @@ SDValue AArch64TargetLowering::LowerLOAD(SDValue Op,
73487348 return SDValue();
73497349}
73507350
7351+ // Convert to ContainerVT with no-op casts where possible.
7352+ static SDValue convertToSVEContainerType(SDLoc DL, SDValue Vec, EVT ContainerVT,
7353+ SelectionDAG &DAG) {
7354+ EVT VecVT = Vec.getValueType();
7355+ if (VecVT.isFloatingPoint()) {
7356+ // Use no-op casts for floating-point types.
7357+ EVT PackedVT = getPackedSVEVectorVT(VecVT.getScalarType());
7358+ Vec = DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, PackedVT, Vec);
7359+ Vec = DAG.getNode(AArch64ISD::NVCAST, DL, ContainerVT, Vec);
7360+ } else {
7361+ // Extend integers (may not be a no-op).
7362+ Vec = DAG.getNode(ISD::ANY_EXTEND, DL, ContainerVT, Vec);
7363+ }
7364+ return Vec;
7365+ }
7366+
7367+ // Convert to VecVT with no-op casts where possible.
7368+ static SDValue convertFromSVEContainerType(SDLoc DL, SDValue Vec, EVT VecVT,
7369+ SelectionDAG &DAG) {
7370+ if (VecVT.isFloatingPoint()) {
7371+ // Use no-op casts for floating-point types.
7372+ EVT PackedVT = getPackedSVEVectorVT(VecVT.getScalarType());
7373+ Vec = DAG.getNode(AArch64ISD::NVCAST, DL, PackedVT, Vec);
7374+ Vec = DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, VecVT, Vec);
7375+ } else {
7376+ // Truncate integers (may not be a no-op).
7377+ Vec = DAG.getNode(ISD::TRUNCATE, DL, VecVT, Vec);
7378+ }
7379+ return Vec;
7380+ }
7381+
73517382SDValue AArch64TargetLowering::LowerVECTOR_COMPRESS(SDValue Op,
73527383 SelectionDAG &DAG) const {
73537384 SDLoc DL(Op);
@@ -7399,14 +7430,10 @@ SDValue AArch64TargetLowering::LowerVECTOR_COMPRESS(SDValue Op,
73997430
74007431 // Get legal type for compact instruction
74017432 EVT ContainerVT = getSVEContainerType(VecVT);
7402- EVT CastVT = VecVT.changeVectorElementTypeToInteger();
74037433
7404- // Convert to i32 or i64 for smaller types, as these are the only supported
7434+ // Convert to 32 or 64 bits for smaller types, as these are the only supported
74057435 // sizes for compact.
7406- if (ContainerVT != VecVT) {
7407- Vec = DAG.getBitcast(CastVT, Vec);
7408- Vec = DAG.getNode(ISD::ANY_EXTEND, DL, ContainerVT, Vec);
7409- }
7436+ Vec = convertToSVEContainerType(DL, Vec, ContainerVT, DAG);
74107437
74117438 SDValue Compressed = DAG.getNode(
74127439 ISD::INTRINSIC_WO_CHAIN, DL, Vec.getValueType(),
@@ -7429,21 +7456,23 @@ SDValue AArch64TargetLowering::LowerVECTOR_COMPRESS(SDValue Op,
74297456 DAG.getNode(ISD::VSELECT, DL, VecVT, IndexMask, Compressed, Passthru);
74307457 }
74317458
7459+ // If we changed the element type before, we need to convert it back.
7460+ if (ElmtVT.isFloatingPoint())
7461+ Compressed = convertFromSVEContainerType(DL, Compressed, VecVT, DAG);
7462+
74327463 // Extracting from a legal SVE type before truncating produces better code.
74337464 if (IsFixedLength) {
7434- Compressed = DAG.getNode(
7435- ISD::EXTRACT_SUBVECTOR, DL,
7436- FixedVecVT.changeVectorElementType(ContainerVT.getVectorElementType()),
7437- Compressed, DAG.getConstant(0, DL, MVT::i64));
7438- CastVT = FixedVecVT.changeVectorElementTypeToInteger();
7465+ EVT FixedSubVector = VecVT.isInteger()
7466+ ? FixedVecVT.changeVectorElementType(
7467+ ContainerVT.getVectorElementType())
7468+ : FixedVecVT;
7469+ Compressed = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, FixedSubVector,
7470+ Compressed, DAG.getConstant(0, DL, MVT::i64));
74397471 VecVT = FixedVecVT;
74407472 }
74417473
7442- // If we changed the element type before, we need to convert it back.
7443- if (ContainerVT != VecVT) {
7444- Compressed = DAG.getNode(ISD::TRUNCATE, DL, CastVT, Compressed);
7445- Compressed = DAG.getBitcast(VecVT, Compressed);
7446- }
7474+ if (VecVT.isInteger())
7475+ Compressed = DAG.getNode(ISD::TRUNCATE, DL, VecVT, Compressed);
74477476
74487477 return Compressed;
74497478}
0 commit comments