Build: Unset FLOATTEST* by default for non-x86

Because libjpeg-turbo 3.0.x now supports multiple data precisions in the
same build, the regression test system can test the 8-bit and 12-bit
floating point DCT/IDCT algorithms separately.  The expected MD5 sums
for those tests are communicated to the test system using the FLOATTEST8
and FLOATTEST12 CMake variables.  Whereas it is possible to
intelligently set a default value for FLOATTEST8 when building for
x86[-64] and a default value for FLOATTEST12 when building for x86-64,
it is not possible with other architectures.  (Refer to #705, #709,
and #710.)  Clang 14, for example, now enables FMA (fused multiply-add)
instructions by default on architectures that support them, but with
AArch64 builds, the results are not the same as when using GCC/AArch64
with FMA instructions enabled.  Thus, setting FLOATTEST12=fp-contract
doesn't make the tests pass.  It was already impossible to intelligently
set a default for FLOATTEST8 with i386 builds, but referring to #710,
that appears to be the case with other non-x86-64 builds as well.

Back in 1991, when Tom Lane first released libjpeg, some CPUs had
floating point units and some didn't.  It could take minutes to compress
or decompress a 1-megapixel JPEG image using the "slow" integer DCT/IDCT
algorithms, and the floating point algorithms were significantly faster
on systems that had an FPU.  On systems without FPUs, floating point
math was emulated and really slow, so Tom also developed "fast" integer
DCT/IDCT algorithms to speed up JPEG performance, at the expense of
accuracy, on those systems.  Because of libjpeg-turbo's SIMD extensions,
the floating point algorithms are now significantly slower than the
"slow" integer algorithms without being significantly more accurate, and
the "fast" integer algorithms fail the ISO/ITU-T conformance tests
without being any faster than the "slow" integer algorithms on x86
systems.  Thus, the floating point and "fast" integer algorithms are
considered legacy features.

In order for the floating point regression tests to be useful, the
results of the tests must be validated against an independent metric.
(In other words, it wouldn't be useful to use the floating point
DCT/IDCT algorithms to determine the expected results of the floating
point DCT/IDCT algorithms.)  In the past, I attempted without success to
develop a low-level floating point test that would run at configure time
and determine the appropriate default value of FLOATTEST*.  Barring that
approach, the only other possibilities would be:

1. Develop a test framework that compares the floating point results
with a margin of error, as TJUnitTest does.  However, that effort isn't
justified unless it could also benefit non-legacy features.

2. Compare the floating point results against an expected MD5 sum, as we
currently do.  However, as previously described, it isn't possible in
most cases to determine an appropriate default value for the expected
MD5 sum.

For the moment, it makes the most sense to disable the 8-bit floating
point tests by default except with x86[-64] builds and to disable the
12-bit floating point tests by default except with x86-64 builds.  That
means that the floating point algorithms will still be regression tested
when performing x86[-64] builds, but other types of builds will have to
opt in to the same regression tests.  Since the floating point DCT/IDCT
algorithms are unlikely to change ever again (the only reason they still
exist at all is to maintain backward compatibility with libjpeg), this
seems like a reasonable tradeoff.
This commit is contained in:
DRC
2023-07-25 10:01:42 -04:00
parent d6914b6b1e
commit 63bd71885f

View File

@@ -893,18 +893,11 @@ if(CPU_TYPE STREQUAL "x86_64" OR CPU_TYPE STREQUAL "i386")
set(DEFAULT_FLOATTEST8 sse)
elseif(CPU_TYPE STREQUAL "x86_64")
set(DEFAULT_FLOATTEST8 no-fp-contract)
# else we can't really set an intelligent default for i386. The appropriate
# value could be no-fp-contract, fp-contract, 387, or msvc, depending on the
# compiler and compiler options. We leave it to the user to set FLOATTEST8
# manually.
endif()
else()
if((CPU_TYPE STREQUAL "powerpc" OR CPU_TYPE STREQUAL "arm64") AND
NOT CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT MSVC)
set(DEFAULT_FLOATTEST8 fp-contract)
else()
set(DEFAULT_FLOATTEST8 no-fp-contract)
endif()
# else we can't really set an intelligent default for FLOATTEST8. The
# appropriate value could be no-fp-contract, fp-contract, 387, or msvc,
# depending on the compiler and compiler options. We leave it to the user to
# set FLOATTEST8 manually.
endif()
# This causes FLOATTEST8 to reset to the default value if WITH_SIMD has
@@ -932,13 +925,10 @@ endif()
if(CPU_TYPE STREQUAL "x86_64")
set(DEFAULT_FLOATTEST12 no-fp-contract)
elseif(NOT CPU_TYPE STREQUAL "i386")
if((CPU_TYPE STREQUAL "powerpc" OR CPU_TYPE STREQUAL "arm64") AND
NOT CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT MSVC)
set(DEFAULT_FLOATTEST12 fp-contract)
else()
set(DEFAULT_FLOATTEST12 no-fp-contract)
endif()
# else we can't really set an intelligent default for FLOATTEST12. The
# appropriate value could be no-fp-contract, fp-contract, or something else,
# depending on the compiler and compiler options. We leave it to the user to
# set FLOATTEST12 manually.
endif()
set(FLOATTEST12 ${DEFAULT_FLOATTEST12} CACHE STRING