From 805145847bc310cb4b54363b610d2f3a86fdd5e8 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Mon, 30 Mar 2015 22:14:08 -0400 Subject: [PATCH] add workaround to DoNotOptimize(...) for clang inline assembly bug. --- include/benchmark/benchmark_api.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/benchmark/benchmark_api.h b/include/benchmark/benchmark_api.h index a99ae9bc..8e6a63ad 100644 --- a/include/benchmark/benchmark_api.h +++ b/include/benchmark/benchmark_api.h @@ -190,10 +190,19 @@ void UseCharPointer(char const volatile*); // expression from being optimized away by the compiler. This function is // intented to add little to no overhead. // See: http://stackoverflow.com/questions/28287064 -#if defined(__GNUC__) +#if defined(__clang__) && defined(__GNUC__) +// TODO(ericwf): Clang has a bug where it tries to always use a register +// even if value must be stored in memory. This causes codegen to fail. +// To work around this we remove the "r" modifier so the operand is always +// loaded into memory. template inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { - asm volatile("" : "+r" (const_cast(value))); + asm volatile("" : "+m" (const_cast(value))); +} +#elif defined(__GNUC__) +template +inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { + asm volatile("" : "+rm" (const_cast(value))); } #else template