[llvm] [RISCV][P-ext] packed exchanged add/sub codegen (PR #203473)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 08:58:46 PDT 2026
================
@@ -11687,6 +11688,63 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
EVT PtrVT = getPointerTy(DAG.getDataLayout());
return DAG.getRegister(RISCV::X4, PtrVT);
}
+ case Intrinsic::riscv_pas:
+ case Intrinsic::riscv_psa:
+ case Intrinsic::riscv_psas:
+ case Intrinsic::riscv_pssa:
+ case Intrinsic::riscv_paas:
+ case Intrinsic::riscv_pasa: {
+ // v2i32 has no paired instruction on RV32; split into a pair of i32 ops
+ // with cross-lane operands. The exchange shape is: even result uses
+ // (S1[0], S2[1]); odd result uses (S1[1], S2[0]).
+ if (Subtarget.is64Bit() || Op.getSimpleValueType() != MVT::v2i32)
+ break;
+
+ unsigned EvenOpc, OddOpc;
+ switch (IntNo) {
+ case Intrinsic::riscv_pas:
+ EvenOpc = ISD::SUB;
+ OddOpc = ISD::ADD;
+ break;
+ case Intrinsic::riscv_psa:
+ EvenOpc = ISD::ADD;
+ OddOpc = ISD::SUB;
+ break;
+ case Intrinsic::riscv_psas:
+ EvenOpc = ISD::SSUBSAT;
+ OddOpc = ISD::SADDSAT;
+ break;
+ case Intrinsic::riscv_pssa:
+ EvenOpc = ISD::SADDSAT;
+ OddOpc = ISD::SSUBSAT;
+ break;
+ case Intrinsic::riscv_paas:
+ EvenOpc = RISCVISD::ASUB;
+ OddOpc = ISD::AVGFLOORS;
+ break;
+ case Intrinsic::riscv_pasa:
+ EvenOpc = ISD::AVGFLOORS;
+ OddOpc = RISCVISD::ASUB;
+ break;
+ default:
+ llvm_unreachable("Unexpected exchanged add/sub intrinsic");
+ }
+
+ SDValue S1 = Op.getOperand(1);
+ SDValue S2 = Op.getOperand(2);
+ SDValue Zero = DAG.getVectorIdxConstant(0, DL);
+ SDValue One = DAG.getVectorIdxConstant(1, DL);
+ SDValue S1Even =
+ DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, S1, Zero);
----------------
topperc wrote:
Use `getExtractVectorElt` which takes the index as an `unsigned`
https://github.com/llvm/llvm-project/pull/203473
More information about the llvm-commits
mailing list