riscv: Improve the RVV availability check

In some cases, the vector extension is not supported, although the
compiler allows the "v" flag in `-march` and includes `<riscv_vector>`
without raising an error.

Signed-off-by: Cosmin Truta <ctruta@gmail.com>
This commit is contained in:
Filip Wasil 2025-06-17 08:36:53 +02:00 committed by Cosmin Truta
parent 5dc5937b30
commit edf46621f3
2 changed files with 33 additions and 6 deletions

View File

@ -331,9 +331,28 @@ if(PNG_HARDWARE_OPTIMIZATIONS)
if(index EQUAL -1)
message(FATAL_ERROR "PNG_RISCV_RVV must be one of [${PNG_RISCV_RVV_POSSIBLE_VALUES}]")
elseif(NOT PNG_RISCV_RVV STREQUAL "off")
check_c_compiler_flag("-march=rv64gv1p0" COMPILER_SUPPORTS_RVV)
set(_SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-march=rv64gv1p0")
check_c_source_compiles("
#include <riscv_vector.h>
#include <asm/hwcap.h>
#ifndef COMPAT_HWCAP_ISA_V /* added in linux-6.5 */
#error \"COMPAT_HWCAP_ISA_V is not available\"
#endif
int main() {
const float src[] = { 0.0f, 0.0f, 0.0f, 0.0f };
uint64_t ptr[2] = {0x0908060504020100, 0xFFFFFFFF0E0D0C0A};
vuint8m1_t a = __riscv_vreinterpret_v_u64m1_u8m1(__riscv_vle64_v_u64m1(ptr, 2));
vfloat32m1_t val = __riscv_vle32_v_f32m1((const float*)(src), 4);
return (int)__riscv_vfmv_f_s_f32m1_f32(val);
}" COMPILER_SUPPORTS_RVV)
set(CMAKE_REQUIRED_FLAGS ${_SAVED_CMAKE_REQUIRED_FLAGS})
if(NOT COMPILER_SUPPORTS_RVV)
message(FATAL_ERROR "Compiler does not support -march=rv64gv1p0 option")
message(FATAL_ERROR "Compiler does not support RISC-V Vector extension or its unable to detect it")
endif()
set(libpng_riscv_sources
riscv/filter_rvv_intrinsics.c

View File

@ -700,7 +700,7 @@ AS_HELP_STRING([[[--enable-riscv-rvv]]],
AC_DEFINE([PNG_RISCV_RVV_OPT], [2],
[Enable RISC-V Vector optimizations])
AC_MSG_WARN([--enable-riscv-rvv: please specify 'check' or 'api', if]
[you want the optimizations unconditionally pass e.g. '-march=rv64gv']
[you want the optimizations unconditionally pass e.g. '-march=rv64gv1p0']
[to the compiler.]);;
*)
AC_MSG_ERROR([--enable-riscv-rvv=${enable_riscv_rvv}: invalid value])
@ -716,11 +716,19 @@ then
AC_MSG_CHECKING(whether to use RISC-V RVV intrinsics)
save_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -march=rv64gv"
CFLAGS="$CFLAGS -march=rv64gv1p0"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <riscv_vector.h>
int main(){
return 0;
#include <asm/hwcap.h>
#ifndef COMPAT_HWCAP_ISA_V /* added in linux-6.5 */
#error "COMPAT_HWCAP_ISA_V is not available"
#endif
int main() {
const float src[] = { 0.0f, 0.0f, 0.0f, 0.0f };
uint64_t ptr[2] = {0x0908060504020100, 0xFFFFFFFF0E0D0C0A};
vuint8m1_t a = __riscv_vreinterpret_v_u64m1_u8m1(__riscv_vle64_v_u64m1(ptr, 2));
vfloat32m1_t val = __riscv_vle32_v_f32m1((const float*)(src), 4);
return (int)__riscv_vfmv_f_s_f32m1_f32(val);
}]])],compiler_support_riscv_rvv=yes)
AC_MSG_RESULT($compiler_support_riscv_rvv)
if test "$compiler_support_riscv_rvv" = "yes"; then