Author: Craig Topper Date: 2026-07-27T23:51:52-07:00 New Revision: b59d69d79e547a432485c18611efd2ec8d9540ca
URL: https://github.com/llvm/llvm-project/commit/b59d69d79e547a432485c18611efd2ec8d9540ca DIFF: https://github.com/llvm/llvm-project/commit/b59d69d79e547a432485c18611efd2ec8d9540ca.diff LOG: [RISCV][P-Ext] Unify pncvt(h) intrinsics between RV32 and RV64. (#210996) Use __builtin_convertvector for pncvt and __builtin_shufflevector for pncvth. Alternatively we could use shift+__builtin_convertvector for pncvth but that requires combining psrl+unzip(8/16)p to unzip(8/16)hp. I'm not sure which is better right now. Added: Modified: clang/lib/Headers/riscv_packed_simd.h clang/test/CodeGen/RISCV/rvp-intrinsics.c Removed: ################################################################################ diff --git a/clang/lib/Headers/riscv_packed_simd.h b/clang/lib/Headers/riscv_packed_simd.h index 5324a3676651e..e63585fb99e38 100644 --- a/clang/lib/Headers/riscv_packed_simd.h +++ b/clang/lib/Headers/riscv_packed_simd.h @@ -134,24 +134,6 @@ typedef uint32_t uint32x2_t __attribute__((__vector_size__(8))); 7); \ } -#if __riscv_xlen == 64 -#define __packed_narrow_even2(name, rty, ty, sty) \ - static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \ - return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 0, 2); \ - } -#define __packed_narrow_even4(name, rty, ty, sty) \ - static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \ - return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 0, 2, 4, 6); \ - } -#define __packed_narrow_odd2(name, rty, ty, sty, uty) \ - static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \ - return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 1, 3); \ - } -#define __packed_narrow_odd4(name, rty, ty, sty, uty) \ - static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \ - return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 1, 3, 5, 7); \ - } -#else #define __packed_narrow_even2(name, rty, ty, sty) \ static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \ return __builtin_convertvector(__rs1, rty); \ @@ -162,13 +144,12 @@ typedef uint32_t uint32x2_t __attribute__((__vector_size__(8))); } #define __packed_narrow_odd2(name, rty, ty, sty, uty) \ static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \ - return __builtin_convertvector(((uty)__rs1) >> 16, rty); \ + return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 1, 3); \ } #define __packed_narrow_odd4(name, rty, ty, sty, uty) \ static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \ - return __builtin_convertvector(((uty)__rs1) >> 8, rty); \ + return __builtin_shufflevector((sty)__rs1, (sty)__rs1, 1, 3, 5, 7); \ } -#endif /* Packed Reverse: reverse the order of the elements. Lowered to a single * rev8/rev16/ppairoe.* by the backend's packed reverse-shuffle handling. */ diff --git a/clang/test/CodeGen/RISCV/rvp-intrinsics.c b/clang/test/CodeGen/RISCV/rvp-intrinsics.c index eeb53de2f9a35..7e3f5b3d1de2c 100644 --- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c +++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c @@ -7207,9 +7207,9 @@ uint32x2_t test_pwcvth_u32x2(uint16x2_t rs1) { // RV64-LABEL: define dso_local i32 @test_pncvt_i8x4( // RV64-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] -// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8> -// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6> -// RV64-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32 +// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> +// RV64-NEXT: [[CONV_I:%.*]] = trunc <4 x i16> [[TMP0]] to <4 x i8> +// RV64-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[CONV_I]] to i32 // RV64-NEXT: ret i32 [[TMP1]] // int8x4_t test_pncvt_i8x4(int16x4_t rs1) { return __riscv_pncvt_i8x4(rs1); } @@ -7225,9 +7225,9 @@ int8x4_t test_pncvt_i8x4(int16x4_t rs1) { return __riscv_pncvt_i8x4(rs1); } // RV64-LABEL: define dso_local i32 @test_pncvt_u8x4( // RV64-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] -// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8> -// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6> -// RV64-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32 +// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> +// RV64-NEXT: [[CONV_I:%.*]] = trunc <4 x i16> [[TMP0]] to <4 x i8> +// RV64-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[CONV_I]] to i32 // RV64-NEXT: ret i32 [[TMP1]] // uint8x4_t test_pncvt_u8x4(uint16x4_t rs1) { return __riscv_pncvt_u8x4(rs1); } @@ -7243,9 +7243,9 @@ uint8x4_t test_pncvt_u8x4(uint16x4_t rs1) { return __riscv_pncvt_u8x4(rs1); } // RV64-LABEL: define dso_local i32 @test_pncvt_i16x2( // RV64-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] -// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> -// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <2 x i32> <i32 0, i32 2> -// RV64-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[SHUFFLE_I]] to i32 +// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// RV64-NEXT: [[CONV_I:%.*]] = trunc <2 x i32> [[TMP0]] to <2 x i16> +// RV64-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[CONV_I]] to i32 // RV64-NEXT: ret i32 [[TMP1]] // int16x2_t test_pncvt_i16x2(int32x2_t rs1) { return __riscv_pncvt_i16x2(rs1); } @@ -7261,9 +7261,9 @@ int16x2_t test_pncvt_i16x2(int32x2_t rs1) { return __riscv_pncvt_i16x2(rs1); } // RV64-LABEL: define dso_local i32 @test_pncvt_u16x2( // RV64-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] -// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> -// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <2 x i32> <i32 0, i32 2> -// RV64-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[SHUFFLE_I]] to i32 +// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> +// RV64-NEXT: [[CONV_I:%.*]] = trunc <2 x i32> [[TMP0]] to <2 x i16> +// RV64-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[CONV_I]] to i32 // RV64-NEXT: ret i32 [[TMP1]] // uint16x2_t test_pncvt_u16x2(uint32x2_t rs1) { @@ -7273,10 +7273,9 @@ uint16x2_t test_pncvt_u16x2(uint32x2_t rs1) { // RV32-LABEL: define dso_local i32 @test_pncvth_i8x4( // RV32-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] -// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> -// RV32-NEXT: [[SHR_I:%.*]] = lshr <4 x i16> [[TMP0]], splat (i16 8) -// RV32-NEXT: [[CONV_I:%.*]] = trunc nuw <4 x i16> [[SHR_I]] to <4 x i8> -// RV32-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[CONV_I]] to i32 +// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8> +// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7> +// RV32-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32 // RV32-NEXT: ret i32 [[TMP1]] // // RV64-LABEL: define dso_local i32 @test_pncvth_i8x4( @@ -7292,10 +7291,9 @@ int8x4_t test_pncvth_i8x4(int16x4_t rs1) { return __riscv_pncvth_i8x4(rs1); } // RV32-LABEL: define dso_local i32 @test_pncvth_u8x4( // RV32-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] -// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> -// RV32-NEXT: [[SHR_I:%.*]] = lshr <4 x i16> [[TMP0]], splat (i16 8) -// RV32-NEXT: [[CONV_I:%.*]] = trunc nuw <4 x i16> [[SHR_I]] to <4 x i8> -// RV32-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[CONV_I]] to i32 +// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8> +// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7> +// RV32-NEXT: [[TMP1:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32 // RV32-NEXT: ret i32 [[TMP1]] // // RV64-LABEL: define dso_local i32 @test_pncvth_u8x4( @@ -7313,10 +7311,9 @@ uint8x4_t test_pncvth_u8x4(uint16x4_t rs1) { // RV32-LABEL: define dso_local i32 @test_pncvth_i16x2( // RV32-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] -// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> -// RV32-NEXT: [[SHR_I:%.*]] = lshr <2 x i32> [[TMP0]], splat (i32 16) -// RV32-NEXT: [[CONV_I:%.*]] = trunc nuw <2 x i32> [[SHR_I]] to <2 x i16> -// RV32-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[CONV_I]] to i32 +// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> +// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <2 x i32> <i32 1, i32 3> +// RV32-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[SHUFFLE_I]] to i32 // RV32-NEXT: ret i32 [[TMP1]] // // RV64-LABEL: define dso_local i32 @test_pncvth_i16x2( @@ -7334,10 +7331,9 @@ int16x2_t test_pncvth_i16x2(int32x2_t rs1) { // RV32-LABEL: define dso_local i32 @test_pncvth_u16x2( // RV32-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] -// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <2 x i32> -// RV32-NEXT: [[SHR_I:%.*]] = lshr <2 x i32> [[TMP0]], splat (i32 16) -// RV32-NEXT: [[CONV_I:%.*]] = trunc nuw <2 x i32> [[SHR_I]] to <2 x i16> -// RV32-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[CONV_I]] to i32 +// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> +// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <2 x i32> <i32 1, i32 3> +// RV32-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[SHUFFLE_I]] to i32 // RV32-NEXT: ret i32 [[TMP1]] // // RV64-LABEL: define dso_local i32 @test_pncvth_u16x2( _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
