Index: tools/CMakeLists.txt =================================================================== --- tools/CMakeLists.txt +++ tools/CMakeLists.txt @@ -27,3 +27,5 @@ add_executable(timeit-target ${CMAKE_CURRENT_SOURCE_DIR}/timeit.c) llvm_add_host_executable(timeit-host timeit timeit.c) endif() + +add_executable(FP-contraction_detection___-target ${CMAKE_CURRENT_SOURCE_DIR}/FP-contraction_detection.c) Index: tools/FP-contraction_detection.c =================================================================== --- /dev/null +++ tools/FP-contraction_detection.c @@ -0,0 +1,66 @@ +#include +#include +#include + +// for ease of future change +#define FP_type double + +__attribute__((noinline)) +FP_type FMA_test_using_default_compiler_setting( FP_type a, FP_type b, FP_type c) { + return a+b*c; +} + +__attribute__((noinline)) +FP_type FMA_test_with_pragma_for_NO_contraction( FP_type a, FP_type b, FP_type c) { + #pragma STDC FP_CONTRACT OFF + return a+b*c; +} + +__attribute__((noinline)) +FP_type FMA_test_with_pragma_for_YES_contraction(FP_type a, FP_type b, FP_type c) { + #pragma STDC FP_CONTRACT ON + return a+b*c; +} + +#pragma clang optimize off +__attribute__((optnone)) // for Clang +__attribute__((optimize("-O0"))) // for GCC +__attribute__((noinline)) +FP_type FMA_test_trying_to_disable_optimization( FP_type a, FP_type b, FP_type c) { + return a+b*c; +} + + +// the following routine: with thanks to Matthias Braun +static double u64_to_double(uint64_t x) { + double d; + memcpy(&d, &x, sizeof(x)); + return d; +} + + +int main() { + + double A, B, C; + // the next 3 lines: thanks to the author of + A = u64_to_double(0x3c54c9b71a0e6500); + B = u64_to_double(0xbf43a04556d864ae); + C = u64_to_double(0xbfc55364b6b08299); + + FP_type result_1 = FMA_test_using_default_compiler_setting( A, B, C); + FP_type result_2 = FMA_test_with_pragma_for_NO_contraction( A, B, C); + FP_type result_3 = FMA_test_with_pragma_for_YES_contraction(A, B, C); + FP_type result_4 = FMA_test_trying_to_disable_optimization( A, B, C); + + printf("(%d " , result_1 == result_2); + printf( "%d " , result_1 == result_3); + printf( "%d) " , result_1 == result_4); + printf("(%d " , result_2 == result_3); + printf( "%d) " , result_2 == result_4); + printf("(%d)\n", result_3 == result_4); + + return ! ( (result_1 == result_2) && (result_1 == result_3) && (result_1 == result_4) && + (result_2 == result_3) && (result_2 == result_4) && + (result_3 == result_4) + ); +} Index: tools/Makefile =================================================================== --- tools/Makefile +++ tools/Makefile @@ -24,6 +24,9 @@ chmod u+x $@ endif +FP-contraction_detection___-target: FP-contraction_detection.c + $(LD_ENV_OVERRIDES) $(LCC) -o $@ $< $(LDFLAGS) $(CFLAGS) $(TARGET_FLAGS) -O3 + fpcmp: fpcmp.c $(ORIGINAL_CC) $(CFLAGS) -O3 -o $@ $<