[llvm] [AArch64][SVE2] Generate XAR (PR #77160)

Usman Nadeem via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 10 13:14:45 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 ||
+        LConst.getOpcode() != ISD::SPLAT_VECTOR)
+      return false;
+    if (!isa<ConstantSDNode>(RConst.getOperand(0).getNode()) ||
+        !isa<ConstantSDNode>(LConst.getOperand(0).getNode()))
+      return false;
+
+    uint64_t ShlAmt = LConst->getConstantOperandVal(0);
+    uint64_t ShrAmt = RConst->getConstantOperandVal(0);
+
+    if (ShlAmt + ShrAmt != VT.getScalarSizeInBits())
----------------
UsmanNadeem wrote:

Added!

https://github.com/llvm/llvm-project/pull/77160


More information about the llvm-commits mailing list