[Clang][RISCV] packed absolute difference sum intrinsics (#207936)
Add the __riscv_pabdsumu/pabdsumau_* header wrappers over new __builtin_riscv_* builtins, lowering to the llvm.riscv.pabdsumu/pabdsumau intrinsics.
This commit is contained in:
parent
62907d4a3b
commit
35678db1b4
5 changed files with 231 additions and 0 deletions
|
|
@ -247,6 +247,16 @@ def pmerge_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4,
|
|||
def pmerge_u32x2 : RISCVBuiltin<"_Vector<2, unsigned int>(_Vector<2, unsigned int>, _Vector<2, unsigned int>, _Vector<2, unsigned int>)">;
|
||||
def pmerge_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>, _Vector<2, unsigned int>)">;
|
||||
|
||||
// Packed Absolute Difference Sum (32-bit)
|
||||
def pabdsumu_u8x4_u32 : RISCVBuiltin<"unsigned int(_Vector<4, unsigned char>, _Vector<4, unsigned char>)">;
|
||||
def pabdsumau_u8x4_u32 : RISCVBuiltin<"unsigned int(unsigned int, _Vector<4, unsigned char>, _Vector<4, unsigned char>)">;
|
||||
|
||||
// Packed Absolute Difference Sum (64-bit)
|
||||
def pabdsumu_u8x8_u32 : RISCVBuiltin<"unsigned int(_Vector<8, unsigned char>, _Vector<8, unsigned char>)">;
|
||||
def pabdsumu_u8x8_u64 : RISCVBuiltin<"uint64_t(_Vector<8, unsigned char>, _Vector<8, unsigned char>)">;
|
||||
def pabdsumau_u8x8_u32 : RISCVBuiltin<"unsigned int(unsigned int, _Vector<8, unsigned char>, _Vector<8, unsigned char>)">;
|
||||
def pabdsumau_u8x8_u64 : RISCVBuiltin<"uint64_t(uint64_t, _Vector<8, unsigned char>, _Vector<8, unsigned char>)">;
|
||||
|
||||
} // Features = "experimental-p"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
|||
|
|
@ -1392,6 +1392,34 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
|
|||
break;
|
||||
}
|
||||
|
||||
// Packed Absolute Difference Sum
|
||||
case RISCV::BI__builtin_riscv_pabdsumu_u8x4_u32:
|
||||
case RISCV::BI__builtin_riscv_pabdsumu_u8x8_u32:
|
||||
case RISCV::BI__builtin_riscv_pabdsumu_u8x8_u64:
|
||||
case RISCV::BI__builtin_riscv_pabdsumau_u8x4_u32:
|
||||
case RISCV::BI__builtin_riscv_pabdsumau_u8x8_u32:
|
||||
case RISCV::BI__builtin_riscv_pabdsumau_u8x8_u64: {
|
||||
switch (BuiltinID) {
|
||||
default:
|
||||
llvm_unreachable("unexpected builtin ID");
|
||||
case RISCV::BI__builtin_riscv_pabdsumu_u8x4_u32:
|
||||
case RISCV::BI__builtin_riscv_pabdsumu_u8x8_u32:
|
||||
case RISCV::BI__builtin_riscv_pabdsumu_u8x8_u64:
|
||||
ID = Intrinsic::riscv_pabdsumu;
|
||||
break;
|
||||
case RISCV::BI__builtin_riscv_pabdsumau_u8x4_u32:
|
||||
case RISCV::BI__builtin_riscv_pabdsumau_u8x8_u32:
|
||||
case RISCV::BI__builtin_riscv_pabdsumau_u8x8_u64:
|
||||
ID = Intrinsic::riscv_pabdsumau;
|
||||
break;
|
||||
}
|
||||
|
||||
// The two vector sources are the last two arguments; the accumulate form
|
||||
// has an extra accumulator argument first.
|
||||
IntrinsicTypes = {ResultType, Ops.back()->getType()};
|
||||
break;
|
||||
}
|
||||
|
||||
// Zk builtins
|
||||
|
||||
// Zknh
|
||||
|
|
|
|||
|
|
@ -130,6 +130,18 @@ typedef uint32_t uint32x2_t __attribute__((__vector_size__(8)));
|
|||
return __builtin_shufflevector(__rs1, __rs1, 7, 6, 5, 4, 3, 2, 1, 0); \
|
||||
}
|
||||
|
||||
#define __packed_abdsum(name, rty, ty, builtin) \
|
||||
static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \
|
||||
ty __rs2) { \
|
||||
return builtin(__rs1, __rs2); \
|
||||
}
|
||||
|
||||
#define __packed_abdsum_acc(name, rty, ty, builtin) \
|
||||
static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(rty __rd, ty __rs1, \
|
||||
ty __rs2) { \
|
||||
return builtin(__rd, __rs1, __rs2); \
|
||||
}
|
||||
|
||||
// clang-format off: macro call sites have no trailing semicolons, which
|
||||
// confuses clang-format into a deeply nested expression.
|
||||
|
||||
|
|
@ -497,6 +509,16 @@ __packed_merge_builtin(pmerge_i16x4, int16x4_t, uint16x4_t, __builtin_riscv_pmer
|
|||
__packed_merge_builtin(pmerge_u32x2, uint32x2_t, uint32x2_t, __builtin_riscv_pmerge_u32x2)
|
||||
__packed_merge_builtin(pmerge_i32x2, int32x2_t, uint32x2_t, __builtin_riscv_pmerge_i32x2)
|
||||
|
||||
/* Packed Absolute Difference Sum (32-bit) */
|
||||
__packed_abdsum(pabdsumu_u8x4_u32, uint32_t, uint8x4_t, __builtin_riscv_pabdsumu_u8x4_u32)
|
||||
__packed_abdsum_acc(pabdsumau_u8x4_u32, uint32_t, uint8x4_t, __builtin_riscv_pabdsumau_u8x4_u32)
|
||||
|
||||
/* Packed Absolute Difference Sum (64-bit) */
|
||||
__packed_abdsum(pabdsumu_u8x8_u32, uint32_t, uint8x8_t, __builtin_riscv_pabdsumu_u8x8_u32)
|
||||
__packed_abdsum(pabdsumu_u8x8_u64, uint64_t, uint8x8_t, __builtin_riscv_pabdsumu_u8x8_u64)
|
||||
__packed_abdsum_acc(pabdsumau_u8x8_u32, uint32_t, uint8x8_t, __builtin_riscv_pabdsumau_u8x8_u32)
|
||||
__packed_abdsum_acc(pabdsumau_u8x8_u64, uint64_t, uint8x8_t, __builtin_riscv_pabdsumau_u8x8_u64)
|
||||
|
||||
// clang-format on
|
||||
|
||||
#undef __packed_splat2
|
||||
|
|
@ -521,6 +543,8 @@ __packed_merge_builtin(pmerge_i32x2, int32x2_t, uint32x2_t, __builtin_riscv_pmer
|
|||
#undef __packed_reverse2
|
||||
#undef __packed_reverse4
|
||||
#undef __packed_reverse8
|
||||
#undef __packed_abdsum
|
||||
#undef __packed_abdsum_acc
|
||||
#undef __DEFAULT_FN_ATTRS
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
|||
|
|
@ -6575,3 +6575,125 @@ int32x2_t test_prev_i32x2(int32x2_t rs1) {
|
|||
uint32x2_t test_prev_u32x2(uint32x2_t rs1) {
|
||||
return __riscv_prev_u32x2(rs1);
|
||||
}
|
||||
|
||||
/* 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]] {
|
||||
// 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: [[TMP2:%.*]] = call i32 @llvm.riscv.pabdsumu.i32.v4i8(<4 x i8> [[TMP0]], <4 x i8> [[TMP1]])
|
||||
// RV32-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
// RV64-LABEL: define dso_local signext i32 @test_pabdsumu_u8x4_u32(
|
||||
// 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: [[TMP2:%.*]] = call i32 @llvm.riscv.pabdsumu.i32.v4i8(<4 x i8> [[TMP0]], <4 x i8> [[TMP1]])
|
||||
// RV64-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
uint32_t test_pabdsumu_u8x4_u32(uint8x4_t rs1, uint8x4_t rs2) {
|
||||
return __riscv_pabdsumu_u8x4_u32(rs1, rs2);
|
||||
}
|
||||
|
||||
// RV32-LABEL: define dso_local i32 @test_pabdsumau_u8x4_u32(
|
||||
// RV32-SAME: i32 noundef [[RD:%.*]], 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: [[TMP2:%.*]] = call i32 @llvm.riscv.pabdsumau.i32.v4i8(i32 [[RD]], <4 x i8> [[TMP0]], <4 x i8> [[TMP1]])
|
||||
// RV32-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
// RV64-LABEL: define dso_local signext i32 @test_pabdsumau_u8x4_u32(
|
||||
// RV64-SAME: i32 noundef signext [[RD:%.*]], 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: [[TMP2:%.*]] = call i32 @llvm.riscv.pabdsumau.i32.v4i8(i32 [[RD]], <4 x i8> [[TMP0]], <4 x i8> [[TMP1]])
|
||||
// RV64-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
uint32_t test_pabdsumau_u8x4_u32(uint32_t rd, uint8x4_t rs1, uint8x4_t rs2) {
|
||||
return __riscv_pabdsumau_u8x4_u32(rd, rs1, rs2);
|
||||
}
|
||||
|
||||
/* Packed Absolute Difference Sum (64-bit) */
|
||||
// RV32-LABEL: define dso_local i32 @test_pabdsumu_u8x8_u32(
|
||||
// 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: [[TMP2:%.*]] = call i32 @llvm.riscv.pabdsumu.i32.v8i8(<8 x i8> [[TMP0]], <8 x i8> [[TMP1]])
|
||||
// RV32-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
// RV64-LABEL: define dso_local signext i32 @test_pabdsumu_u8x8_u32(
|
||||
// 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: [[TMP2:%.*]] = call i32 @llvm.riscv.pabdsumu.i32.v8i8(<8 x i8> [[TMP0]], <8 x i8> [[TMP1]])
|
||||
// RV64-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
uint32_t test_pabdsumu_u8x8_u32(uint8x8_t rs1, uint8x8_t rs2) {
|
||||
return __riscv_pabdsumu_u8x8_u32(rs1, rs2);
|
||||
}
|
||||
|
||||
// RV32-LABEL: define dso_local i64 @test_pabdsumu_u8x8_u64(
|
||||
// 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: [[TMP2:%.*]] = call i64 @llvm.riscv.pabdsumu.i64.v8i8(<8 x i8> [[TMP0]], <8 x i8> [[TMP1]])
|
||||
// RV32-NEXT: ret i64 [[TMP2]]
|
||||
//
|
||||
// RV64-LABEL: define dso_local i64 @test_pabdsumu_u8x8_u64(
|
||||
// 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: [[TMP2:%.*]] = call i64 @llvm.riscv.pabdsumu.i64.v8i8(<8 x i8> [[TMP0]], <8 x i8> [[TMP1]])
|
||||
// RV64-NEXT: ret i64 [[TMP2]]
|
||||
//
|
||||
uint64_t test_pabdsumu_u8x8_u64(uint8x8_t rs1, uint8x8_t rs2) {
|
||||
return __riscv_pabdsumu_u8x8_u64(rs1, rs2);
|
||||
}
|
||||
|
||||
// RV32-LABEL: define dso_local i32 @test_pabdsumau_u8x8_u32(
|
||||
// RV32-SAME: i32 noundef [[RD:%.*]], 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: [[TMP2:%.*]] = call i32 @llvm.riscv.pabdsumau.i32.v8i8(i32 [[RD]], <8 x i8> [[TMP0]], <8 x i8> [[TMP1]])
|
||||
// RV32-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
// RV64-LABEL: define dso_local signext i32 @test_pabdsumau_u8x8_u32(
|
||||
// RV64-SAME: i32 noundef signext [[RD:%.*]], 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: [[TMP2:%.*]] = call i32 @llvm.riscv.pabdsumau.i32.v8i8(i32 [[RD]], <8 x i8> [[TMP0]], <8 x i8> [[TMP1]])
|
||||
// RV64-NEXT: ret i32 [[TMP2]]
|
||||
//
|
||||
uint32_t test_pabdsumau_u8x8_u32(uint32_t rd, uint8x8_t rs1, uint8x8_t rs2) {
|
||||
return __riscv_pabdsumau_u8x8_u32(rd, rs1, rs2);
|
||||
}
|
||||
|
||||
// RV32-LABEL: define dso_local i64 @test_pabdsumau_u8x8_u64(
|
||||
// RV32-SAME: i64 noundef [[RD:%.*]], 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: [[TMP2:%.*]] = call i64 @llvm.riscv.pabdsumau.i64.v8i8(i64 [[RD]], <8 x i8> [[TMP0]], <8 x i8> [[TMP1]])
|
||||
// RV32-NEXT: ret i64 [[TMP2]]
|
||||
//
|
||||
// RV64-LABEL: define dso_local i64 @test_pabdsumau_u8x8_u64(
|
||||
// RV64-SAME: i64 noundef [[RD:%.*]], 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: [[TMP2:%.*]] = call i64 @llvm.riscv.pabdsumau.i64.v8i8(i64 [[RD]], <8 x i8> [[TMP0]], <8 x i8> [[TMP1]])
|
||||
// RV64-NEXT: ret i64 [[TMP2]]
|
||||
//
|
||||
uint64_t test_pabdsumau_u8x8_u64(uint64_t rd, uint8x8_t rs1, uint8x8_t rs2) {
|
||||
return __riscv_pabdsumau_u8x8_u64(rd, rs1, rs2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2289,3 +2289,50 @@ int32x2_t test_pmerge_mvm_i32x2(int32x2_t rs1, uint32x2_t rd, int32x2_t rs2) {
|
|||
int32x2_t test_pmerge_mvmn_i32x2(int32x2_t rs2, int32x2_t rs1, uint32x2_t rd) {
|
||||
return __riscv_pmerge_i32x2(rs1, rs2, rd);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test_pabdsumu_u8x4_u32:
|
||||
// RV32: pabdsumu.b
|
||||
// RV64: zext.w
|
||||
// RV64: pabdsumu.b
|
||||
uint32_t test_pabdsumu_u8x4_u32(uint8x4_t a, uint8x4_t b) {
|
||||
return __riscv_pabdsumu_u8x4_u32(a, b);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test_pabdsumau_u8x4_u32:
|
||||
// RV32: pabdsumau.b
|
||||
// RV64: zext.w
|
||||
// RV64: pabdsumau.b
|
||||
uint32_t test_pabdsumau_u8x4_u32(uint32_t rd, uint8x4_t a, uint8x4_t b) {
|
||||
return __riscv_pabdsumau_u8x4_u32(rd, a, b);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test_pabdsumu_u8x8_u32:
|
||||
// RV32: pabdsumu.b
|
||||
// RV32: pabdsumau.b
|
||||
// RV64: pabdsumu.b
|
||||
uint32_t test_pabdsumu_u8x8_u32(uint8x8_t a, uint8x8_t b) {
|
||||
return __riscv_pabdsumu_u8x8_u32(a, b);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test_pabdsumu_u8x8_u64:
|
||||
// RV32-COUNT-2: pabdsumu.b
|
||||
// RV32: waddu
|
||||
// RV64: pabdsumu.b
|
||||
uint64_t test_pabdsumu_u8x8_u64(uint8x8_t a, uint8x8_t b) {
|
||||
return __riscv_pabdsumu_u8x8_u64(a, b);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test_pabdsumau_u8x8_u32:
|
||||
// RV32-COUNT-2: pabdsumau.b
|
||||
// RV64: pabdsumau.b
|
||||
uint32_t test_pabdsumau_u8x8_u32(uint32_t rd, uint8x8_t a, uint8x8_t b) {
|
||||
return __riscv_pabdsumau_u8x8_u32(rd, a, b);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test_pabdsumau_u8x8_u64:
|
||||
// RV32-COUNT-2: pabdsumu.b
|
||||
// RV32: waddau
|
||||
// RV64: pabdsumau.b
|
||||
uint64_t test_pabdsumau_u8x8_u64(uint64_t rd, uint8x8_t a, uint8x8_t b) {
|
||||
return __riscv_pabdsumau_u8x8_u64(rd, a, b);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue