@@ -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,26 @@ 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
+ 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
+
4565
4583
APInt ShlAmt, ShrAmt;
4566
4584
if (!ISD::isConstantSplatVector (N0.getOperand (2 ).getNode (), ShlAmt) ||
4567
4585
!ISD::isConstantSplatVector (N1.getOperand (2 ).getNode (), ShrAmt))
@@ -4570,11 +4588,11 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
4570
4588
if (ShlAmt + ShrAmt != VT.getScalarSizeInBits ())
4571
4589
return false ;
4572
4590
4573
- SDLoc DL (N);
4591
+ SDLoc DLImm (N);
4574
4592
SDValue Imm =
4575
- CurDAG->getTargetConstant (ShrAmt.getZExtValue (), DL , MVT::i32 );
4593
+ CurDAG->getTargetConstant (ShrAmt.getZExtValue (), DLImm , MVT::i32 );
4576
4594
4577
- SDValue Ops[] = {XOR. getOperand ( 0 ), XOR. getOperand ( 1 ) , Imm};
4595
+ SDValue Ops[] = {R1, R2 , Imm};
4578
4596
if (auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4579
4597
VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4580
4598
AArch64::XAR_ZZZI_D})) {
@@ -4591,20 +4609,28 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
4591
4609
N1->getOpcode () != AArch64ISD::VLSHR)
4592
4610
return false ;
4593
4611
4594
- if (N0->getOperand (0 ) != N1->getOperand (0 ) ||
4595
- N1->getOperand (0 )->getOpcode () != ISD::XOR)
4612
+ if (N0->getOperand (0 ) != N1->getOperand (0 ))
4596
4613
return false ;
4597
4614
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
+ }
4601
4627
4602
4628
unsigned HsAmt = N0.getConstantOperandVal (1 );
4603
4629
unsigned ShAmt = N1.getConstantOperandVal (1 );
4604
4630
4605
- SDLoc DL = SDLoc (N0.getOperand (1 ));
4631
+ SDLoc DLImm = SDLoc (N0.getOperand (1 ));
4606
4632
SDValue Imm = CurDAG->getTargetConstant (
4607
- ShAmt, DL , N0.getOperand (1 ).getValueType (), false );
4633
+ ShAmt, DLImm , N0.getOperand (1 ).getValueType (), false );
4608
4634
4609
4635
if (ShAmt + HsAmt != 64 )
4610
4636
return false ;
0 commit comments