donotoptimize_assembly_test.cc (4308B)
1 #include <benchmark/benchmark.h> 2 3 #ifdef __clang__ 4 #pragma clang diagnostic ignored "-Wreturn-type" 5 #endif 6 7 extern "C" { 8 9 extern int ExternInt; 10 extern int ExternInt2; 11 extern int ExternInt3; 12 13 inline int Add42(int x) { return x + 42; } 14 15 struct NotTriviallyCopyable { 16 NotTriviallyCopyable(); 17 explicit NotTriviallyCopyable(int x) : value(x) {} 18 NotTriviallyCopyable(NotTriviallyCopyable const&); 19 int value; 20 }; 21 22 struct Large { 23 int value; 24 int data[2]; 25 }; 26 27 } 28 // CHECK-LABEL: test_with_rvalue: 29 extern "C" void test_with_rvalue() { 30 benchmark::DoNotOptimize(Add42(0)); 31 // CHECK: movl $42, %eax 32 // CHECK: ret 33 } 34 35 // CHECK-LABEL: test_with_large_rvalue: 36 extern "C" void test_with_large_rvalue() { 37 benchmark::DoNotOptimize(Large{ExternInt, {ExternInt, ExternInt}}); 38 // CHECK: ExternInt(%rip) 39 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]] 40 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) 41 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) 42 // CHECK: ret 43 } 44 45 // CHECK-LABEL: test_with_non_trivial_rvalue: 46 extern "C" void test_with_non_trivial_rvalue() { 47 benchmark::DoNotOptimize(NotTriviallyCopyable(ExternInt)); 48 // CHECK: mov{{l|q}} ExternInt(%rip) 49 // CHECK: ret 50 } 51 52 // CHECK-LABEL: test_with_lvalue: 53 extern "C" void test_with_lvalue() { 54 int x = 101; 55 benchmark::DoNotOptimize(x); 56 // CHECK-GNU: movl $101, %eax 57 // CHECK-CLANG: movl $101, -{{[0-9]+}}(%[[REG:[a-z]+]]) 58 // CHECK: ret 59 } 60 61 // CHECK-LABEL: test_with_large_lvalue: 62 extern "C" void test_with_large_lvalue() { 63 Large L{ExternInt, {ExternInt, ExternInt}}; 64 benchmark::DoNotOptimize(L); 65 // CHECK: ExternInt(%rip) 66 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]) 67 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) 68 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) 69 // CHECK: ret 70 } 71 72 // CHECK-LABEL: test_with_non_trivial_lvalue: 73 extern "C" void test_with_non_trivial_lvalue() { 74 NotTriviallyCopyable NTC(ExternInt); 75 benchmark::DoNotOptimize(NTC); 76 // CHECK: ExternInt(%rip) 77 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]) 78 // CHECK: ret 79 } 80 81 // CHECK-LABEL: test_with_const_lvalue: 82 extern "C" void test_with_const_lvalue() { 83 const int x = 123; 84 benchmark::DoNotOptimize(x); 85 // CHECK: movl $123, %eax 86 // CHECK: ret 87 } 88 89 // CHECK-LABEL: test_with_large_const_lvalue: 90 extern "C" void test_with_large_const_lvalue() { 91 const Large L{ExternInt, {ExternInt, ExternInt}}; 92 benchmark::DoNotOptimize(L); 93 // CHECK: ExternInt(%rip) 94 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]) 95 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) 96 // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]]) 97 // CHECK: ret 98 } 99 100 // CHECK-LABEL: test_with_non_trivial_const_lvalue: 101 extern "C" void test_with_non_trivial_const_lvalue() { 102 const NotTriviallyCopyable Obj(ExternInt); 103 benchmark::DoNotOptimize(Obj); 104 // CHECK: mov{{q|l}} ExternInt(%rip) 105 // CHECK: ret 106 } 107 108 // CHECK-LABEL: test_div_by_two: 109 extern "C" int test_div_by_two(int input) { 110 int divisor = 2; 111 benchmark::DoNotOptimize(divisor); 112 return input / divisor; 113 // CHECK: movl $2, [[DEST:.*]] 114 // CHECK: idivl [[DEST]] 115 // CHECK: ret 116 } 117 118 // CHECK-LABEL: test_inc_integer: 119 extern "C" int test_inc_integer() { 120 int x = 0; 121 for (int i=0; i < 5; ++i) 122 benchmark::DoNotOptimize(++x); 123 // CHECK: movl $1, [[DEST:.*]] 124 // CHECK: {{(addl \$1,|incl)}} [[DEST]] 125 // CHECK: {{(addl \$1,|incl)}} [[DEST]] 126 // CHECK: {{(addl \$1,|incl)}} [[DEST]] 127 // CHECK: {{(addl \$1,|incl)}} [[DEST]] 128 // CHECK-CLANG: movl [[DEST]], %eax 129 // CHECK: ret 130 return x; 131 } 132 133 // CHECK-LABEL: test_pointer_rvalue 134 extern "C" void test_pointer_rvalue() { 135 // CHECK: movl $42, [[DEST:.*]] 136 // CHECK: leaq [[DEST]], %rax 137 // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]]) 138 // CHECK: ret 139 int x = 42; 140 benchmark::DoNotOptimize(&x); 141 } 142 143 // CHECK-LABEL: test_pointer_const_lvalue: 144 extern "C" void test_pointer_const_lvalue() { 145 // CHECK: movl $42, [[DEST:.*]] 146 // CHECK: leaq [[DEST]], %rax 147 // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]]) 148 // CHECK: ret 149 int x = 42; 150 int * const xp = &x; 151 benchmark::DoNotOptimize(xp); 152 } 153 154 // CHECK-LABEL: test_pointer_lvalue: 155 extern "C" void test_pointer_lvalue() { 156 // CHECK: movl $42, [[DEST:.*]] 157 // CHECK: leaq [[DEST]], %rax 158 // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z+]+]]) 159 // CHECK: ret 160 int x = 42; 161 int *xp = &x; 162 benchmark::DoNotOptimize(xp); 163 }