[Clang][RISCV] Add packed pair byte intrinsics (#212589)

Add the 32-bit byte forms and the 64-bit byte/halfword forms of the
P-extension packed pair intrinsics to riscv_packed_simd.h using generic
shufflevector IR.

Extend the existing packed pair shuffle lowering to recognize the mixed
even/odd forms and select ppaireo/ppairoe in addition to ppaire/ppairo.

Add Clang CodeGen, LLVM CodeGen, and intrinsic header tests for the new
forms.
This commit is contained in:
陈子昂 2026-07-30 02:24:02 +08:00 committed by GitHub
parent 58a93a1eec
commit 33c7ef4a63
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 898 additions and 17 deletions

View file

@ -193,6 +193,39 @@ typedef uint32_t uint32x2_t __attribute__((__vector_size__(8)));
return __builtin_shufflevector(__rs1, __rs1, 1, 3, 5, 7); \
}
#define __packed_pair_ee4(name, ty) \
static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
return __builtin_shufflevector(__rs1, __rs2, 0, 4, 2, 6); \
}
#define __packed_pair_eo4(name, ty) \
static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
return __builtin_shufflevector(__rs1, __rs2, 0, 5, 2, 7); \
}
#define __packed_pair_oe4(name, ty) \
static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
return __builtin_shufflevector(__rs1, __rs2, 1, 4, 3, 6); \
}
#define __packed_pair_oo4(name, ty) \
static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
return __builtin_shufflevector(__rs1, __rs2, 1, 5, 3, 7); \
}
#define __packed_pair_ee8(name, ty) \
static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
return __builtin_shufflevector(__rs1, __rs2, 0, 8, 2, 10, 4, 12, 6, 14); \
}
#define __packed_pair_eo8(name, ty) \
static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
return __builtin_shufflevector(__rs1, __rs2, 0, 9, 2, 11, 4, 13, 6, 15); \
}
#define __packed_pair_oe8(name, ty) \
static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
return __builtin_shufflevector(__rs1, __rs2, 1, 8, 3, 10, 5, 12, 7, 14); \
}
#define __packed_pair_oo8(name, ty) \
static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
return __builtin_shufflevector(__rs1, __rs2, 1, 9, 3, 11, 5, 13, 7, 15); \
}
#define __packed_nzip2(name, rty, ty) \
static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
ty __rs2) { \
@ -565,6 +598,34 @@ __packed_unzipo2(punzipo_i16x2, int16x2_t, int16x4_t)
__packed_unzipe2(punzipe_u16x2, uint16x2_t, uint16x4_t)
__packed_unzipo2(punzipo_u16x2, uint16x2_t, uint16x4_t)
/* Packed Pair (32-bit byte forms) */
__packed_pair_ee4(ppaire_i8x4, int8x4_t)
__packed_pair_ee4(ppaire_u8x4, uint8x4_t)
__packed_pair_eo4(ppaireo_i8x4, int8x4_t)
__packed_pair_eo4(ppaireo_u8x4, uint8x4_t)
__packed_pair_oe4(ppairoe_i8x4, int8x4_t)
__packed_pair_oe4(ppairoe_u8x4, uint8x4_t)
__packed_pair_oo4(ppairo_i8x4, int8x4_t)
__packed_pair_oo4(ppairo_u8x4, uint8x4_t)
/* Packed Pair (64-bit byte and halfword forms) */
__packed_pair_ee8(ppaire_i8x8, int8x8_t)
__packed_pair_ee8(ppaire_u8x8, uint8x8_t)
__packed_pair_eo8(ppaireo_i8x8, int8x8_t)
__packed_pair_eo8(ppaireo_u8x8, uint8x8_t)
__packed_pair_oe8(ppairoe_i8x8, int8x8_t)
__packed_pair_oe8(ppairoe_u8x8, uint8x8_t)
__packed_pair_oo8(ppairo_i8x8, int8x8_t)
__packed_pair_oo8(ppairo_u8x8, uint8x8_t)
__packed_pair_ee4(ppaire_i16x4, int16x4_t)
__packed_pair_ee4(ppaire_u16x4, uint16x4_t)
__packed_pair_eo4(ppaireo_i16x4, int16x4_t)
__packed_pair_eo4(ppaireo_u16x4, uint16x4_t)
__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 Narrowing Zip (32-bit) */
__packed_nzip2(pnzip_i8x4, int8x4_t, int16x2_t)
__packed_nzip2(pnzip_u8x4, uint8x4_t, uint16x2_t)
@ -809,6 +870,14 @@ __packed_reinterpret(u32x2_i32x2, int32x2_t, uint32x2_t)
#undef __packed_unzipe4
#undef __packed_unzipo2
#undef __packed_unzipo4
#undef __packed_pair_ee4
#undef __packed_pair_eo4
#undef __packed_pair_oe4
#undef __packed_pair_oo4
#undef __packed_pair_ee8
#undef __packed_pair_eo8
#undef __packed_pair_oe8
#undef __packed_pair_oo8
#undef __packed_nzip2
#undef __packed_nzip4
#undef __packed_nziph2

View file

@ -6826,6 +6826,536 @@ uint16x2_t test_punzipo_u16x2(uint16x4_t rs1) {
return __riscv_punzipo_u16x2(rs1);
}
/* Packed Pair */
// RV32-LABEL: define dso_local i32 @test_ppaire_i8x4(
// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 6>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV32-NEXT: ret i32 [[TMP2]]
//
// RV64-LABEL: define dso_local i32 @test_ppaire_i8x4(
// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 6>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV64-NEXT: ret i32 [[TMP2]]
//
int8x4_t test_ppaire_i8x4(int8x4_t rs1, int8x4_t rs2) {
return __riscv_ppaire_i8x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i32 @test_ppaire_u8x4(
// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 6>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV32-NEXT: ret i32 [[TMP2]]
//
// RV64-LABEL: define dso_local i32 @test_ppaire_u8x4(
// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 6>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV64-NEXT: ret i32 [[TMP2]]
//
uint8x4_t test_ppaire_u8x4(uint8x4_t rs1, uint8x4_t rs2) {
return __riscv_ppaire_u8x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i32 @test_ppaireo_i8x4(
// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV32-NEXT: ret i32 [[TMP2]]
//
// RV64-LABEL: define dso_local i32 @test_ppaireo_i8x4(
// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV64-NEXT: ret i32 [[TMP2]]
//
int8x4_t test_ppaireo_i8x4(int8x4_t rs1, int8x4_t rs2) {
return __riscv_ppaireo_i8x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i32 @test_ppaireo_u8x4(
// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV32-NEXT: ret i32 [[TMP2]]
//
// RV64-LABEL: define dso_local i32 @test_ppaireo_u8x4(
// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV64-NEXT: ret i32 [[TMP2]]
//
uint8x4_t test_ppaireo_u8x4(uint8x4_t rs1, uint8x4_t rs2) {
return __riscv_ppaireo_u8x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i32 @test_ppairoe_i8x4(
// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 1, i32 4, i32 3, i32 6>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV32-NEXT: ret i32 [[TMP2]]
//
// RV64-LABEL: define dso_local i32 @test_ppairoe_i8x4(
// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 1, i32 4, i32 3, i32 6>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV64-NEXT: ret i32 [[TMP2]]
//
int8x4_t test_ppairoe_i8x4(int8x4_t rs1, int8x4_t rs2) {
return __riscv_ppairoe_i8x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i32 @test_ppairoe_u8x4(
// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 1, i32 4, i32 3, i32 6>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV32-NEXT: ret i32 [[TMP2]]
//
// RV64-LABEL: define dso_local i32 @test_ppairoe_u8x4(
// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 1, i32 4, i32 3, i32 6>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV64-NEXT: ret i32 [[TMP2]]
//
uint8x4_t test_ppairoe_u8x4(uint8x4_t rs1, uint8x4_t rs2) {
return __riscv_ppairoe_u8x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i32 @test_ppairo_i8x4(
// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 1, i32 5, i32 3, i32 7>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV32-NEXT: ret i32 [[TMP2]]
//
// RV64-LABEL: define dso_local i32 @test_ppairo_i8x4(
// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 1, i32 5, i32 3, i32 7>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV64-NEXT: ret i32 [[TMP2]]
//
int8x4_t test_ppairo_i8x4(int8x4_t rs1, int8x4_t rs2) {
return __riscv_ppairo_i8x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i32 @test_ppairo_u8x4(
// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 1, i32 5, i32 3, i32 7>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV32-NEXT: ret i32 [[TMP2]]
//
// RV64-LABEL: define dso_local i32 @test_ppairo_u8x4(
// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]], i32 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i32 [[RS2_COERCE]] to <4 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <4 x i32> <i32 1, i32 5, i32 3, i32 7>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[SHUFFLE_I]] to i32
// RV64-NEXT: ret i32 [[TMP2]]
//
uint8x4_t test_ppairo_u8x4(uint8x4_t rs1, uint8x4_t rs2) {
return __riscv_ppairo_u8x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppaire_i8x8(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppaire_i8x8(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
int8x8_t test_ppaire_i8x8(int8x8_t rs1, int8x8_t rs2) {
return __riscv_ppaire_i8x8(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppaire_u8x8(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppaire_u8x8(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
uint8x8_t test_ppaire_u8x8(uint8x8_t rs1, uint8x8_t rs2) {
return __riscv_ppaire_u8x8(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppaireo_i8x8(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppaireo_i8x8(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
int8x8_t test_ppaireo_i8x8(int8x8_t rs1, int8x8_t rs2) {
return __riscv_ppaireo_i8x8(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppaireo_u8x8(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppaireo_u8x8(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
uint8x8_t test_ppaireo_u8x8(uint8x8_t rs1, uint8x8_t rs2) {
return __riscv_ppaireo_u8x8(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppairoe_i8x8(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 1, i32 8, i32 3, i32 10, i32 5, i32 12, i32 7, i32 14>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppairoe_i8x8(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 1, i32 8, i32 3, i32 10, i32 5, i32 12, i32 7, i32 14>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
int8x8_t test_ppairoe_i8x8(int8x8_t rs1, int8x8_t rs2) {
return __riscv_ppairoe_i8x8(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppairoe_u8x8(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 1, i32 8, i32 3, i32 10, i32 5, i32 12, i32 7, i32 14>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppairoe_u8x8(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 1, i32 8, i32 3, i32 10, i32 5, i32 12, i32 7, i32 14>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
uint8x8_t test_ppairoe_u8x8(uint8x8_t rs1, uint8x8_t rs2) {
return __riscv_ppairoe_u8x8(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppairo_i8x8(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppairo_i8x8(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
int8x8_t test_ppairo_i8x8(int8x8_t rs1, int8x8_t rs2) {
return __riscv_ppairo_i8x8(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppairo_u8x8(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppairo_u8x8(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <8 x i8>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <8 x i8> [[TMP0]], <8 x i8> [[TMP1]], <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
uint8x8_t test_ppairo_u8x8(uint8x8_t rs1, uint8x8_t rs2) {
return __riscv_ppairo_u8x8(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppaire_i16x4(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 6>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppaire_i16x4(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 6>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
int16x4_t test_ppaire_i16x4(int16x4_t rs1, int16x4_t rs2) {
return __riscv_ppaire_i16x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppaire_u16x4(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 6>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppaire_u16x4(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 6>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
uint16x4_t test_ppaire_u16x4(uint16x4_t rs1, uint16x4_t rs2) {
return __riscv_ppaire_u16x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppaireo_i16x4(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppaireo_i16x4(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
int16x4_t test_ppaireo_i16x4(int16x4_t rs1, int16x4_t rs2) {
return __riscv_ppaireo_i16x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppaireo_u16x4(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppaireo_u16x4(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
uint16x4_t test_ppaireo_u16x4(uint16x4_t rs1, uint16x4_t rs2) {
return __riscv_ppaireo_u16x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppairoe_i16x4(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 1, i32 4, i32 3, i32 6>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppairoe_i16x4(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 1, i32 4, i32 3, i32 6>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
int16x4_t test_ppairoe_i16x4(int16x4_t rs1, int16x4_t rs2) {
return __riscv_ppairoe_i16x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppairoe_u16x4(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 1, i32 4, i32 3, i32 6>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppairoe_u16x4(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 1, i32 4, i32 3, i32 6>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
uint16x4_t test_ppairoe_u16x4(uint16x4_t rs1, uint16x4_t rs2) {
return __riscv_ppairoe_u16x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppairo_i16x4(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 1, i32 5, i32 3, i32 7>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppairo_i16x4(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 1, i32 5, i32 3, i32 7>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
int16x4_t test_ppairo_i16x4(int16x4_t rs1, int16x4_t rs2) {
return __riscv_ppairo_i16x4(rs1, rs2);
}
// RV32-LABEL: define dso_local i64 @test_ppairo_u16x4(
// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV32-NEXT: [[ENTRY:.*:]]
// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV32-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV32-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 1, i32 5, i32 3, i32 7>
// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV32-NEXT: ret i64 [[TMP2]]
//
// RV64-LABEL: define dso_local i64 @test_ppairo_u16x4(
// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]], i64 noundef [[RS2_COERCE:%.*]]) #[[ATTR0]] {
// RV64-NEXT: [[ENTRY:.*:]]
// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16>
// RV64-NEXT: [[TMP1:%.*]] = bitcast i64 [[RS2_COERCE]] to <4 x i16>
// RV64-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> [[TMP1]], <4 x i32> <i32 1, i32 5, i32 3, i32 7>
// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[SHUFFLE_I]] to i64
// RV64-NEXT: ret i64 [[TMP2]]
//
uint16x4_t test_ppairo_u16x4(uint16x4_t rs1, uint16x4_t rs2) {
return __riscv_ppairo_u16x4(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]] {

View file

@ -2539,6 +2539,167 @@ int32x2_t test_pmulq_i32x2(int32x2_t a, int32x2_t b) {
int32x2_t test_pmulqr_i32x2(int32x2_t a, int32x2_t b) {
return __riscv_pmulqr_i32x2(a, b);
}
// CHECK-LABEL: test_ppaire_i8x4:
// CHECK: ppaire.b
int8x4_t test_ppaire_i8x4(int8x4_t rs1, int8x4_t rs2) {
return __riscv_ppaire_i8x4(rs1, rs2);
}
// CHECK-LABEL: test_ppaire_u8x4:
// CHECK: ppaire.b
uint8x4_t test_ppaire_u8x4(uint8x4_t rs1, uint8x4_t rs2) {
return __riscv_ppaire_u8x4(rs1, rs2);
}
// CHECK-LABEL: test_ppaireo_i8x4:
// CHECK: ppaireo.b
int8x4_t test_ppaireo_i8x4(int8x4_t rs1, int8x4_t rs2) {
return __riscv_ppaireo_i8x4(rs1, rs2);
}
// CHECK-LABEL: test_ppaireo_u8x4:
// CHECK: ppaireo.b
uint8x4_t test_ppaireo_u8x4(uint8x4_t rs1, uint8x4_t rs2) {
return __riscv_ppaireo_u8x4(rs1, rs2);
}
// CHECK-LABEL: test_ppairoe_i8x4:
// CHECK: ppairoe.b
int8x4_t test_ppairoe_i8x4(int8x4_t rs1, int8x4_t rs2) {
return __riscv_ppairoe_i8x4(rs1, rs2);
}
// CHECK-LABEL: test_ppairoe_u8x4:
// CHECK: ppairoe.b
uint8x4_t test_ppairoe_u8x4(uint8x4_t rs1, uint8x4_t rs2) {
return __riscv_ppairoe_u8x4(rs1, rs2);
}
// CHECK-LABEL: test_ppairo_i8x4:
// CHECK: ppairo.b
int8x4_t test_ppairo_i8x4(int8x4_t rs1, int8x4_t rs2) {
return __riscv_ppairo_i8x4(rs1, rs2);
}
// CHECK-LABEL: test_ppairo_u8x4:
// CHECK: ppairo.b
uint8x4_t test_ppairo_u8x4(uint8x4_t rs1, uint8x4_t rs2) {
return __riscv_ppairo_u8x4(rs1, rs2);
}
// CHECK-LABEL: test_ppaire_i8x8:
// RV32: ppaire.db
// RV64: ppaire.b
int8x8_t test_ppaire_i8x8(int8x8_t rs1, int8x8_t rs2) {
return __riscv_ppaire_i8x8(rs1, rs2);
}
// CHECK-LABEL: test_ppaire_u8x8:
// RV32: ppaire.db
// RV64: ppaire.b
uint8x8_t test_ppaire_u8x8(uint8x8_t rs1, uint8x8_t rs2) {
return __riscv_ppaire_u8x8(rs1, rs2);
}
// CHECK-LABEL: test_ppaireo_i8x8:
// RV32: ppaireo.db
// RV64: ppaireo.b
int8x8_t test_ppaireo_i8x8(int8x8_t rs1, int8x8_t rs2) {
return __riscv_ppaireo_i8x8(rs1, rs2);
}
// CHECK-LABEL: test_ppaireo_u8x8:
// RV32: ppaireo.db
// RV64: ppaireo.b
uint8x8_t test_ppaireo_u8x8(uint8x8_t rs1, uint8x8_t rs2) {
return __riscv_ppaireo_u8x8(rs1, rs2);
}
// CHECK-LABEL: test_ppairoe_i8x8:
// RV32: ppairoe.db
// RV64: ppairoe.b
int8x8_t test_ppairoe_i8x8(int8x8_t rs1, int8x8_t rs2) {
return __riscv_ppairoe_i8x8(rs1, rs2);
}
// CHECK-LABEL: test_ppairoe_u8x8:
// RV32: ppairoe.db
// RV64: ppairoe.b
uint8x8_t test_ppairoe_u8x8(uint8x8_t rs1, uint8x8_t rs2) {
return __riscv_ppairoe_u8x8(rs1, rs2);
}
// CHECK-LABEL: test_ppairo_i8x8:
// RV32: ppairo.db
// RV64: ppairo.b
int8x8_t test_ppairo_i8x8(int8x8_t rs1, int8x8_t rs2) {
return __riscv_ppairo_i8x8(rs1, rs2);
}
// CHECK-LABEL: test_ppairo_u8x8:
// RV32: ppairo.db
// RV64: ppairo.b
uint8x8_t test_ppairo_u8x8(uint8x8_t rs1, uint8x8_t rs2) {
return __riscv_ppairo_u8x8(rs1, rs2);
}
// CHECK-LABEL: test_ppaire_i16x4:
// RV32: ppaire.dh
// RV64: ppaire.h
int16x4_t test_ppaire_i16x4(int16x4_t rs1, int16x4_t rs2) {
return __riscv_ppaire_i16x4(rs1, rs2);
}
// CHECK-LABEL: test_ppaire_u16x4:
// RV32: ppaire.dh
// RV64: ppaire.h
uint16x4_t test_ppaire_u16x4(uint16x4_t rs1, uint16x4_t rs2) {
return __riscv_ppaire_u16x4(rs1, rs2);
}
// CHECK-LABEL: test_ppaireo_i16x4:
// RV32: ppaireo.dh
// RV64: ppaireo.h
int16x4_t test_ppaireo_i16x4(int16x4_t rs1, int16x4_t rs2) {
return __riscv_ppaireo_i16x4(rs1, rs2);
}
// CHECK-LABEL: test_ppaireo_u16x4:
// RV32: ppaireo.dh
// RV64: ppaireo.h
uint16x4_t test_ppaireo_u16x4(uint16x4_t rs1, uint16x4_t rs2) {
return __riscv_ppaireo_u16x4(rs1, rs2);
}
// CHECK-LABEL: test_ppairoe_i16x4:
// RV32: ppairoe.dh
// RV64: ppairoe.h
int16x4_t test_ppairoe_i16x4(int16x4_t rs1, int16x4_t rs2) {
return __riscv_ppairoe_i16x4(rs1, rs2);
}
// CHECK-LABEL: test_ppairoe_u16x4:
// RV32: ppairoe.dh
// RV64: ppairoe.h
uint16x4_t test_ppairoe_u16x4(uint16x4_t rs1, uint16x4_t rs2) {
return __riscv_ppairoe_u16x4(rs1, rs2);
}
// CHECK-LABEL: test_ppairo_i16x4:
// RV32: ppairo.dh
// RV64: ppairo.h
int16x4_t test_ppairo_i16x4(int16x4_t rs1, int16x4_t rs2) {
return __riscv_ppairo_i16x4(rs1, rs2);
}
// CHECK-LABEL: test_ppairo_u16x4:
// RV32: ppairo.dh
// RV64: ppairo.h
uint16x4_t test_ppairo_u16x4(uint16x4_t rs1, uint16x4_t rs2) {
return __riscv_ppairo_u16x4(rs1, rs2);
}
// CHECK-LABEL: test_pnzip_i8x4:
// CHECK: ppaire.b
int8x4_t test_pnzip_i8x4(int16x2_t rs1, int16x2_t rs2) {

View file

@ -6527,6 +6527,8 @@ lowerVECTOR_SHUFFLEAsRV32PNarrowingShift(ShuffleVectorSDNode *SVN,
// Match a strided-interleave shuffle that forms a P-extension packed pair:
// <a0, b0, a2, b2, ...> -> ppaire.*
// <a0, b1, a2, b3, ...> -> ppaireo.*
// <a1, b0, a3, b2, ...> -> ppairoe.*
// <a1, b1, a3, b3, ...> -> ppairo.*
static SDValue lowerVECTOR_SHUFFLEAsPPair(ShuffleVectorSDNode *SVN,
SelectionDAG &DAG) {
@ -6549,32 +6551,37 @@ static SDValue lowerVECTOR_SHUFFLEAsPPair(ShuffleVectorSDNode *SVN,
bool V1IsSplat = DAG.isSplatValue(V1);
bool V2IsSplat = DAG.isSplatValue(V2);
// Match <start, N+start, start+2, N+start+2, ...>: even lanes come from V1
// and odd lanes from V2 (start=0, ppaire) or vice versa (start=1, ppairo).
// Trailing lanes may be undef when a 4-byte source was widened to v8i8.
auto IsStrided = [&](unsigned Start) {
// Match the packed pair shuffle forms:
// <V1Start, N+V2Start, V1Start+2, N+V2Start+2, ...>
// where each start is 0 for even lanes or 1 for odd lanes. This covers all
// four PPAIRE/PPAIREO/PPAIROE/PPAIRO combinations. Trailing lanes may be
// undef when a 4-byte source was widened to v8i8.
auto IsStrided = [&](unsigned V1Start, unsigned V2Start) {
for (unsigned I = 0; I != NumElts / 2; ++I) {
int M0 = Mask[2 * I];
int M1 = Mask[2 * I + 1];
if (M0 >= 0 &&
(V1IsSplat ? M0 >= (int)NumElts : M0 != (int)(Start + 2 * I)))
(V1IsSplat ? M0 >= (int)NumElts : M0 != (int)(V1Start + 2 * I)))
return false;
if (M1 >= 0 && (V2IsSplat ? M1 < (int)NumElts
: M1 != (int)(NumElts + Start + 2 * I)))
: M1 != (int)(NumElts + V2Start + 2 * I)))
return false;
}
return true;
};
bool IsOdd;
if (IsStrided(0))
IsOdd = false;
else if (IsStrided(1))
IsOdd = true;
unsigned Opc;
if (IsStrided(0, 0))
Opc = RISCVISD::PPAIRE;
else if (IsStrided(1, 1))
Opc = RISCVISD::PPAIRO;
else if (IsStrided(0, 1))
Opc = RISCVISD::PPAIREO;
else if (IsStrided(1, 0))
Opc = RISCVISD::PPAIROE;
else
return SDValue();
unsigned Opc = IsOdd ? RISCVISD::PPAIRO : RISCVISD::PPAIRE;
return DAG.getNode(Opc, DL, VT, V1, V2);
}

View file

@ -1866,11 +1866,13 @@ def shiftMask64 : ComplexPattern<XLenVT, 1, "selectShiftMask<64>", [], [], 0>;
def BuildGPRPair : OutPatFrag<(ops node:$lo, node:$hi),
(REG_SEQUENCE GPRPair, $lo, sub_gpr_even, $hi, sub_gpr_odd)>;
def SDT_RISCVPPairEven : SDTypeProfile<1, 2, [SDTCisVec<0>,
SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>]>;
def riscv_ppaire : RVSDNode<"PPAIRE", SDT_RISCVPPairEven>;
def riscv_ppairo : RVSDNode<"PPAIRO", SDT_RISCVPPairEven>;
def SDT_RISCVPPair : SDTypeProfile<1, 2, [SDTCisVec<0>,
SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>]>;
def riscv_ppaire : RVSDNode<"PPAIRE", SDT_RISCVPPair>;
def riscv_ppaireo : RVSDNode<"PPAIREO", SDT_RISCVPPair>;
def riscv_ppairoe : RVSDNode<"PPAIROE", SDT_RISCVPPair>;
def riscv_ppairo : RVSDNode<"PPAIRO", SDT_RISCVPPair>;
def SDT_RISCVPackedBinary : SDTypeProfile<1, 2, [SDTCisVec<0>,
SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>]>;
@ -2321,14 +2323,26 @@ let append Predicates = [IsRV32] in {
// Packed pair: pair the even/odd-position elements of rs1 and rs2.
def : Pat<(v4i8 (riscv_ppaire (v4i8 GPR:$rs1), (v4i8 GPR:$rs2))),
(PPAIRE_B GPR:$rs1, GPR:$rs2)>;
def : Pat<(v4i8 (riscv_ppaireo (v4i8 GPR:$rs1), (v4i8 GPR:$rs2))),
(PPAIREO_B GPR:$rs1, GPR:$rs2)>;
def : Pat<(v4i8 (riscv_ppairoe (v4i8 GPR:$rs1), (v4i8 GPR:$rs2))),
(PPAIROE_B GPR:$rs1, GPR:$rs2)>;
def : Pat<(v4i8 (riscv_ppairo (v4i8 GPR:$rs1), (v4i8 GPR:$rs2))),
(PPAIRO_B GPR:$rs1, GPR:$rs2)>;
def : Pat<(v8i8 (riscv_ppaire GPRPair:$rs1, GPRPair:$rs2)),
(PPAIRE_DB GPRPair:$rs1, GPRPair:$rs2)>;
def : Pat<(v8i8 (riscv_ppaireo GPRPair:$rs1, GPRPair:$rs2)),
(PPAIREO_DB GPRPair:$rs1, GPRPair:$rs2)>;
def : Pat<(v8i8 (riscv_ppairoe GPRPair:$rs1, GPRPair:$rs2)),
(PPAIROE_DB GPRPair:$rs1, GPRPair:$rs2)>;
def : Pat<(v8i8 (riscv_ppairo GPRPair:$rs1, GPRPair:$rs2)),
(PPAIRO_DB GPRPair:$rs1, GPRPair:$rs2)>;
def : Pat<(v4i16 (riscv_ppaire GPRPair:$rs1, GPRPair:$rs2)),
(PPAIRE_DH GPRPair:$rs1, GPRPair:$rs2)>;
def : Pat<(v4i16 (riscv_ppaireo GPRPair:$rs1, GPRPair:$rs2)),
(PPAIREO_DH GPRPair:$rs1, GPRPair:$rs2)>;
def : Pat<(v4i16 (riscv_ppairoe GPRPair:$rs1, GPRPair:$rs2)),
(PPAIROE_DH GPRPair:$rs1, GPRPair:$rs2)>;
def : Pat<(v4i16 (riscv_ppairo GPRPair:$rs1, GPRPair:$rs2)),
(PPAIRO_DH GPRPair:$rs1, GPRPair:$rs2)>;
@ -2888,10 +2902,18 @@ let append Predicates = [IsRV64] in {
// Packed pair: pair the even/odd-position elements of rs1 and rs2.
def : Pat<(v8i8 (riscv_ppaire (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))),
(PPAIRE_B GPR:$rs1, GPR:$rs2)>;
def : Pat<(v8i8 (riscv_ppaireo (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))),
(PPAIREO_B GPR:$rs1, GPR:$rs2)>;
def : Pat<(v8i8 (riscv_ppairoe (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))),
(PPAIROE_B GPR:$rs1, GPR:$rs2)>;
def : Pat<(v8i8 (riscv_ppairo (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))),
(PPAIRO_B GPR:$rs1, GPR:$rs2)>;
def : Pat<(v4i16 (riscv_ppaire (v4i16 GPR:$rs1), (v4i16 GPR:$rs2))),
(PPAIRE_H GPR:$rs1, GPR:$rs2)>;
def : Pat<(v4i16 (riscv_ppaireo (v4i16 GPR:$rs1), (v4i16 GPR:$rs2))),
(PPAIREO_H GPR:$rs1, GPR:$rs2)>;
def : Pat<(v4i16 (riscv_ppairoe (v4i16 GPR:$rs1), (v4i16 GPR:$rs2))),
(PPAIROE_H GPR:$rs1, GPR:$rs2)>;
def : Pat<(v4i16 (riscv_ppairo (v4i16 GPR:$rs1), (v4i16 GPR:$rs2))),
(PPAIRO_H GPR:$rs1, GPR:$rs2)>;
} // append Predicates = [IsRV64]

View file

@ -2304,6 +2304,42 @@ define <4 x i8> @test_vselect_v4i8(<4 x i8> %a, <4 x i8> %b, <4 x i8> %c) {
ret <4 x i8> %res
}
define <4 x i8> @test_ppaire_v4i8(<4 x i8> %a, <4 x i8> %b) {
; CHECK-LABEL: test_ppaire_v4i8:
; CHECK: # %bb.0:
; CHECK-NEXT: ppaire.b a0, a0, a1
; CHECK-NEXT: ret
%res = shufflevector <4 x i8> %a, <4 x i8> %b, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
ret <4 x i8> %res
}
define <4 x i8> @test_ppaireo_v4i8(<4 x i8> %a, <4 x i8> %b) {
; CHECK-LABEL: test_ppaireo_v4i8:
; CHECK: # %bb.0:
; CHECK-NEXT: ppaireo.b a0, a0, a1
; CHECK-NEXT: ret
%res = shufflevector <4 x i8> %a, <4 x i8> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
ret <4 x i8> %res
}
define <4 x i8> @test_ppairoe_v4i8(<4 x i8> %a, <4 x i8> %b) {
; CHECK-LABEL: test_ppairoe_v4i8:
; CHECK: # %bb.0:
; CHECK-NEXT: ppairoe.b a0, a0, a1
; CHECK-NEXT: ret
%res = shufflevector <4 x i8> %a, <4 x i8> %b, <4 x i32> <i32 1, i32 4, i32 3, i32 6>
ret <4 x i8> %res
}
define <4 x i8> @test_ppairo_v4i8(<4 x i8> %a, <4 x i8> %b) {
; CHECK-LABEL: test_ppairo_v4i8:
; CHECK: # %bb.0:
; CHECK-NEXT: ppairo.b a0, a0, a1
; CHECK-NEXT: ret
%res = shufflevector <4 x i8> %a, <4 x i8> %b, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
ret <4 x i8> %res
}
define <2 x i16> @test_bswap_v2i16(<2 x i16> %a) {
; CHECK-LABEL: test_bswap_v2i16:
; CHECK: # %bb.0:

View file

@ -6168,3 +6168,59 @@ define <2 x i32> @test_undef_v2i32() {
; CHECK-NEXT: ret
ret <2 x i32> undef
}
define <8 x i8> @test_ppaireo_v8i8(<8 x i8> %a, <8 x i8> %b) {
; RV32-LABEL: test_ppaireo_v8i8:
; RV32: # %bb.0:
; RV32-NEXT: ppaireo.db a0, a0, a2
; RV32-NEXT: ret
;
; RV64-LABEL: test_ppaireo_v8i8:
; RV64: # %bb.0:
; RV64-NEXT: ppaireo.b a0, a0, a1
; RV64-NEXT: ret
%res = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>
ret <8 x i8> %res
}
define <8 x i8> @test_ppairoe_v8i8(<8 x i8> %a, <8 x i8> %b) {
; RV32-LABEL: test_ppairoe_v8i8:
; RV32: # %bb.0:
; RV32-NEXT: ppairoe.db a0, a0, a2
; RV32-NEXT: ret
;
; RV64-LABEL: test_ppairoe_v8i8:
; RV64: # %bb.0:
; RV64-NEXT: ppairoe.b a0, a0, a1
; RV64-NEXT: ret
%res = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 1, i32 8, i32 3, i32 10, i32 5, i32 12, i32 7, i32 14>
ret <8 x i8> %res
}
define <4 x i16> @test_ppaireo_v4i16(<4 x i16> %a, <4 x i16> %b) {
; RV32-LABEL: test_ppaireo_v4i16:
; RV32: # %bb.0:
; RV32-NEXT: ppaireo.dh a0, a0, a2
; RV32-NEXT: ret
;
; RV64-LABEL: test_ppaireo_v4i16:
; RV64: # %bb.0:
; RV64-NEXT: ppaireo.h a0, a0, a1
; RV64-NEXT: ret
%res = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
ret <4 x i16> %res
}
define <4 x i16> @test_ppairoe_v4i16(<4 x i16> %a, <4 x i16> %b) {
; RV32-LABEL: test_ppairoe_v4i16:
; RV32: # %bb.0:
; RV32-NEXT: ppairoe.dh a0, a0, a2
; RV32-NEXT: ret
;
; RV64-LABEL: test_ppairoe_v4i16:
; RV64: # %bb.0:
; RV64-NEXT: ppairoe.h a0, a0, a1
; RV64-NEXT: ret
%res = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 1, i32 4, i32 3, i32 6>
ret <4 x i16> %res
}