Add tests to verify assembler output -- Fix DoNotOptimize. (#530)
* Add tests to verify assembler output -- Fix DoNotOptimize.
For things like `DoNotOptimize`, `ClobberMemory`, and even `KeepRunning()`,
it is important exactly what assembly they generate. However, we currently
have no way to test this. Instead it must be manually validated every
time a change occurs -- including a change in compiler version.
This patch attempts to introduce a way to test the assembled output automatically.
It's mirrors how LLVM verifies compiler output, and it uses LLVM FileCheck to run
the tests in a similar way.
The tests function by generating the assembly for a test in CMake, and then
using FileCheck to verify the // CHECK lines in the source file are found
in the generated assembly.
Currently, the tests only run on 64-bit x86 systems under GCC and Clang,
and when FileCheck is found on the system.
Additionally, this patch tries to improve the code gen from DoNotOptimize.
This should probably be a separate change, but I needed something to test.
* Disable assembly tests on Bazel for now
* Link FIXME to github issue
* Fix Tests on OS X
* fix strip_asm.py to work on both Linux and OS X like targets
2018-03-23 22:10:47 +00:00
|
|
|
#include <benchmark/benchmark.h>
|
|
|
|
|
|
|
|
#ifdef __clang__
|
|
|
|
#pragma clang diagnostic ignored "-Wreturn-type"
|
|
|
|
#endif
|
2023-03-13 12:34:12 +00:00
|
|
|
BENCHMARK_DISABLE_DEPRECATED_WARNING
|
Add tests to verify assembler output -- Fix DoNotOptimize. (#530)
* Add tests to verify assembler output -- Fix DoNotOptimize.
For things like `DoNotOptimize`, `ClobberMemory`, and even `KeepRunning()`,
it is important exactly what assembly they generate. However, we currently
have no way to test this. Instead it must be manually validated every
time a change occurs -- including a change in compiler version.
This patch attempts to introduce a way to test the assembled output automatically.
It's mirrors how LLVM verifies compiler output, and it uses LLVM FileCheck to run
the tests in a similar way.
The tests function by generating the assembly for a test in CMake, and then
using FileCheck to verify the // CHECK lines in the source file are found
in the generated assembly.
Currently, the tests only run on 64-bit x86 systems under GCC and Clang,
and when FileCheck is found on the system.
Additionally, this patch tries to improve the code gen from DoNotOptimize.
This should probably be a separate change, but I needed something to test.
* Disable assembly tests on Bazel for now
* Link FIXME to github issue
* Fix Tests on OS X
* fix strip_asm.py to work on both Linux and OS X like targets
2018-03-23 22:10:47 +00:00
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
extern int ExternInt;
|
|
|
|
extern int ExternInt2;
|
|
|
|
extern int ExternInt3;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: test_basic:
|
|
|
|
extern "C" void test_basic() {
|
|
|
|
int x;
|
|
|
|
benchmark::DoNotOptimize(&x);
|
|
|
|
x = 101;
|
|
|
|
benchmark::ClobberMemory();
|
|
|
|
// CHECK: leaq [[DEST:[^,]+]], %rax
|
|
|
|
// CHECK: movl $101, [[DEST]]
|
|
|
|
// CHECK: ret
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: test_redundant_store:
|
|
|
|
extern "C" void test_redundant_store() {
|
|
|
|
ExternInt = 3;
|
|
|
|
benchmark::ClobberMemory();
|
|
|
|
ExternInt = 51;
|
|
|
|
// CHECK-DAG: ExternInt
|
|
|
|
// CHECK-DAG: movl $3
|
|
|
|
// CHECK: movl $51
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: test_redundant_read:
|
|
|
|
extern "C" void test_redundant_read() {
|
|
|
|
int x;
|
|
|
|
benchmark::DoNotOptimize(&x);
|
|
|
|
x = ExternInt;
|
|
|
|
benchmark::ClobberMemory();
|
|
|
|
x = ExternInt2;
|
|
|
|
// CHECK: leaq [[DEST:[^,]+]], %rax
|
|
|
|
// CHECK: ExternInt(%rip)
|
|
|
|
// CHECK: movl %eax, [[DEST]]
|
|
|
|
// CHECK-NOT: ExternInt2
|
|
|
|
// CHECK: ret
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: test_redundant_read2:
|
|
|
|
extern "C" void test_redundant_read2() {
|
|
|
|
int x;
|
|
|
|
benchmark::DoNotOptimize(&x);
|
|
|
|
x = ExternInt;
|
|
|
|
benchmark::ClobberMemory();
|
|
|
|
x = ExternInt2;
|
|
|
|
benchmark::ClobberMemory();
|
|
|
|
// CHECK: leaq [[DEST:[^,]+]], %rax
|
|
|
|
// CHECK: ExternInt(%rip)
|
|
|
|
// CHECK: movl %eax, [[DEST]]
|
|
|
|
// CHECK: ExternInt2(%rip)
|
|
|
|
// CHECK: movl %eax, [[DEST]]
|
|
|
|
// CHECK: ret
|
|
|
|
}
|