Skip to content

Commit c14ca26

Browse files
committed
[AArch64] Utilize XAR for certain vector rotates
Resolves #137162 For cases when there isn't any `XOR` in the transformation, replace with a zero register.
1 parent ba3fa39 commit c14ca26

File tree

1 file changed

+38
-9
lines changed

1 file changed

+38
-9
lines changed

llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4558,9 +4558,27 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
45584558
!TLI->isAllActivePredicate(*CurDAG, N1.getOperand(0)))
45594559
return false;
45604560

4561-
SDValue XOR = N0.getOperand(1);
4562-
if (XOR.getOpcode() != ISD::XOR || XOR != N1.getOperand(1))
4563-
return false;
4561+
SDValue R1, R2;
4562+
if (N0.getOperand(1).getOpcode() != ISD::XOR) {
4563+
if (N0.getOperand(1) != N1.getOperand(1))
4564+
return false;
4565+
SDLoc DL(N1->getOperand(0));
4566+
EVT VT = N1->getOperand(0).getValueType();
4567+
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::i64);
4573+
SDNode *SubRegToReg = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, DL,
4574+
MVT::i64, Zero, MOVIV, ZSub);
4575+
4576+
R1 = N1->getOperand(0);
4577+
R2 = SDValue(SubRegToReg, 0);
4578+
} else {
4579+
R1 = N0.getOperand(1);
4580+
R2 = N1.getOperand(1);
4581+
}
45644582

45654583
APInt ShlAmt, ShrAmt;
45664584
if (!ISD::isConstantSplatVector(N0.getOperand(2).getNode(), ShlAmt) ||
@@ -4574,7 +4592,7 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
45744592
SDValue Imm =
45754593
CurDAG->getTargetConstant(ShrAmt.getZExtValue(), DL, 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,13 +4609,24 @@ 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+
SDLoc DL(N1->getOperand(0));
4618+
EVT VT = N1->getOperand(0).getValueType();
4619+
4620+
SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i64);
4621+
SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns, DL, VT, Zero);
4622+
SDValue MOVIV = SDValue(MOV, 0);
4623+
R1 = N1->getOperand(0);
4624+
R2 = MOVIV;
4625+
} else {
4626+
SDValue XOR = N0.getOperand(0);
4627+
R1 = XOR.getOperand(0);
4628+
R2 = XOR.getOperand(1);
4629+
}
46014630

46024631
unsigned HsAmt = N0.getConstantOperandVal(1);
46034632
unsigned ShAmt = N1.getConstantOperandVal(1);

0 commit comments

Comments
 (0)