[llvm] [AArch64] Use `AArch64ISD::UADDLP` for manual widening adjacent arithmetic (zext/shuffle combination) (PR #189255)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 31 09:19:07 PDT 2026


================
@@ -22310,6 +22310,131 @@ static SDValue performSetccAddFolding(SDNode *Op, SelectionDAG &DAG) {
   return DAG.getNode(AArch64ISD::CSEL, DL, VT, RHS, LHS, CCVal, Cmp);
 }
 
+static bool isEvenOddShufflePair(SDValue Op0, SDValue Op1) {
+  auto *S0 = dyn_cast<ShuffleVectorSDNode>(Op0);
+  auto *S1 = dyn_cast<ShuffleVectorSDNode>(Op1);
+
+  if (!S0 || !S1)
+    return false;
+
+  if (S0->getOperand(0) != S1->getOperand(0))
+    return false;
+
+  ArrayRef<int> Mask0 = S0->getMask();
+  ArrayRef<int> Mask1 = S1->getMask();
+
+  if (Mask0.size() != Mask1.size())
+    return false;
+
+  auto IsValidSequence = [](ArrayRef<int> Mask0, ArrayRef<int> Mask1) {
+    bool isValid = true;
+    for (unsigned I = 0; I < Mask0.size(); ++I) {
+      if (Mask0[I] != (int)(I * 2) || Mask1[I] != (int)(I * 2 + 1))
+        isValid = false;
+    }
+    return isValid;
+  };
+
+  return IsValidSequence(Mask0, Mask1) || IsValidSequence(Mask1, Mask0);
+}
+
+static SDValue isEvenOddBuildVector(SDValue Op0, SDValue Op1) {
+  auto *B0 = dyn_cast<BuildVectorSDNode>(Op0);
+  auto *B1 = dyn_cast<BuildVectorSDNode>(Op1);
+
+  if (!B0 || !B1)
+    return SDValue();
+
+  if (B0->getNumOperands() != B1->getNumOperands())
+    return SDValue();
+
+  auto IsValidSequence = [](BuildVectorSDNode *B0, BuildVectorSDNode *B1) {
+    SDValue Src;
+    for (unsigned int I = 0; I < B0->getNumOperands(); ++I) {
+      SDValue ExtVecElt0 = B0->getOperand(I);
+      SDValue ExtVecElt1 = B1->getOperand(I);
+
+      if (!ExtVecElt0 || !ExtVecElt1)
+        return SDValue();
+
+      if (ExtVecElt0->getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
+          ExtVecElt1->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
+        return SDValue();
+
+      if (!Src)
+        Src = ExtVecElt0->getOperand(0);
+
+      if (Src != ExtVecElt0->getOperand(0) ||
+          ExtVecElt0->getOperand(0) != ExtVecElt1->getOperand(0))
+        return SDValue();
----------------
arsenm wrote:

I think sd_match can clean this up a lot 

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


More information about the llvm-commits mailing list