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

source code of third-party/benchmark/test/donotoptimize_assembly_test.cc