@@ -4532,7 +4532,9 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
4532
4532
4533
4533
SDValue N0 = N->getOperand (0 );
4534
4534
SDValue N1 = N->getOperand (1 );
4535
+
4535
4536
EVT VT = N->getValueType (0 );
4537
+ SDLoc DL (N);
4536
4538
4537
4539
// Essentially: rotr (xor(x, y), imm) -> xar (x, y, imm)
4538
4540
// Rotate by a constant is a funnel shift in IR which is exanded to
@@ -4558,10 +4560,18 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
4558
4560
!TLI->isAllActivePredicate (*CurDAG, N1.getOperand (0 )))
4559
4561
return false ;
4560
4562
4561
- SDValue XOR = N0.getOperand (1 );
4562
- if (XOR.getOpcode () != ISD::XOR || XOR != N1.getOperand (1 ))
4563
+ if (N0.getOperand (1 ) != N1.getOperand (1 ))
4563
4564
return false ;
4564
4565
4566
+ SDValue R1, R2;
4567
+ bool IsXOROperand = true ;
4568
+ if (N0.getOperand (1 ).getOpcode () != ISD::XOR) {
4569
+ IsXOROperand = false ;
4570
+ } else {
4571
+ R1 = N0.getOperand (1 ).getOperand (0 );
4572
+ R2 = N1.getOperand (1 ).getOperand (1 );
4573
+ }
4574
+
4565
4575
APInt ShlAmt, ShrAmt;
4566
4576
if (!ISD::isConstantSplatVector (N0.getOperand (2 ).getNode (), ShlAmt) ||
4567
4577
!ISD::isConstantSplatVector (N1.getOperand (2 ).getNode (), ShrAmt))
@@ -4570,11 +4580,23 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
4570
4580
if (ShlAmt + ShrAmt != VT.getScalarSizeInBits ())
4571
4581
return false ;
4572
4582
4573
- SDLoc DL (N);
4583
+ if (!IsXOROperand) {
4584
+ SDValue Zero = CurDAG->getTargetConstant (0 , DL, MVT::i64 );
4585
+ SDNode *MOV = CurDAG->getMachineNode (AArch64::MOVIv2d_ns, DL, VT, Zero);
4586
+ SDValue MOVIV = SDValue (MOV, 0 );
4587
+
4588
+ SDValue ZSub = CurDAG->getTargetConstant (AArch64::zsub, DL, MVT::i32 );
4589
+ SDNode *SubRegToReg = CurDAG->getMachineNode (AArch64::SUBREG_TO_REG, DL,
4590
+ VT, Zero, MOVIV, ZSub);
4591
+
4592
+ R1 = N1->getOperand (1 );
4593
+ R2 = SDValue (SubRegToReg, 0 );
4594
+ }
4595
+
4574
4596
SDValue Imm =
4575
4597
CurDAG->getTargetConstant (ShrAmt.getZExtValue (), DL, MVT::i32 );
4576
4598
4577
- SDValue Ops[] = {XOR. getOperand ( 0 ), XOR. getOperand ( 1 ) , Imm};
4599
+ SDValue Ops[] = {R1, R2 , Imm};
4578
4600
if (auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4579
4601
VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4580
4602
AArch64::XAR_ZZZI_D})) {
@@ -4591,24 +4613,36 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
4591
4613
N1->getOpcode () != AArch64ISD::VLSHR)
4592
4614
return false ;
4593
4615
4594
- if (N0->getOperand (0 ) != N1->getOperand (0 ) ||
4595
- N1->getOperand (0 )->getOpcode () != ISD::XOR)
4616
+ if (N0->getOperand (0 ) != N1->getOperand (0 ))
4596
4617
return false ;
4597
4618
4598
- SDValue XOR = N0.getOperand (0 );
4599
- SDValue R1 = XOR.getOperand (0 );
4600
- SDValue R2 = XOR.getOperand (1 );
4619
+ SDValue R1, R2;
4620
+ bool IsXOROperand = true ;
4621
+ if (N1->getOperand (0 )->getOpcode () != ISD::XOR) {
4622
+ IsXOROperand = false ;
4623
+ } else {
4624
+ SDValue XOR = N0.getOperand (0 );
4625
+ R1 = XOR.getOperand (0 );
4626
+ R2 = XOR.getOperand (1 );
4627
+ }
4601
4628
4602
4629
unsigned HsAmt = N0.getConstantOperandVal (1 );
4603
4630
unsigned ShAmt = N1.getConstantOperandVal (1 );
4604
4631
4605
- SDLoc DL = SDLoc (N0.getOperand (1 ));
4606
4632
SDValue Imm = CurDAG->getTargetConstant (
4607
4633
ShAmt, DL, N0.getOperand (1 ).getValueType (), false );
4608
4634
4609
4635
if (ShAmt + HsAmt != 64 )
4610
4636
return false ;
4611
4637
4638
+ if (!IsXOROperand) {
4639
+ SDValue Zero = CurDAG->getTargetConstant (0 , DL, MVT::i64 );
4640
+ SDNode *MOV = CurDAG->getMachineNode (AArch64::MOVIv2d_ns, DL, VT, Zero);
4641
+ SDValue MOVIV = SDValue (MOV, 0 );
4642
+ R1 = N1->getOperand (0 );
4643
+ R2 = MOVIV;
4644
+ }
4645
+
4612
4646
SDValue Ops[] = {R1, R2, Imm};
4613
4647
CurDAG->SelectNodeTo (N, AArch64::XAR, N0.getValueType (), Ops);
4614
4648
0 commit comments