@@ -4632,22 +4632,55 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
4632
4632
SDValue Imm = CurDAG->getTargetConstant (
4633
4633
ShAmt, DL, N0.getOperand (1 ).getValueType (), false );
4634
4634
4635
- if (ShAmt + HsAmt != 64 )
4635
+ unsigned VTSizeInBits =
4636
+ (Subtarget->hasSVE2 () ? VT.getScalarSizeInBits () : 64 );
4637
+ if (ShAmt + HsAmt != VTSizeInBits)
4636
4638
return false ;
4637
4639
4640
+ // We have Neon SHA3 XAR operation for v2i64 but for types
4641
+ // v4i32, v8i16, v16i8 we can use SVE operations when SVE2-SHA3
4642
+ // is available.
4643
+ EVT SVT = MVT::v2i64;
4644
+ switch (VT.getSimpleVT ().SimpleTy ) {
4645
+ case MVT::v4i32:
4646
+ SVT = MVT::nxv4i32;
4647
+ break ;
4648
+ case MVT::v8i16:
4649
+ SVT = MVT::nxv8i16;
4650
+ break ;
4651
+ case MVT::v16i8:
4652
+ SVT = MVT::nxv16i8;
4653
+ break ;
4654
+ default :
4655
+ if (!(VT == MVT::v2i64 || VT == MVT::v1i64))
4656
+ return false ;
4657
+ break ;
4658
+ }
4659
+
4638
4660
if (!IsXOROperand) {
4639
4661
SDValue Zero = CurDAG->getTargetConstant (0 , DL, MVT::i64 );
4640
- SDNode *MOV =
4641
- CurDAG->getMachineNode (AArch64::MOVIv2d_ns, DL, MVT::v2i64, Zero);
4662
+ SDNode *MOV = CurDAG->getMachineNode (AArch64::MOVIv2d_ns, DL, SVT, Zero);
4642
4663
SDValue MOVIV = SDValue (MOV, 0 );
4664
+
4643
4665
R1 = N1->getOperand (0 );
4644
4666
R2 = MOVIV;
4645
4667
}
4646
4668
4669
+ if (SVT != VT && VT != MVT::v1i64) {
4670
+ SDValue Undef =
4671
+ SDValue (CurDAG->getMachineNode (TargetOpcode::IMPLICIT_DEF, DL, SVT), 0 );
4672
+ SDValue ZSub = CurDAG->getTargetConstant (AArch64::zsub, DL, MVT::i32 );
4673
+
4674
+ R1 = SDValue (CurDAG->getMachineNode (AArch64::INSERT_SUBREG, DL, SVT, Undef,
4675
+ R1, ZSub),
4676
+ 0 );
4677
+ R2 = SDValue (CurDAG->getMachineNode (AArch64::INSERT_SUBREG, DL, SVT, Undef,
4678
+ R2, ZSub),
4679
+ 0 );
4680
+ }
4681
+
4647
4682
// If the input is a v1i64, widen to a v2i64 to use XAR.
4648
- assert ((VT == MVT::v1i64 || VT == MVT::v2i64) && " Unexpected XAR type!" );
4649
4683
if (VT == MVT::v1i64) {
4650
- EVT SVT = MVT::v2i64;
4651
4684
SDValue Undef =
4652
4685
SDValue (CurDAG->getMachineNode (AArch64::IMPLICIT_DEF, DL, SVT), 0 );
4653
4686
SDValue DSub = CurDAG->getTargetConstant (AArch64::dsub, DL, MVT::i32 );
@@ -4661,12 +4694,28 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
4661
4694
}
4662
4695
4663
4696
SDValue Ops[] = {R1, R2, Imm};
4664
- SDNode *XAR = CurDAG->getMachineNode (AArch64::XAR, DL, MVT::v2i64, Ops);
4697
+ SDNode *XAR = nullptr ;
4698
+
4699
+ if (SVT != VT && VT != MVT::v1i64) {
4700
+ if (auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4701
+ SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4702
+ AArch64::XAR_ZZZI_D}))
4703
+ XAR = CurDAG->getMachineNode (Opc, DL, VT, Ops);
4704
+ } else {
4705
+ XAR = CurDAG->getMachineNode (AArch64::XAR, DL, MVT::v2i64, Ops);
4706
+ }
4707
+
4708
+ if (!XAR)
4709
+ return false ;
4665
4710
4666
4711
if (VT == MVT::v1i64) {
4667
4712
SDValue DSub = CurDAG->getTargetConstant (AArch64::dsub, DL, MVT::i32 );
4668
4713
XAR = CurDAG->getMachineNode (AArch64::EXTRACT_SUBREG, DL, VT,
4669
4714
SDValue (XAR, 0 ), DSub);
4715
+ } else if (SVT != VT) {
4716
+ SDValue ZSub = CurDAG->getTargetConstant (AArch64::zsub, DL, MVT::i32 );
4717
+ XAR = CurDAG->getMachineNode (AArch64::EXTRACT_SUBREG, DL, VT,
4718
+ SDValue (XAR, 0 ), ZSub);
4670
4719
}
4671
4720
ReplaceNode (N, XAR);
4672
4721
return true ;
0 commit comments