[llvm] [AArch64][SVE2] Generate XAR (PR #77160)
Usman Nadeem via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 10 13:15:07 PST 2024
================
@@ -4275,6 +4275,64 @@ bool AArch64DAGToDAGISel::trySelectXAR(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
+ EVT VT = N->getValueType(0);
+
+ // Essentially: rotr (xor(x, y), imm) -> xar (x, y, imm)
+ // Rotate by a constant is a funnel shift in IR which is exanded to
+ // an OR with shifted operands.
+ // We do the following transform:
+ // OR N0, N1 -> xar (x, y, imm)
+ // Where:
+ // N1 = SRL_PRED true, V, splat(imm) --> rotr amount
+ // N0 = SHL_PRED true, V, splat(bits-imm)
+ // V = (xor x, y)
+ if (VT.isScalableVector() && Subtarget->hasSVE2orSME()) {
+ if (N0.getOpcode() != AArch64ISD::SHL_PRED ||
+ N1.getOpcode() != AArch64ISD::SRL_PRED)
+ std::swap(N0, N1);
+ if (N0.getOpcode() != AArch64ISD::SHL_PRED ||
+ N1.getOpcode() != AArch64ISD::SRL_PRED)
+ return false;
+
+ auto *TLI = static_cast<const AArch64TargetLowering *>(getTargetLowering());
+ if (!TLI->isAllActivePredicate(*CurDAG, N0.getOperand(0)) ||
+ !TLI->isAllActivePredicate(*CurDAG, N1.getOperand(0)))
+ return false;
+
+ SDValue XOR = N0.getOperand(1);
+ if (XOR.getOpcode() != ISD::XOR || XOR != N1.getOperand(1))
+ return false;
+
+ SDValue LConst = N0.getOperand(2);
+ SDValue RConst = N1.getOperand(2);
+ if (RConst.getOpcode() != ISD::SPLAT_VECTOR ||
----------------
UsmanNadeem wrote:
Done!
https://github.com/llvm/llvm-project/pull/77160
More information about the llvm-commits
mailing list