https://github.com/XChy created https://github.com/llvm/llvm-project/pull/232202
Add missing v2i32 packed pair intrinsics. >From b85f83bffc5b3f824e8e29677cbd92621a502093 Mon Sep 17 00:00:00 2001 From: XChy <[email protected]> Date: Thu, 15 Oct 2026 14:34:12 +0800 Subject: [PATCH 1/2] [RISCV][P-ext] Add missing packed pair --- clang/lib/Headers/riscv_packed_simd.h | 10 +- clang/test/CodeGen/RISCV/rvp-intrinsics.c | 104 ++++++++++++++++++ .../riscv_packed_simd.c | 56 ++++++++++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 7 +- llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 4 + llvm/test/CodeGen/RISCV/rvp-simd-64.ll | 58 ++++++++++ 6 files changed, 235 insertions(+), 4 deletions(-) diff --git a/clang/lib/Headers/riscv_packed_simd.h b/clang/lib/Headers/riscv_packed_simd.h index 4bf017f81db9f..4c3599e8f192b 100644 --- a/clang/lib/Headers/riscv_packed_simd.h +++ b/clang/lib/Headers/riscv_packed_simd.h @@ -958,7 +958,7 @@ __packed_pair_oe2(ppairoe_u16x2, uint16x2_t) __packed_pair_oo2(ppairo_i16x2, int16x2_t) __packed_pair_oo2(ppairo_u16x2, uint16x2_t) -/* Packed Pair (64-bit byte and halfword forms) */ +/* Packed Pair (64-bit) */ __packed_pair_ee8(ppaire_i8x8, int8x8_t) __packed_pair_ee8(ppaire_u8x8, uint8x8_t) __packed_pair_eo8(ppaireo_i8x8, int8x8_t) @@ -975,6 +975,14 @@ __packed_pair_oe4(ppairoe_i16x4, int16x4_t) __packed_pair_oe4(ppairoe_u16x4, uint16x4_t) __packed_pair_oo4(ppairo_i16x4, int16x4_t) __packed_pair_oo4(ppairo_u16x4, uint16x4_t) +__packed_pair_ee2(ppaire_i32x2, int32x2_t) +__packed_pair_ee2(ppaire_u32x2, uint32x2_t) +__packed_pair_eo2(ppaireo_i32x2, int32x2_t) +__packed_pair_eo2(ppaireo_u32x2, uint32x2_t) +__packed_pair_oe2(ppairoe_i32x2, int32x2_t) +__packed_pair_oe2(ppairoe_u32x2, uint32x2_t) +__packed_pair_oo2(ppairo_i32x2, int32x2_t) +__packed_pair_oo2(ppairo_u32x2, uint32x2_t) /* Packed Narrowing Zip (32-bit) */ __packed_nzip2(pnzip_i8x4, int8x4_t, int16x2_t) diff --git a/clang/test/CodeGen/RISCV/rvp-intrinsics.c b/clang/test/CodeGen/RISCV/rvp-intrinsics.c index b672c04bc35d5..9866b4915d267 100644 --- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c +++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c @@ -5302,6 +5302,110 @@ uint16x4_t test_ppairo_u16x4(uint16x4_t rs1, uint16x4_t rs2) { return __riscv_ppairo_u16x4(rs1, rs2); } +// CHECK-LABEL: define dso_local i64 @test_ppaire_i32x2( +// CHECK-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <2 x i32> +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> [[TMP1]], <2 x i32> <i32 0, i32 2> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to i64 +// CHECK-NEXT: ret i64 [[TMP2]] +// +int32x2_t test_ppaire_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_ppaire_i32x2(rs1, rs2); +} + +// CHECK-LABEL: define dso_local i64 @test_ppaire_u32x2( +// CHECK-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <2 x i32> +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> [[TMP1]], <2 x i32> <i32 0, i32 2> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to i64 +// CHECK-NEXT: ret i64 [[TMP2]] +// +uint32x2_t test_ppaire_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_ppaire_u32x2(rs1, rs2); +} + +// CHECK-LABEL: define dso_local i64 @test_ppaireo_i32x2( +// CHECK-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <2 x i32> +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> [[TMP1]], <2 x i32> <i32 0, i32 3> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to i64 +// CHECK-NEXT: ret i64 [[TMP2]] +// +int32x2_t test_ppaireo_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_ppaireo_i32x2(rs1, rs2); +} + +// CHECK-LABEL: define dso_local i64 @test_ppaireo_u32x2( +// CHECK-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <2 x i32> +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> [[TMP1]], <2 x i32> <i32 0, i32 3> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to i64 +// CHECK-NEXT: ret i64 [[TMP2]] +// +uint32x2_t test_ppaireo_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_ppaireo_u32x2(rs1, rs2); +} + +// CHECK-LABEL: define dso_local i64 @test_ppairoe_i32x2( +// CHECK-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <2 x i32> +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> [[TMP1]], <2 x i32> <i32 1, i32 2> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to i64 +// CHECK-NEXT: ret i64 [[TMP2]] +// +int32x2_t test_ppairoe_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_ppairoe_i32x2(rs1, rs2); +} + +// CHECK-LABEL: define dso_local i64 @test_ppairoe_u32x2( +// CHECK-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <2 x i32> +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> [[TMP1]], <2 x i32> <i32 1, i32 2> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to i64 +// CHECK-NEXT: ret i64 [[TMP2]] +// +uint32x2_t test_ppairoe_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_ppairoe_u32x2(rs1, rs2); +} + +// CHECK-LABEL: define dso_local i64 @test_ppairo_i32x2( +// CHECK-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <2 x i32> +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> [[TMP1]], <2 x i32> <i32 1, i32 3> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to i64 +// CHECK-NEXT: ret i64 [[TMP2]] +// +int32x2_t test_ppairo_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_ppairo_i32x2(rs1, rs2); +} + +// CHECK-LABEL: define dso_local i64 @test_ppairo_u32x2( +// CHECK-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <2 x i32> +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> [[TMP1]], <2 x i32> <i32 1, i32 3> +// CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[SHUFFLE_I]] to i64 +// CHECK-NEXT: ret i64 [[TMP2]] +// +uint32x2_t test_ppairo_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_ppairo_u32x2(rs1, rs2); +} + /* Packed Absolute Difference Sum (32-bit) */ // RV32-LABEL: define dso_local i32 @test_pabdsumu_u8x4_u32( // RV32-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] { 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 75c5a1ff8b75d..507ad0c83f776 100644 --- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c +++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c @@ -3728,6 +3728,62 @@ uint16x4_t test_ppairo_u16x4(uint16x4_t rs1, uint16x4_t rs2) { return __riscv_ppairo_u16x4(rs1, rs2); } +// CHECK-LABEL: test_ppaire_i32x2: +// RV32: mv +// RV64: pack +int32x2_t test_ppaire_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_ppaire_i32x2(rs1, rs2); +} + +// CHECK-LABEL: test_ppaire_u32x2: +// RV32: mv +// RV64: pack +uint32x2_t test_ppaire_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_ppaire_u32x2(rs1, rs2); +} + +// CHECK-LABEL: test_ppaireo_i32x2: +// RV32: mv +// RV64: ppaireo.w +int32x2_t test_ppaireo_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_ppaireo_i32x2(rs1, rs2); +} + +// CHECK-LABEL: test_ppaireo_u32x2: +// RV32: mv +// RV64: ppaireo.w +uint32x2_t test_ppaireo_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_ppaireo_u32x2(rs1, rs2); +} + +// CHECK-LABEL: test_ppairoe_i32x2: +// RV32: mv +// RV64: ppairoe.w +int32x2_t test_ppairoe_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_ppairoe_i32x2(rs1, rs2); +} + +// CHECK-LABEL: test_ppairoe_u32x2: +// RV32: mv +// RV64: ppairoe.w +uint32x2_t test_ppairoe_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_ppairoe_u32x2(rs1, rs2); +} + +// CHECK-LABEL: test_ppairo_i32x2: +// RV32: mv +// RV64: ppairo.w +int32x2_t test_ppairo_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_ppairo_i32x2(rs1, rs2); +} + +// CHECK-LABEL: test_ppairo_u32x2: +// RV32: mv +// RV64: ppairo.w +uint32x2_t test_ppairo_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_ppairo_u32x2(rs1, rs2); +} + // CHECK-LABEL: test_psext_b_i16x2: // CHECK: psext.h.b int16x2_t test_psext_b_i16x2(int16x2_t a) { return __riscv_psext_b_i16x2(a); } diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 00dbaeab507cb..e2340742ccf4f 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -6610,10 +6610,10 @@ lowerVECTOR_SHUFFLEAsRV32PNarrowingShift(ShuffleVectorSDNode *SVN, // <a1, b0, a3, b2, ...> -> ppairoe.* // <a1, b1, a3, b3, ...> -> ppairo.* static SDValue lowerVECTOR_SHUFFLEAsPPair(ShuffleVectorSDNode *SVN, - SelectionDAG &DAG) { + SelectionDAG &DAG, bool IsRV64) { MVT VT = SVN->getSimpleValueType(0); if (VT != MVT::v4i8 && VT != MVT::v8i8 && VT != MVT::v2i16 && - VT != MVT::v4i16) + VT != MVT::v4i16 && !(IsRV64 && VT == MVT::v2i32)) return SDValue(); SDValue V1 = SVN->getOperand(0); @@ -6734,7 +6734,8 @@ SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, if (SDValue V = lowerVECTOR_SHUFFLEAsRV32PNarrowingShift(SVN, Subtarget, DAG)) return V; - if (SDValue V = lowerVECTOR_SHUFFLEAsPPair(SVN, DAG)) + if (SDValue V = + lowerVECTOR_SHUFFLEAsPPair(SVN, DAG, Subtarget.is64Bit())) return V; return SDValue(); } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index e092ce6049e6b..a4f3973e83c79 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -3652,8 +3652,12 @@ let append Predicates = [IsRV64] in { // Packed pair: pair the even/odd-position elements of rs1 and rs2. def : Pat<(v2i32 (riscv_ppaire (v2i32 GPR:$rs1), (v2i32 GPR:$rs2))), (PACK GPR:$rs1, GPR:$rs2)>; + def : Pat<(v2i32 (riscv_ppaireo (v2i32 GPR:$rs1), (v2i32 GPR:$rs2))), + (PPAIREO_W GPR:$rs1, GPR:$rs2)>; def : Pat<(v2i32 (riscv_ppairoe (v2i32 GPR:$rs1), (v2i32 GPR:$rs2))), (PPAIROE_W GPR:$rs1, GPR:$rs2)>; + def : Pat<(v2i32 (riscv_ppairo (v2i32 GPR:$rs1), (v2i32 GPR:$rs2))), + (PPAIRO_W GPR:$rs1, GPR:$rs2)>; def : Pat<(v4i16 (riscv_ppaire (v4i16 GPR:$rs1), (v4i16 GPR:$rs2))), (PPAIRE_H GPR:$rs1, GPR:$rs2)>; } // append Predicates = [IsRV64] diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll index b5dd4d7b9534a..ee26f6ab53dd0 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll @@ -6762,6 +6762,64 @@ define <2 x i32> @test_undef_v2i32() { ret <2 x i32> undef } +define <2 x i32> @test_ppaire_v2i32(<2 x i32> %a, <2 x i32> %b) { +; RV32-LABEL: test_ppaire_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mv a1, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_ppaire_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pack a0, a0, a1 +; RV64-NEXT: ret + %res = shufflevector <2 x i32> %a, <2 x i32> %b, <2 x i32> <i32 0, i32 2> + ret <2 x i32> %res +} + +define <2 x i32> @test_ppaireo_v2i32(<2 x i32> %a, <2 x i32> %b) { +; RV32-LABEL: test_ppaireo_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mv a1, a3 +; RV32-NEXT: ret +; +; RV64-LABEL: test_ppaireo_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: ppaireo.w a0, a0, a1 +; RV64-NEXT: ret + %res = shufflevector <2 x i32> %a, <2 x i32> %b, <2 x i32> <i32 0, i32 3> + ret <2 x i32> %res +} + +define <2 x i32> @test_ppairoe_v2i32(<2 x i32> %a, <2 x i32> %b) { +; RV32-LABEL: test_ppairoe_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mv a0, a1 +; RV32-NEXT: mv a1, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_ppairoe_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: ppairoe.w a0, a0, a1 +; RV64-NEXT: ret + %res = shufflevector <2 x i32> %a, <2 x i32> %b, <2 x i32> <i32 1, i32 2> + ret <2 x i32> %res +} + +define <2 x i32> @test_ppairo_v2i32(<2 x i32> %a, <2 x i32> %b) { +; RV32-LABEL: test_ppairo_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mv a0, a1 +; RV32-NEXT: mv a1, a3 +; RV32-NEXT: ret +; +; RV64-LABEL: test_ppairo_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: ppairo.w a0, a0, a1 +; RV64-NEXT: ret + %res = shufflevector <2 x i32> %a, <2 x i32> %b, <2 x i32> <i32 1, i32 3> + ret <2 x i32> %res +} + define <8 x i8> @test_ppaireo_v8i8(<8 x i8> %a, <8 x i8> %b) { ; RV32-LABEL: test_ppaireo_v8i8: ; RV32: # %bb.0: >From 71cfee2c5beec582db941dd0901e553a3bb328f9 Mon Sep 17 00:00:00 2001 From: XChy <[email protected]> Date: Thu, 15 Oct 2026 15:03:35 +0800 Subject: [PATCH 2/2] format --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index e2340742ccf4f..44ce7bfb6dd9a 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -6734,8 +6734,7 @@ SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, if (SDValue V = lowerVECTOR_SHUFFLEAsRV32PNarrowingShift(SVN, Subtarget, DAG)) return V; - if (SDValue V = - lowerVECTOR_SHUFFLEAsPPair(SVN, DAG, Subtarget.is64Bit())) + if (SDValue V = lowerVECTOR_SHUFFLEAsPPair(SVN, DAG, Subtarget.is64Bit())) return V; return SDValue(); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
