llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: 陈子昂 (Michael-Chen-NJU) <details> <summary>Changes</summary> Add support for the Packed "Q-format" Multiply with Widening Accumulate intrinsics: - `__riscv_pmqwacc_i32x2` - `__riscv_pmqrwacc_i32x2` RV32 selects the direct instructions, while RV64 lowers to the spec-listed `zip16p` and packed Q-format accumulate sequences. --- Full diff: https://github.com/llvm/llvm-project/pull/228009.diff 9 Files Affected: - (modified) clang/include/clang/Basic/BuiltinsRISCV.td (+4) - (modified) clang/lib/CodeGen/TargetBuiltins/RISCV.cpp (+9) - (modified) clang/lib/Headers/riscv_packed_simd.h (+6) - (modified) clang/test/CodeGen/RISCV/rvp-intrinsics.c (+28) - (modified) cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c (+16) - (modified) llvm/include/llvm/IR/IntrinsicsRISCV.td (+8) - (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+24) - (modified) llvm/lib/Target/RISCV/RISCVInstrInfoP.td (+17-5) - (modified) llvm/test/CodeGen/RISCV/rvp-simd-64.ll (+32) ``````````diff diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td b/clang/include/clang/Basic/BuiltinsRISCV.td index e38c0ffe73c80..3a3e85c25b664 100644 --- a/clang/include/clang/Basic/BuiltinsRISCV.td +++ b/clang/include/clang/Basic/BuiltinsRISCV.td @@ -329,6 +329,10 @@ def pmhacc_h1_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, def pmhaccsu_h0_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>, _Vector<4, unsigned short>)">; def pmhaccsu_h1_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>, _Vector<4, unsigned short>)">; +// Packed "Q-format" Multiply with Widening Accumulate +def pmqwacc_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, short>, _Vector<2, short>)">; +def pmqrwacc_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, short>, _Vector<2, short>)">; + // Packed Multiplication with Horizontal Addition (32-bit) def pm4add_i8x4 : RISCVBuiltin<"int(_Vector<4, signed char>, _Vector<4, signed char>)">; def pm2add_i16x2 : RISCVBuiltin<"int(_Vector<2, short>, _Vector<2, short>)">; diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp index 474a0aa577734..74f85712e4828 100644 --- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp @@ -1661,6 +1661,15 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, break; } + // Packed "Q-format" Multiply with Widening Accumulate + case RISCV::BI__builtin_riscv_pmqwacc_i32x2: + case RISCV::BI__builtin_riscv_pmqrwacc_i32x2: { + ID = BuiltinID == RISCV::BI__builtin_riscv_pmqwacc_i32x2 + ? Intrinsic::riscv_pmqwacc_i32x2 + : Intrinsic::riscv_pmqrwacc_i32x2; + break; + } + // Packed Multiplication with Horizontal Addition case RISCV::BI__builtin_riscv_pm4add_i8x4: case RISCV::BI__builtin_riscv_pm4add_i8x8: diff --git a/clang/lib/Headers/riscv_packed_simd.h b/clang/lib/Headers/riscv_packed_simd.h index 6bc610d74246b..4148b165e28f3 100644 --- a/clang/lib/Headers/riscv_packed_simd.h +++ b/clang/lib/Headers/riscv_packed_simd.h @@ -826,6 +826,12 @@ __packed_widen_mulsu(pwmulsu_i16x4, int16x4_t, int8x4_t, uint8x4_t, uint16x4_t) __packed_widen_mulsu(pwmulsu_i32x2, int32x2_t, int16x2_t, uint16x2_t, uint32x2_t) +/* Packed "Q-format" Multiply with Widening Accumulate */ +__packed_ternary_builtin_mixed(pmqwacc_i32x2, int32x2_t, int16x2_t, int16x2_t, + __builtin_riscv_pmqwacc_i32x2) +__packed_ternary_builtin_mixed(pmqrwacc_i32x2, int32x2_t, int16x2_t, int16x2_t, + __builtin_riscv_pmqrwacc_i32x2) + /* Packed Narrowing Convert */ __packed_narrow_even4(pncvt_i8x4, int8x4_t, int16x4_t, int8x8_t) __packed_narrow_even4(pncvt_u8x4, uint8x4_t, uint16x4_t, uint8x8_t) diff --git a/clang/test/CodeGen/RISCV/rvp-intrinsics.c b/clang/test/CodeGen/RISCV/rvp-intrinsics.c index b26b75b3e1431..5f57545cf6c9f 100644 --- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c +++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c @@ -5801,6 +5801,34 @@ int32x2_t test_pwmul_i32x2(int16x2_t rs1, int16x2_t rs2) { return __riscv_pwmul_i32x2(rs1, rs2); } +// CHECK-LABEL: define dso_local i64 @test_pmqwacc_i32x2( +// CHECK-SAME: i64 noundef [[RD_COERCE:%.*]], i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RD_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS1_COERCE]] to <2 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i32 [[RS2_COERCE]] to <2 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = call <2 x i32> @llvm.riscv.pmqwacc.i32x2(<2 x i32> [[TMP0]], <2 x i16> [[TMP1]], <2 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP3]] to i64 +// CHECK-NEXT: ret i64 [[TMP4]] +// +int32x2_t test_pmqwacc_i32x2(int32x2_t rd, int16x2_t rs1, int16x2_t rs2) { + return __riscv_pmqwacc_i32x2(rd, rs1, rs2); +} + +// CHECK-LABEL: define dso_local i64 @test_pmqrwacc_i32x2( +// CHECK-SAME: i64 noundef [[RD_COERCE:%.*]], i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RD_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS1_COERCE]] to <2 x i16> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i32 [[RS2_COERCE]] to <2 x i16> +// CHECK-NEXT: [[TMP3:%.*]] = call <2 x i32> @llvm.riscv.pmqrwacc.i32x2(<2 x i32> [[TMP0]], <2 x i16> [[TMP1]], <2 x i16> [[TMP2]]) +// CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i32> [[TMP3]] to i64 +// CHECK-NEXT: ret i64 [[TMP4]] +// +int32x2_t test_pmqrwacc_i32x2(int32x2_t rd, int16x2_t rs1, int16x2_t rs2) { + return __riscv_pmqrwacc_i32x2(rd, rs1, rs2); +} + // CHECK-LABEL: define dso_local i64 @test_pwmulu_u16x4( // CHECK-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] diff --git a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c index 469c3d6846ed8..e7ad4af120270 100644 --- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c +++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c @@ -2632,6 +2632,22 @@ int32x2_t test_pwmul_i32x2(int16x2_t rs1, int16x2_t rs2) { return __riscv_pwmul_i32x2(rs1, rs2); } +// CHECK-LABEL: test_pmqwacc_i32x2: +// RV32: pmqwacc.h{{[[:space:]]}} +// RV64: zip16p{{[[:space:]]}} +// RV64: pmqacc.w.h01{{[[:space:]]}} +int32x2_t test_pmqwacc_i32x2(int32x2_t rd, int16x2_t rs1, int16x2_t rs2) { + return __riscv_pmqwacc_i32x2(rd, rs1, rs2); +} + +// CHECK-LABEL: test_pmqrwacc_i32x2: +// RV32: pmqrwacc.h{{[[:space:]]}} +// RV64: zip16p{{[[:space:]]}} +// RV64: pmqracc.w.h01{{[[:space:]]}} +int32x2_t test_pmqrwacc_i32x2(int32x2_t rd, int16x2_t rs1, int16x2_t rs2) { + return __riscv_pmqrwacc_i32x2(rd, rs1, rs2); +} + // CHECK-LABEL: test_pwmulu_u16x4: // RV32: pwmulu.b // RV64: zip8p diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index b2e9bbba3ad6f..3ff0b10bb6f53 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -2217,6 +2217,14 @@ class RVPBinaryIntrinsic def int_riscv_pmulhsu_h0 : RVPMulHighPartsIntrinsic; def int_riscv_pmulhsu_h1 : RVPMulHighPartsIntrinsic; + // Packed "Q-format" Multiply with Widening Accumulate. + class RVPQFormatWideningAccIntrinsic + : DefaultAttrsIntrinsic<[llvm_v2i32_ty], + [llvm_v2i32_ty, llvm_v2i16_ty, llvm_v2i16_ty], + [IntrNoMem, IntrSpeculatable]>; + def int_riscv_pmqwacc_i32x2 : RVPQFormatWideningAccIntrinsic; + def int_riscv_pmqrwacc_i32x2 : RVPQFormatWideningAccIntrinsic; + // The scalar forms keep a single product of the full-width rs1 and one // halfword of rs2: <2 x i16> pairs with i32. class RVPScalarMulHighPartsIntrinsic diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 7730a52a2e26d..477d5a331eb81 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -13414,6 +13414,30 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, return SDValue(); } + case Intrinsic::riscv_pmqwacc_i32x2: + case Intrinsic::riscv_pmqrwacc_i32x2: { + EVT VT = Op.getValueType(); + SDValue Acc = Op.getOperand(1); + SDValue Rs1 = Op.getOperand(2); + SDValue Rs2 = Op.getOperand(3); + + if (!Subtarget.is64Bit()) { + unsigned Opc = IntNo == Intrinsic::riscv_pmqwacc_i32x2 + ? RISCVISD::PMQWACC_H + : RISCVISD::PMQRWACC_H; + return DAG.getNode(Opc, DL, VT, Acc, Rs1, Rs2); + } + + Rs1 = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v4i16, Rs1, + DAG.getUNDEF(MVT::v2i16)); + Rs2 = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v4i16, Rs2, + DAG.getUNDEF(MVT::v2i16)); + SDValue Zip = DAG.getNode(RISCVISD::PZIP, DL, MVT::v4i16, Rs1, Rs2); + unsigned Opc = IntNo == Intrinsic::riscv_pmqwacc_i32x2 + ? RISCVISD::PMQACC_W_H01 + : RISCVISD::PMQRACC_W_H01; + return DAG.getNode(Opc, DL, VT, Acc, Zip, Zip); + } case Intrinsic::riscv_mulh_h0: case Intrinsic::riscv_mulh_h1: case Intrinsic::riscv_mulhsu_h0: diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index 8a6754b900028..67fee79db0582 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -1926,16 +1926,20 @@ def riscv_pm2waddu def riscv_pm2waddsu : RVSDNode<"PM2WADDSU", SDT_RISCVPackedWideningHorizontalAdd>; -// Packed multiplication with widening horizontal addition and accumulate. -def SDT_RISCVPackedWideningHorizontalAddAcc +// Packed widening multiply-accumulate operations. +def SDT_RISCVPackedWideningAcc : SDTypeProfile<1, 3, [SDTCisVT<0, v2i32>, SDTCisSameAs<0, 1>, SDTCisVT<2, v2i16>, SDTCisSameAs<2, 3>]>; +def riscv_pmqwacc_h + : RVSDNode<"PMQWACC_H", SDT_RISCVPackedWideningAcc>; +def riscv_pmqrwacc_h + : RVSDNode<"PMQRWACC_H", SDT_RISCVPackedWideningAcc>; def riscv_pm2wadda - : RVSDNode<"PM2WADDA", SDT_RISCVPackedWideningHorizontalAddAcc>; + : RVSDNode<"PM2WADDA", SDT_RISCVPackedWideningAcc>; def riscv_pm2waddau - : RVSDNode<"PM2WADDAU", SDT_RISCVPackedWideningHorizontalAddAcc>; + : RVSDNode<"PM2WADDAU", SDT_RISCVPackedWideningAcc>; def riscv_pm2waddasu - : RVSDNode<"PM2WADDASU", SDT_RISCVPackedWideningHorizontalAddAcc>; + : RVSDNode<"PM2WADDASU", SDT_RISCVPackedWideningAcc>; def SDT_RISCVPM2Halfword : SDTypeProfile<1, 2, [SDTCisVT<0, v2i32>, @@ -2717,6 +2721,14 @@ let append Predicates = [IsRV32] in { def : Pat<(v2i32 (riscv_pwmulsu (v2i16 GPR:$rs1), (v2i16 GPR:$rs2))), (PWMULSU_H GPR:$rs1, GPR:$rs2)>; + // Packed Q-format widening multiply-accumulate patterns. + def : Pat<(v2i32 (riscv_pmqwacc_h (v2i32 GPRPair:$rd), + (v2i16 GPR:$rs1), (v2i16 GPR:$rs2))), + (PMQWACC_H GPRPair:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(v2i32 (riscv_pmqrwacc_h (v2i32 GPRPair:$rd), + (v2i16 GPR:$rs1), (v2i16 GPR:$rs2))), + (PMQRWACC_H GPRPair:$rd, GPR:$rs1, GPR:$rs2)>; + // Packed multiplication with widening horizontal addition patterns. def : Pat<(v2i32 (riscv_pm2wadd (v2i16 GPR:$rs1), (v2i16 GPR:$rs2))), (PM2WADD_H GPR:$rs1, GPR:$rs2)>; diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll index 77376296bfbdf..3ba711d2082e0 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll @@ -8017,6 +8017,38 @@ declare <2 x i32> @llvm.riscv.pmhacc.h0.v2i32(<2 x i32>, <2 x i32>, <4 x i16>) declare <2 x i32> @llvm.riscv.pmhacc.h1.v2i32(<2 x i32>, <2 x i32>, <4 x i16>) declare <2 x i32> @llvm.riscv.pmhaccsu.h0.v2i32(<2 x i32>, <2 x i32>, <4 x i16>) declare <2 x i32> @llvm.riscv.pmhaccsu.h1.v2i32(<2 x i32>, <2 x i32>, <4 x i16>) +declare <2 x i32> @llvm.riscv.pmqwacc.i32x2(<2 x i32>, <2 x i16>, <2 x i16>) +declare <2 x i32> @llvm.riscv.pmqrwacc.i32x2(<2 x i32>, <2 x i16>, <2 x i16>) + +define <2 x i32> @test_pmqwacc_i32x2(<2 x i32> %rd, <2 x i16> %rs1, <2 x i16> %rs2) { +; RV32-LABEL: test_pmqwacc_i32x2: +; RV32: # %bb.0: +; RV32-NEXT: pmqwacc.h a0, a2, a3 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmqwacc_i32x2: +; RV64: # %bb.0: +; RV64-NEXT: zip16p a1, a1, a2 +; RV64-NEXT: pmqacc.w.h01 a0, a1, a1 +; RV64-NEXT: ret + %r = call <2 x i32> @llvm.riscv.pmqwacc.i32x2(<2 x i32> %rd, <2 x i16> %rs1, <2 x i16> %rs2) + ret <2 x i32> %r +} + +define <2 x i32> @test_pmqrwacc_i32x2(<2 x i32> %rd, <2 x i16> %rs1, <2 x i16> %rs2) { +; RV32-LABEL: test_pmqrwacc_i32x2: +; RV32: # %bb.0: +; RV32-NEXT: pmqrwacc.h a0, a2, a3 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmqrwacc_i32x2: +; RV64: # %bb.0: +; RV64-NEXT: zip16p a1, a1, a2 +; RV64-NEXT: pmqracc.w.h01 a0, a1, a1 +; RV64-NEXT: ret + %r = call <2 x i32> @llvm.riscv.pmqrwacc.i32x2(<2 x i32> %rd, <2 x i16> %rs1, <2 x i16> %rs2) + ret <2 x i32> %r +} define <2 x i32> @test_pmacc_h00_v2i32(<2 x i32> %rd, <4 x i16> %a, <4 x i16> %b) { ; RV32-LABEL: test_pmacc_h00_v2i32: `````````` </details> https://github.com/llvm/llvm-project/pull/228009 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
