From 06b0de9c77551cd4e856d453e094d8a0b6ef0d6d Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Sat, 17 Feb 2024 16:34:11 +0100 Subject: [PATCH] CI: work-around zig cc mips bad codegen for hard-float --- .github/workflows/ci.yml | 5 +++-- CMakeLists.txt | 12 +++++++++--- misc/cmake/functions.cmake | 1 + src/check/dt_check.cpp | 23 +++++++++++++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a04f06a0..bb82523d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -466,8 +466,9 @@ jobs: - { zig_target: i386-linux-musl, qemu: qemu-i386 } # { zig_target: i386-linux-musl, qemu: qemu-i386, zig_pic: -fPIE } - { zig_target: i386-windows-gnu } - - { zig_target: mips-linux-musl } # TODO: qemu - - { zig_target: mipsel-linux-musl } # TODO: qemu + # mips and mipsel: bad hard-float code generation; see https://github.com/upx/upx/issues/788 + - { zig_target: mips-linux-musl, zig_flags: -msoft-float, qemu: qemu-mips } + - { zig_target: mipsel-linux-musl, zig_flags: -msoft-float, qemu: qemu-mipsel } - { zig_target: powerpc-linux-musl, qemu: qemu-ppc } - { zig_target: powerpc64-linux-musl, qemu: qemu-ppc64 } - { zig_target: powerpc64le-linux-musl, qemu: qemu-ppc64le } diff --git a/CMakeLists.txt b/CMakeLists.txt index 47ec7598..d7165faa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -254,9 +254,15 @@ endif() if(Threads_FOUND) foreach(f std_lock_guard.cpp) set(CMAKE_TRY_COMPILE_TARGET_TYPE "EXECUTABLE") - try_compile(result "${CMAKE_CURRENT_BINARY_DIR}" - "${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}" - CXX_STANDARD 17 OUTPUT_VARIABLE output) + if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD) + try_compile(result "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}" + OUTPUT_VARIABLE output CXX_STANDARD 17) + else() + try_compile(result "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}" + OUTPUT_VARIABLE output) + endif() if(NOT result) # failed; under MinGW be sure to use the posix-threads and NOT the win32-threads version #message(STATUS "Threads FAILED: ${output}") # debug output from try_compile diff --git a/misc/cmake/functions.cmake b/misc/cmake/functions.cmake index 4f39407c..9c89e15f 100644 --- a/misc/cmake/functions.cmake +++ b/misc/cmake/functions.cmake @@ -197,6 +197,7 @@ function(upx_add_definitions) # ARGV; needs include(CheckCCompilerFlag) endif() endfunction() +# useful for CI jobs: allow target extra compile options function(upx_add_target_extra_compile_options) # ARGV set(t "${ARGV0}") list(REMOVE_AT ARGV 0) diff --git a/src/check/dt_check.cpp b/src/check/dt_check.cpp index 4f57eba5..1368466c 100644 --- a/src/check/dt_check.cpp +++ b/src/check/dt_check.cpp @@ -323,6 +323,10 @@ struct TestIntegerWrap { static inline bool neg_eq(const T x) noexcept { return T(0) - x == x; } }; +// +// basic exception handling +// + static noinline void throwSomeValue(int x) may_throw { if (x < 0) throw int(x); @@ -342,6 +346,23 @@ static noinline void check_basic_cxx_exception_handling(void (*func)(int)) noexc assert_noexcept(cxx_exception_handling_works); } +// +// basic floating point to early catch bad codegen +// (this has happened in the past with some exotic LLVM targets) +// + +static noinline double sadd_a_b_div(upx_int64_t a, upx_int64_t b) { return (a + b) / 1000000.0; } +static noinline double uadd_a_b_div(upx_uint64_t a, upx_uint64_t b) { return (a + b) / 1000000.0; } +static noinline double ssub_a_b_div(upx_int64_t a, upx_int64_t b) { return (a - b) / 1000000.0; } +static noinline double usub_a_b_div(upx_uint64_t a, upx_uint64_t b) { return (a - b) / 1000000.0; } + +static noinline void check_basic_floating_point(void) noexcept { + assert_noexcept(sadd_a_b_div(1000000, 1000000) == 2.0); + assert_noexcept(uadd_a_b_div(1000000, 1000000) == 2.0); + assert_noexcept(ssub_a_b_div(3000000, 1000000) == 2.0); + assert_noexcept(usub_a_b_div(3000000, 1000000) == 2.0); +} + } // namespace #define ACC_WANT_ACC_CHK_CH 1 @@ -360,6 +381,8 @@ void upx_compiler_sanity_check(void) noexcept { check_basic_cxx_exception_handling(throwSomeValue); } + check_basic_floating_point(); + #define ACC_WANT_ACC_CHK_CH 1 #undef ACCCHK_ASSERT #define ACCCHK_ASSERT(expr) ACC_COMPILE_TIME_ASSERT(expr)