================
@@ -18087,6 +18146,134 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode
*N,
return;
}
+ case Intrinsic::riscv_pm2adda:
+ case Intrinsic::riscv_pm2adda_x:
+ case Intrinsic::riscv_pm2addau:
+ case Intrinsic::riscv_pmq2adda:
+ case Intrinsic::riscv_pmqr2adda:
+ case Intrinsic::riscv_pm2suba:
+ case Intrinsic::riscv_pm2suba_x:
+ case Intrinsic::riscv_pm2addasu: {
+
+ if (N->getSimpleValueType(0) == MVT::i32) {
+ SDValue Rd = N->getOperand(1);
+ SDValue Rs1 = N->getOperand(2);
+ SDValue Rs2 = N->getOperand(3);
+ SDValue WideRd = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v2i32,
Rd);
+ SDValue Undef = DAG.getUNDEF(MVT::v2i16);
+ SDValue WideRs1 =
+ DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v4i16, Rs1, Undef);
+ SDValue WideRs2 =
+ DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v4i16, Rs2, Undef);
+ SDValue Res = DAG.getNode(getRVPMulAddAccOpcode(IntNo), DL, MVT::v2i32,
+ WideRd, WideRs1, WideRs2);
+ Results.push_back(DAG.getExtractVectorElt(DL, MVT::i32, Res, 0));
+ return;
+ }
+
+ assert(!Subtarget.is64Bit() && N->getSimpleValueType(0) == MVT::i64 &&
+ "Unexpected multiply-horizontal-add-accumulate legalization");
+ SDValue Rs1 = N->getOperand(2);
+ SDValue Rs2 = N->getOperand(3);
+ auto [RdLo, RdHi] =
+ DAG.SplitScalar(N->getOperand(1), DL, MVT::i32, MVT::i32);
+ SDVTList VTs = DAG.getVTList(MVT::i32, MVT::i32);
+ auto Extract = [&](SDValue V, unsigned Idx) {
+ return DAG.getExtractVectorElt(DL, MVT::i32, V, Idx);
+ };
+ SDValue Rs1Lo = Extract(Rs1, 0);
+ SDValue Rs1Hi = Extract(Rs1, 1);
+ SDValue Rs2Lo = Extract(Rs2, 0);
+ SDValue Rs2Hi = Extract(Rs2, 1);
+
+ if (IntNo == Intrinsic::riscv_pmq2adda ||
+ IntNo == Intrinsic::riscv_pmqr2adda) {
+ unsigned AccOpc = IntNo == Intrinsic::riscv_pmq2adda
+ ? RISCVISD::MQWACC
+ : RISCVISD::MQRWACC;
+ SDValue Acc = DAG.getNode(AccOpc, DL, VTs, {RdLo, RdHi, Rs1Lo, Rs2Lo});
+ Acc =
+ DAG.getNode(AccOpc, DL, VTs, {Acc, Acc.getValue(1), Rs1Hi, Rs2Hi});
+ Results.push_back(
+ DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Acc, Acc.getValue(1)));
+ return;
+ }
+
+ if (IntNo == Intrinsic::riscv_pm2suba ||
+ IntNo == Intrinsic::riscv_pm2suba_x) {
+ if (IntNo == Intrinsic::riscv_pm2suba_x)
+ std::swap(Rs2Lo, Rs2Hi);
+ SDValue LoMul = DAG.getNode(ISD::SMUL_LOHI, DL, VTs, Rs1Lo, Rs2Lo);
+ SDValue Acc = DAG.getNode(RISCVISD::ADDD, DL, VTs, RdLo, RdHi, LoMul,
+ LoMul.getValue(1));
+ SDValue HiMul = DAG.getNode(ISD::SMUL_LOHI, DL, VTs, Rs1Hi, Rs2Hi);
+ SDValue Res = DAG.getNode(RISCVISD::SUBD, DL, VTs, Acc,
Acc.getValue(1),
+ HiMul, HiMul.getValue(1));
+ Results.push_back(
+ DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Res, Res.getValue(1)));
+ return;
+ }
+
+ if (IntNo == Intrinsic::riscv_pm2adda_x)
+ std::swap(Rs2Lo, Rs2Hi);
+
+ unsigned MulOpc = ISD::SMUL_LOHI;
+ if (IntNo == Intrinsic::riscv_pm2addau)
+ MulOpc = ISD::UMUL_LOHI;
+ else if (IntNo == Intrinsic::riscv_pm2addasu)
+ MulOpc = RISCVISD::WMULSU;
+
+ SDValue LoMul = DAG.getNode(MulOpc, DL, VTs, Rs1Lo, Rs2Lo);
+ SDValue Acc = DAG.getNode(RISCVISD::ADDD, DL, VTs, RdLo, RdHi, LoMul,
+ LoMul.getValue(1));
+ SDValue HiMul = DAG.getNode(MulOpc, DL, VTs, Rs1Hi, Rs2Hi);
+ SDValue Res = DAG.getNode(RISCVISD::ADDD, DL, VTs, Acc, Acc.getValue(1),
+ HiMul, HiMul.getValue(1));
+ Results.push_back(
+ DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Res, Res.getValue(1)));
+ return;
+ }
+
+ case Intrinsic::riscv_pm4adda:
+ case Intrinsic::riscv_pm4addau:
+ case Intrinsic::riscv_pm4addasu: {
+
+ if (N->getSimpleValueType(0) == MVT::i32) {
+ SDValue Rd = N->getOperand(1);
+ SDValue Rs1 = N->getOperand(2);
+ SDValue Rs2 = N->getOperand(3);
+ unsigned Opc = getRVPMulAddAccOpcode(IntNo);
+ SDValue WideRd = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v2i32,
Rd);
+ SDValue Undef = DAG.getUNDEF(MVT::v4i8);
+ SDValue WideRs1 =
+ DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i8, Rs1, Undef);
+ SDValue WideRs2 =
+ DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i8, Rs2, Undef);
+ SDValue Res =
+ DAG.getNode(Opc, DL, MVT::v2i32, WideRd, WideRs1, WideRs2);
+ Results.push_back(DAG.getExtractVectorElt(DL, MVT::i32, Res, 0));
+ return;
+ }
+
+ assert(!Subtarget.is64Bit() && N->getSimpleValueType(0) == MVT::i64 &&
+ "Unexpected widening horizontal multiply-accumulate
legalization");
+ SDValue Rs1 = N->getOperand(2);
+ SDValue Rs2 = N->getOperand(3);
+ auto [Rs1Lo, Rs1Hi] = DAG.SplitVector(Rs1, DL);
+ auto [Rs2Lo, Rs2Hi] = DAG.SplitVector(Rs2, DL);
+ auto [RdLo, RdHi] =
+ DAG.SplitScalar(N->getOperand(1), DL, MVT::i32, MVT::i32);
+ SDValue Rd = DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v2i32, RdLo, RdHi);
+ unsigned AccOpc = IntNo == Intrinsic::riscv_pm4addau ?
RISCVISD::PM2WADDAU
+ : IntNo == Intrinsic::riscv_pm4addasu
+ ? RISCVISD::PM2WADDASU
----------------
topperc wrote:
I'm confused why the PM2WADDAU are defined to use a v2i32 accumulator instead
of having 2 i32 results like WADD, but I guess that's a problem for a different
patch.
https://github.com/llvm/llvm-project/pull/236303
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits