set(source "${WORK}/contraction.cpp") set(assembly "${WORK}/contraction.s") file(MAKE_DIRECTORY "${WORK}") file(WRITE "${source}" "float MultiplyAdd(float a, float b, float c) { return a * b + c; }\n") separate_arguments(options NATIVE_COMMAND "${OPTIONS}") list(FILTER options INCLUDE REGEX "^-f") set(target) foreach(architecture IN LISTS ARCHITECTURES) list(APPEND target -arch ${architecture}) endforeach() foreach(flags IN ITEMS "" ";${options}") execute_process(COMMAND "${COMPILER}" ${target} -std=gnu++20 -O2 -mfma ${flags} -S "${source}" -o "${assembly}" RESULT_VARIABLE result ERROR_VARIABLE error) if(NOT result EQUAL 0) message(FATAL_ERROR "compiling the contraction probe failed: ${error}") endif() file(READ "${assembly}" text) string(REGEX MATCH "vfn?m(add|sub)[0-9]+ss" fused "${text}") if(flags STREQUAL "") if(NOT fused) message(STATUS "the compiler does not contract a * b + c even without libc's options; nothing to compare") endif() elseif(fused) message(FATAL_ERROR "libc's compile options still let the compiler fuse a * b + c into ${fused}") endif() endforeach() message(STATUS "libc's compile options keep a * b + c unfused")