@@ -4532,7 +4532,9 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
45324532
45334533 SDValue N0 = N->getOperand (0 );
45344534 SDValue N1 = N->getOperand (1 );
4535+
45354536 EVT VT = N->getValueType (0 );
4537+ SDLoc DL (N);
45364538
45374539 // Essentially: rotr (xor(x, y), imm) -> xar (x, y, imm)
45384540 // Rotate by a constant is a funnel shift in IR which is exanded to
@@ -4558,10 +4560,26 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
45584560 !TLI->isAllActivePredicate (*CurDAG, N1.getOperand (0 )))
45594561 return false ;
45604562
4561- SDValue XOR = N0.getOperand (1 );
4562- if (XOR.getOpcode () != ISD::XOR || XOR != N1.getOperand (1 ))
4563+ if (N0.getOperand (1 ) != N1.getOperand (1 ))
45634564 return false ;
45644565
4566+ SDValue R1, R2;
4567+ if (N0.getOperand (1 ).getOpcode () != ISD::XOR) {
4568+ SDValue Zero = CurDAG->getTargetConstant (0 , DL, MVT::i64 );
4569+ SDNode *MOV = CurDAG->getMachineNode (AArch64::MOVIv2d_ns, DL, VT, Zero);
4570+ SDValue MOVIV = SDValue (MOV, 0 );
4571+
4572+ SDValue ZSub = CurDAG->getTargetConstant (AArch64::zsub, DL, MVT::i32 );
4573+ SDNode *SubRegToReg = CurDAG->getMachineNode (AArch64::SUBREG_TO_REG, DL,
4574+ VT, Zero, MOVIV, ZSub);
4575+
4576+ R1 = N1->getOperand (1 );
4577+ R2 = SDValue (SubRegToReg, 0 );
4578+ } else {
4579+ R1 = N0.getOperand (1 ).getOperand (0 );
4580+ R2 = N1.getOperand (1 ).getOperand (1 );
4581+ }
4582+
45654583 APInt ShlAmt, ShrAmt;
45664584 if (!ISD::isConstantSplatVector (N0.getOperand (2 ).getNode (), ShlAmt) ||
45674585 !ISD::isConstantSplatVector (N1.getOperand (2 ).getNode (), ShrAmt))
@@ -4570,11 +4588,11 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
45704588 if (ShlAmt + ShrAmt != VT.getScalarSizeInBits ())
45714589 return false ;
45724590
4573- SDLoc DL (N);
4591+ SDLoc DLImm (N);
45744592 SDValue Imm =
4575- CurDAG->getTargetConstant (ShrAmt.getZExtValue (), DL , MVT::i32 );
4593+ CurDAG->getTargetConstant (ShrAmt.getZExtValue (), DLImm , MVT::i32 );
45764594
4577- SDValue Ops[] = {XOR. getOperand ( 0 ), XOR. getOperand ( 1 ) , Imm};
4595+ SDValue Ops[] = {R1, R2 , Imm};
45784596 if (auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
45794597 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
45804598 AArch64::XAR_ZZZI_D})) {
@@ -4591,20 +4609,28 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
45914609 N1->getOpcode () != AArch64ISD::VLSHR)
45924610 return false ;
45934611
4594- if (N0->getOperand (0 ) != N1->getOperand (0 ) ||
4595- N1->getOperand (0 )->getOpcode () != ISD::XOR)
4612+ if (N0->getOperand (0 ) != N1->getOperand (0 ))
45964613 return false ;
45974614
4598- SDValue XOR = N0.getOperand (0 );
4599- SDValue R1 = XOR.getOperand (0 );
4600- SDValue R2 = XOR.getOperand (1 );
4615+ SDValue R1, R2;
4616+ if (N1->getOperand (0 )->getOpcode () != ISD::XOR) {
4617+ SDValue Zero = CurDAG->getTargetConstant (0 , DL, MVT::i64 );
4618+ SDNode *MOV = CurDAG->getMachineNode (AArch64::MOVIv2d_ns, DL, VT, Zero);
4619+ SDValue MOVIV = SDValue (MOV, 0 );
4620+ R1 = N1->getOperand (0 );
4621+ R2 = MOVIV;
4622+ } else {
4623+ SDValue XOR = N0.getOperand (0 );
4624+ R1 = XOR.getOperand (0 );
4625+ R2 = XOR.getOperand (1 );
4626+ }
46014627
46024628 unsigned HsAmt = N0.getConstantOperandVal (1 );
46034629 unsigned ShAmt = N1.getConstantOperandVal (1 );
46044630
4605- SDLoc DL = SDLoc (N0.getOperand (1 ));
4631+ SDLoc DLImm = SDLoc (N0.getOperand (1 ));
46064632 SDValue Imm = CurDAG->getTargetConstant (
4607- ShAmt, DL , N0.getOperand (1 ).getValueType (), false );
4633+ ShAmt, DLImm , N0.getOperand (1 ).getValueType (), false );
46084634
46094635 if (ShAmt + HsAmt != 64 )
46104636 return false ;
0 commit comments