[llvm] [RISCV][P-ext] Add codegen for packed absolute difference sum (PR #207314)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 6 09:09:47 PDT 2026


================
@@ -15908,6 +15938,57 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
       Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
       return;
     }
+    case Intrinsic::riscv_pabdsumu:
+    case Intrinsic::riscv_pabdsumau: {
+      bool IsAcc = IntNo == Intrinsic::riscv_pabdsumau;
+      // The two packed sources (rs1, rs2) are the last two operands.
+      SDValue Rs1 = N->getOperand(N->getNumOperands() - 2);
+      SDValue Rs2 = N->getOperand(N->getNumOperands() - 1);
+      MVT VecVT = Rs1.getSimpleValueType();
+
+      // RV32: i64 result, always from a v8i8 source. The accumulator, if any,
+      // folds into the widening add below.
+      if (!Subtarget.is64Bit() && N->getValueType(0) == MVT::i64) {
+        // Sum of absolute differences of two v4i8 halves.
+        auto Sad = [&](SDValue A, SDValue B) {
+          SDValue S = DAG.getNode(
+              ISD::INTRINSIC_WO_CHAIN, DL, MVT::i32,
+              DAG.getTargetConstant(Intrinsic::riscv_pabdsumu, DL, MVT::i32), A,
+              B);
+          return DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, S);
+        };
+        auto [Rs1Lo, Rs1Hi] = DAG.SplitVector(Rs1, DL);
+        auto [Rs2Lo, Rs2Hi] = DAG.SplitVector(Rs2, DL);
+        SDValue Lo = Sad(Rs1Lo, Rs2Lo);
+        SDValue Hi = Sad(Rs1Hi, Rs2Hi);
+        // (acc + lo) + hi keeps the accumulate chained so it folds into a
+        // single waddau; without an accumulator lo + hi folds into waddu.
+        SDValue Res =
+            IsAcc ? DAG.getNode(ISD::ADD, DL, MVT::i64, N->getOperand(1), Lo)
+                  : Lo;
+        Res = DAG.getNode(ISD::ADD, DL, MVT::i64, Res, Hi);
+        Results.push_back(Res);
+        return;
+      }
+
+      // RV64: i32 result, so reduce at i64 and truncate. The source is v4i8 or
+      // v8i8; widen a v4i8 to v8i8, zeroing the upper bytes (v8i8 is legal).
+      if (!Subtarget.is64Bit() || N->getValueType(0) != MVT::i32)
+        return;
+      if (VecVT == MVT::v4i8) {
+        Rs1 = widenPackedVectorWithZeros(DAG, DL, Rs1, MVT::v8i8);
+        Rs2 = widenPackedVectorWithZeros(DAG, DL, Rs2, MVT::v8i8);
+      }
+      SmallVector<SDValue, 4> Ops = {N->getOperand(0)};
----------------
topperc wrote:

```suggestion
      SmallVector<SDValue, 3> Ops = {N->getOperand(0)};
```

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


More information about the llvm-commits mailing list