diff --git a/3rdparty/hal_rvv/hal_rvv_1p0/merge.hpp b/3rdparty/hal_rvv/hal_rvv_1p0/merge.hpp index 353885b709..760024f429 100644 --- a/3rdparty/hal_rvv/hal_rvv_1p0/merge.hpp +++ b/3rdparty/hal_rvv/hal_rvv_1p0/merge.hpp @@ -17,236 +17,195 @@ namespace cv { namespace cv_hal_rvv { #undef cv_hal_merge64s #define cv_hal_merge64s cv::cv_hal_rvv::merge64s -#if defined __GNUC__ -__attribute__((optimize("no-tree-vectorize"))) -#endif +#if defined __clang__ && __clang_major__ < 18 +#define OPENCV_HAL_IMPL_RVV_VCREATE_x2(suffix, width, v0, v1) \ + __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x2(seg, 0, v0); \ + seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x2(seg, 1, v1); + +#define OPENCV_HAL_IMPL_RVV_VCREATE_x3(suffix, width, v0, v1, v2) \ + __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x3(seg, 0, v0); \ + seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x3(seg, 1, v1); \ + seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x3(seg, 2, v2); + +#define OPENCV_HAL_IMPL_RVV_VCREATE_x4(suffix, width, v0, v1, v2, v3) \ + __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(seg, 0, v0); \ + seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(seg, 1, v1); \ + seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(seg, 2, v2); \ + seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(seg, 3, v3); + +#define __riscv_vcreate_v_u8m4x2(v0, v1) OPENCV_HAL_IMPL_RVV_VCREATE_x2(u8, 4, v0, v1) +#define __riscv_vcreate_v_u8m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u8, 2, v0, v1, v2) +#define __riscv_vcreate_v_u8m2x4(v0, v1, v2, v3) OPENCV_HAL_IMPL_RVV_VCREATE_x4(u8, 2, v0, v1, v2, v3) +#define __riscv_vcreate_v_u16m4x2(v0, v1) OPENCV_HAL_IMPL_RVV_VCREATE_x2(u16, 4, v0, v1) +#define __riscv_vcreate_v_u16m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u16, 2, v0, v1, v2) +#define __riscv_vcreate_v_u16m2x4(v0, v1, v2, v3) OPENCV_HAL_IMPL_RVV_VCREATE_x4(u16, 2, v0, v1, v2, v3) +#endif // clang < 18 + inline int merge8u(const uchar** src, uchar* dst, int len, int cn ) { - int k = cn % 4 ? cn % 4 : 4; - int i = 0; - int vl = __riscv_vsetvlmax_e8m1(); - if( k == 1 ) + int vl = 0; + if (cn == 1) { const uchar* src0 = src[0]; - for( ; i <= len - vl; i += vl) + for (int i = 0; i < len; i += vl) { - auto a = __riscv_vle8_v_u8m1(src0 + i, vl); - __riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*cn, a, vl); + vl = __riscv_vsetvl_e8m8(len - i); + __riscv_vse8_v_u8m8(dst + i, __riscv_vle8_v_u8m8(src0 + i, vl), vl); } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; i < len; i++) - dst[i*cn] = src0[i]; } - else if( k == 2 ) + else if (cn == 2) { const uchar *src0 = src[0], *src1 = src[1]; - for( ; i <= len - vl; i += vl) + for (int i = 0; i < len; i += vl) { - auto a = __riscv_vle8_v_u8m1(src0 + i, vl); - auto b = __riscv_vle8_v_u8m1(src1 + i, vl); - __riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*cn, a, vl); - __riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*cn, b, vl); - } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; i < len; i++ ) - { - dst[i*cn] = src0[i]; - dst[i*cn+1] = src1[i]; + vl = __riscv_vsetvl_e8m4(len - i); + vuint8m4x2_t seg = __riscv_vcreate_v_u8m4x2( + __riscv_vle8_v_u8m4(src0 + i, vl), + __riscv_vle8_v_u8m4(src1 + i, vl) + ); + __riscv_vsseg2e8_v_u8m4x2(dst + i * cn, seg, vl); } } - else if( k == 3 ) + else if (cn == 3) { const uchar *src0 = src[0], *src1 = src[1], *src2 = src[2]; - for( ; i <= len - vl; i += vl) + for (int i = 0; i < len; i += vl) { - auto a = __riscv_vle8_v_u8m1(src0 + i, vl); - auto b = __riscv_vle8_v_u8m1(src1 + i, vl); - auto c = __riscv_vle8_v_u8m1(src2 + i, vl); - __riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*cn, a, vl); - __riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*cn, b, vl); - __riscv_vsse8_v_u8m1(dst + i*cn + 2, sizeof(uchar)*cn, c, vl); + vl = __riscv_vsetvl_e8m2(len - i); + vuint8m2x3_t seg = __riscv_vcreate_v_u8m2x3( + __riscv_vle8_v_u8m2(src0 + i, vl), + __riscv_vle8_v_u8m2(src1 + i, vl), + __riscv_vle8_v_u8m2(src2 + i, vl) + ); + __riscv_vsseg3e8_v_u8m2x3(dst + i * cn, seg, vl); } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; i < len; i++ ) + } + else if (cn == 4) + { + const uchar *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3]; + for (int i = 0; i < len; i += vl) { - dst[i*cn] = src0[i]; - dst[i*cn+1] = src1[i]; - dst[i*cn+2] = src2[i]; + vl = __riscv_vsetvl_e8m2(len - i); + vuint8m2x4_t seg = __riscv_vcreate_v_u8m2x4( + __riscv_vle8_v_u8m2(src0 + i, vl), + __riscv_vle8_v_u8m2(src1 + i, vl), + __riscv_vle8_v_u8m2(src2 + i, vl), + __riscv_vle8_v_u8m2(src3 + i, vl) + ); + __riscv_vsseg4e8_v_u8m2x4(dst + i * cn, seg, vl); } } else { - const uchar *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3]; - for( ; i <= len - vl; i += vl) + int k = 0; + for (; k <= cn - 4; k += 4) { - auto a = __riscv_vle8_v_u8m1(src0 + i, vl); - auto b = __riscv_vle8_v_u8m1(src1 + i, vl); - auto c = __riscv_vle8_v_u8m1(src2 + i, vl); - auto d = __riscv_vle8_v_u8m1(src3 + i, vl); - __riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*cn, a, vl); - __riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*cn, b, vl); - __riscv_vsse8_v_u8m1(dst + i*cn + 2, sizeof(uchar)*cn, c, vl); - __riscv_vsse8_v_u8m1(dst + i*cn + 3, sizeof(uchar)*cn, d, vl); + const uchar *src0 = src[k], *src1 = src[k + 1], *src2 = src[k + 2], *src3 = src[k + 3]; + for (int i = 0; i < len; i += vl) + { + vl = __riscv_vsetvl_e8m2(len - i); + vuint8m2x4_t seg = __riscv_vcreate_v_u8m2x4( + __riscv_vle8_v_u8m2(src0 + i, vl), + __riscv_vle8_v_u8m2(src1 + i, vl), + __riscv_vle8_v_u8m2(src2 + i, vl), + __riscv_vle8_v_u8m2(src3 + i, vl) + ); + __riscv_vssseg4e8_v_u8m2x4(dst + k + i * cn, cn, seg, vl); + } } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; i < len; i++ ) + for (; k < cn; ++k) { - dst[i*cn] = src0[i]; - dst[i*cn+1] = src1[i]; - dst[i*cn+2] = src2[i]; - dst[i*cn+3] = src3[i]; - } - } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; k < cn; k += 4 ) - { - const uchar *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3]; - i = 0; - for( ; i <= len - vl; i += vl) - { - auto a = __riscv_vle8_v_u8m1(src0 + i, vl); - auto b = __riscv_vle8_v_u8m1(src1 + i, vl); - auto c = __riscv_vle8_v_u8m1(src2 + i, vl); - auto d = __riscv_vle8_v_u8m1(src3 + i, vl); - __riscv_vsse8_v_u8m1(dst + k+i*cn, sizeof(uchar)*cn, a, vl); - __riscv_vsse8_v_u8m1(dst + k+i*cn + 1, sizeof(uchar)*cn, b, vl); - __riscv_vsse8_v_u8m1(dst + k+i*cn + 2, sizeof(uchar)*cn, c, vl); - __riscv_vsse8_v_u8m1(dst + k+i*cn + 3, sizeof(uchar)*cn, d, vl); - } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; i < len; i++ ) - { - dst[k+i*cn] = src0[i]; - dst[k+i*cn+1] = src1[i]; - dst[k+i*cn+2] = src2[i]; - dst[k+i*cn+3] = src3[i]; + const uchar* srcK = src[k]; + for (int i = 0; i < len; i += vl) + { + vl = __riscv_vsetvl_e8m2(len - i); + vuint8m2_t seg = __riscv_vle8_v_u8m2(srcK + i, vl); + __riscv_vsse8_v_u8m2(dst + k + i * cn, cn, seg, vl); + } } } return CV_HAL_ERROR_OK; } -#if defined __GNUC__ -__attribute__((optimize("no-tree-vectorize"))) -#endif inline int merge16u(const ushort** src, ushort* dst, int len, int cn ) { - int k = cn % 4 ? cn % 4 : 4; - int i = 0; - int vl = __riscv_vsetvlmax_e16m1(); - if( k == 1 ) + int vl = 0; + if (cn == 1) { const ushort* src0 = src[0]; - for( ; i <= len - vl; i += vl) + for (int i = 0; i < len; i += vl) { - auto a = __riscv_vle16_v_u16m1(src0 + i, vl); - __riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*cn, a, vl); + vl = __riscv_vsetvl_e16m8(len - i); + __riscv_vse16_v_u16m8(dst + i, __riscv_vle16_v_u16m8(src0 + i, vl), vl); } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; i < len; i++) - dst[i*cn] = src0[i]; } - else if( k == 2 ) + else if (cn == 2) { const ushort *src0 = src[0], *src1 = src[1]; - for( ; i <= len - vl; i += vl) + for (int i = 0; i < len; i += vl) { - auto a = __riscv_vle16_v_u16m1(src0 + i, vl); - auto b = __riscv_vle16_v_u16m1(src1 + i, vl); - __riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*cn, a, vl); - __riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*cn, b, vl); - } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; i < len; i++ ) - { - dst[i*cn] = src0[i]; - dst[i*cn+1] = src1[i]; + vl = __riscv_vsetvl_e16m4(len - i); + vuint16m4x2_t seg = __riscv_vcreate_v_u16m4x2( + __riscv_vle16_v_u16m4(src0 + i, vl), + __riscv_vle16_v_u16m4(src1 + i, vl) + ); + __riscv_vsseg2e16_v_u16m4x2(dst + i * cn, seg, vl); } } - else if( k == 3 ) + else if (cn == 3) { const ushort *src0 = src[0], *src1 = src[1], *src2 = src[2]; - for( ; i <= len - vl; i += vl) + for (int i = 0; i < len; i += vl) { - auto a = __riscv_vle16_v_u16m1(src0 + i, vl); - auto b = __riscv_vle16_v_u16m1(src1 + i, vl); - auto c = __riscv_vle16_v_u16m1(src2 + i, vl); - __riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*cn, a, vl); - __riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*cn, b, vl); - __riscv_vsse16_v_u16m1(dst + i*cn + 2, sizeof(ushort)*cn, c, vl); + vl = __riscv_vsetvl_e16m2(len - i); + vuint16m2x3_t seg = __riscv_vcreate_v_u16m2x3( + __riscv_vle16_v_u16m2(src0 + i, vl), + __riscv_vle16_v_u16m2(src1 + i, vl), + __riscv_vle16_v_u16m2(src2 + i, vl) + ); + __riscv_vsseg3e16_v_u16m2x3(dst + i * cn, seg, vl); } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; i < len; i++ ) + } + else if (cn == 4) + { + const ushort *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3]; + for (int i = 0; i < len; i += vl) { - dst[i*cn] = src0[i]; - dst[i*cn+1] = src1[i]; - dst[i*cn+2] = src2[i]; + vl = __riscv_vsetvl_e16m2(len - i); + vuint16m2x4_t seg = __riscv_vcreate_v_u16m2x4( + __riscv_vle16_v_u16m2(src0 + i, vl), + __riscv_vle16_v_u16m2(src1 + i, vl), + __riscv_vle16_v_u16m2(src2 + i, vl), + __riscv_vle16_v_u16m2(src3 + i, vl) + ); + __riscv_vsseg4e16_v_u16m2x4(dst + i * cn, seg, vl); } } else { - const ushort *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3]; - for( ; i <= len - vl; i += vl) + int k = 0; + for (; k <= cn - 4; k += 4) { - auto a = __riscv_vle16_v_u16m1(src0 + i, vl); - auto b = __riscv_vle16_v_u16m1(src1 + i, vl); - auto c = __riscv_vle16_v_u16m1(src2 + i, vl); - auto d = __riscv_vle16_v_u16m1(src3 + i, vl); - __riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*cn, a, vl); - __riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*cn, b, vl); - __riscv_vsse16_v_u16m1(dst + i*cn + 2, sizeof(ushort)*cn, c, vl); - __riscv_vsse16_v_u16m1(dst + i*cn + 3, sizeof(ushort)*cn, d, vl); + const ushort *src0 = src[k], *src1 = src[k + 1], *src2 = src[k + 2], *src3 = src[k + 3]; + for (int i = 0; i < len; i += vl) + { + vl = __riscv_vsetvl_e16m2(len - i); + vuint16m2x4_t seg = __riscv_vcreate_v_u16m2x4( + __riscv_vle16_v_u16m2(src0 + i, vl), + __riscv_vle16_v_u16m2(src1 + i, vl), + __riscv_vle16_v_u16m2(src2 + i, vl), + __riscv_vle16_v_u16m2(src3 + i, vl) + ); + __riscv_vssseg4e16_v_u16m2x4(dst + k + i * cn, cn * sizeof(ushort), seg, vl); + } } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; i < len; i++ ) + for (; k < cn; ++k) { - dst[i*cn] = src0[i]; - dst[i*cn+1] = src1[i]; - dst[i*cn+2] = src2[i]; - dst[i*cn+3] = src3[i]; - } - } - #if defined(__clang__) - #pragma clang loop vectorize(disable) - #endif - for( ; k < cn; k += 4 ) - { - const uint16_t *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3]; - i = 0; - for( ; i <= len - vl; i += vl) - { - auto a = __riscv_vle16_v_u16m1(src0 + i, vl); - auto b = __riscv_vle16_v_u16m1(src1 + i, vl); - auto c = __riscv_vle16_v_u16m1(src2 + i, vl); - auto d = __riscv_vle16_v_u16m1(src3 + i, vl); - __riscv_vsse16_v_u16m1(dst + k+i*cn, sizeof(ushort)*cn, a, vl); - __riscv_vsse16_v_u16m1(dst + k+i*cn + 1, sizeof(ushort)*cn, b, vl); - __riscv_vsse16_v_u16m1(dst + k+i*cn + 2, sizeof(ushort)*cn, c, vl); - __riscv_vsse16_v_u16m1(dst + k+i*cn + 3, sizeof(ushort)*cn, d, vl); - } - for( ; i < len; i++ ) - { - dst[k+i*cn] = src0[i]; - dst[k+i*cn+1] = src1[i]; - dst[k+i*cn+2] = src2[i]; - dst[k+i*cn+3] = src3[i]; + const ushort* srcK = src[k]; + for (int i = 0; i < len; i += vl) + { + vl = __riscv_vsetvl_e16m2(len - i); + vuint16m2_t seg = __riscv_vle16_v_u16m2(srcK + i, vl); + __riscv_vsse16_v_u16m2(dst + k + i * cn, cn * sizeof(ushort), seg, vl); + } } } return CV_HAL_ERROR_OK;