#include <benchmark/benchmark.h> #ifdef __clang__ #pragma clang diagnostic ignored "-Wreturn-type" #endif extern "C" { extern int ExternInt; extern int ExternInt2; extern int ExternInt3; inline int Add42(int x) { return x + 42; } struct NotTriviallyCopyable { NotTriviallyCopyable(); explicit NotTriviallyCopyable(int x) : value(x) {} NotTriviallyCopyable(NotTriviallyCopyable const&); int value; }; struct Large { int value; int data[2]; }; } // CHECK-LABEL: test_with_rvalue: extern "C" void test_with_rvalue() { benchmark::DoNotOptimize(Add42(0)); // CHECK: movl $42, %eax // CHECK: ret } // CHECK-LABEL: test_with_large_rvalue: extern "C" void test_with_large_rvalue() { benchmark::DoNotOptimize(Large{ExternInt, {ExternInt, ExternInt}}); // CHECK: ExternInt(%rip) // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]] // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) // CHECK: ret } // CHECK-LABEL: test_with_non_trivial_rvalue: extern "C" void test_with_non_trivial_rvalue() { benchmark::DoNotOptimize(NotTriviallyCopyable(ExternInt)); // CHECK: mov{{l|q}} ExternInt(%rip) // CHECK: ret } // CHECK-LABEL: test_with_lvalue: extern "C" void test_with_lvalue() { int x = 101; benchmark::DoNotOptimize(x); // CHECK-GNU: movl $101, %eax // CHECK-CLANG: movl $101, -{{[0-9]+}}(%[[REG:[a-z]+]]) // CHECK: ret } // CHECK-LABEL: test_with_large_lvalue: extern "C" void test_with_large_lvalue() { Large L{ExternInt, {ExternInt, ExternInt}}; benchmark::DoNotOptimize(L); // CHECK: ExternInt(%rip) // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]) // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) // CHECK: ret } // CHECK-LABEL: test_with_non_trivial_lvalue: extern "C" void test_with_non_trivial_lvalue() { NotTriviallyCopyable NTC(ExternInt); benchmark::DoNotOptimize(NTC); // CHECK: ExternInt(%rip) // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]) // CHECK: ret } // CHECK-LABEL: test_with_const_lvalue: extern "C" void test_with_const_lvalue() { const int x = 123; benchmark::DoNotOptimize(x); // CHECK: movl $123, %eax // CHECK: ret } // CHECK-LABEL: test_with_large_const_lvalue: extern "C" void test_with_large_const_lvalue() { const Large L{ExternInt, {ExternInt, ExternInt}}; benchmark::DoNotOptimize(L); // CHECK: ExternInt(%rip) // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]) // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) // CHECK: ret } // CHECK-LABEL: test_with_non_trivial_const_lvalue: extern "C" void test_with_non_trivial_const_lvalue() { const NotTriviallyCopyable Obj(ExternInt); benchmark::DoNotOptimize(Obj); // CHECK: mov{{q|l}} ExternInt(%rip) // CHECK: ret } // CHECK-LABEL: test_div_by_two: extern "C" int test_div_by_two(int input) { int divisor = 2; benchmark::DoNotOptimize(divisor); return input / divisor; // CHECK: movl $2, [[DEST:.*]] // CHECK: idivl [[DEST]] // CHECK: ret } // CHECK-LABEL: test_inc_integer: extern "C" int test_inc_integer() { int x = 0; for (int i=0; i < 5; ++i) benchmark::DoNotOptimize(++x); // CHECK: movl $1, [[DEST:.*]] // CHECK: {{(addl \$1,|incl)}} [[DEST]] // CHECK: {{(addl \$1,|incl)}} [[DEST]] // CHECK: {{(addl \$1,|incl)}} [[DEST]] // CHECK: {{(addl \$1,|incl)}} [[DEST]] // CHECK-CLANG: movl [[DEST]], %eax // CHECK: ret return x; } // CHECK-LABEL: test_pointer_rvalue extern "C" void test_pointer_rvalue() { // CHECK: movl $42, [[DEST:.*]] // CHECK: leaq [[DEST]], %rax // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]]) // CHECK: ret int x = 42; benchmark::DoNotOptimize(&x); } // CHECK-LABEL: test_pointer_const_lvalue: extern "C" void test_pointer_const_lvalue() { // CHECK: movl $42, [[DEST:.*]] // CHECK: leaq [[DEST]], %rax // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]]) // CHECK: ret int x = 42; int * const xp = &x; benchmark::DoNotOptimize(xp); } // CHECK-LABEL: test_pointer_lvalue: extern "C" void test_pointer_lvalue() { // CHECK: movl $42, [[DEST:.*]] // CHECK: leaq [[DEST]], %rax // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z+]+]]) // CHECK: ret int x = 42; int *xp = &x; benchmark::DoNotOptimize(xp); }