xref: /aosp_15_r20/external/google-benchmark/test/donotoptimize_assembly_test.cc (revision dbb99499c3810fa1611fa2242a2fc446be01a57c)
1 #include <benchmark/benchmark.h>
2 
3 #ifdef __clang__
4 #pragma clang diagnostic ignored "-Wreturn-type"
5 #endif
6 BENCHMARK_DISABLE_DEPRECATED_WARNING
7 
8 extern "C" {
9 
10 extern int ExternInt;
11 extern int ExternInt2;
12 extern int ExternInt3;
13 extern int BigArray[2049];
14 
15 const int ConstBigArray[2049]{};
16 
17 inline int Add42(int x) { return x + 42; }
18 
19 struct NotTriviallyCopyable {
20   NotTriviallyCopyable();
21   explicit NotTriviallyCopyable(int x) : value(x) {}
22   NotTriviallyCopyable(NotTriviallyCopyable const &);
23   int value;
24 };
25 
26 struct Large {
27   int value;
28   int data[2];
29 };
30 
31 struct ExtraLarge {
32   int arr[2049];
33 };
34 }
35 
36 extern ExtraLarge ExtraLargeObj;
37 const ExtraLarge ConstExtraLargeObj{};
38 
39 // CHECK-LABEL: test_with_rvalue:
test_with_rvalue()40 extern "C" void test_with_rvalue() {
41   benchmark::DoNotOptimize(Add42(0));
42   // CHECK: movl $42, %eax
43   // CHECK: ret
44 }
45 
46 // CHECK-LABEL: test_with_large_rvalue:
test_with_large_rvalue()47 extern "C" void test_with_large_rvalue() {
48   benchmark::DoNotOptimize(Large{ExternInt, {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:
test_with_non_trivial_rvalue()57 extern "C" void test_with_non_trivial_rvalue() {
58   benchmark::DoNotOptimize(NotTriviallyCopyable(ExternInt));
59   // CHECK: mov{{l|q}} ExternInt(%rip)
60   // CHECK: ret
61 }
62 
63 // CHECK-LABEL: test_with_lvalue:
test_with_lvalue()64 extern "C" void test_with_lvalue() {
65   int x = 101;
66   benchmark::DoNotOptimize(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:
test_with_large_lvalue()73 extern "C" void test_with_large_lvalue() {
74   Large L{ExternInt, {ExternInt, ExternInt}};
75   benchmark::DoNotOptimize(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:
test_with_extra_large_lvalue_with_op()84 extern "C" void test_with_extra_large_lvalue_with_op() {
85   ExtraLargeObj.arr[16] = 42;
86   benchmark::DoNotOptimize(ExtraLargeObj);
87   // CHECK: movl $42, ExtraLargeObj+64(%rip)
88   // CHECK: ret
89 }
90 
91 // CHECK-LABEL: test_with_big_array_with_op
test_with_big_array_with_op()92 extern "C" void test_with_big_array_with_op() {
93   BigArray[16] = 42;
94   benchmark::DoNotOptimize(BigArray);
95   // CHECK: movl $42, BigArray+64(%rip)
96   // CHECK: ret
97 }
98 
99 // CHECK-LABEL: test_with_non_trivial_lvalue:
test_with_non_trivial_lvalue()100 extern "C" void test_with_non_trivial_lvalue() {
101   NotTriviallyCopyable NTC(ExternInt);
102   benchmark::DoNotOptimize(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:
test_with_const_lvalue()109 extern "C" void test_with_const_lvalue() {
110   const int x = 123;
111   benchmark::DoNotOptimize(x);
112   // CHECK: movl $123, %eax
113   // CHECK: ret
114 }
115 
116 // CHECK-LABEL: test_with_large_const_lvalue:
test_with_large_const_lvalue()117 extern "C" void test_with_large_const_lvalue() {
118   const Large L{ExternInt, {ExternInt, ExternInt}};
119   benchmark::DoNotOptimize(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:
test_with_const_extra_large_obj()128 extern "C" void test_with_const_extra_large_obj() {
129   benchmark::DoNotOptimize(ConstExtraLargeObj);
130   // CHECK: ret
131 }
132 
133 // CHECK-LABEL: test_with_const_big_array
test_with_const_big_array()134 extern "C" void test_with_const_big_array() {
135   benchmark::DoNotOptimize(ConstBigArray);
136   // CHECK: ret
137 }
138 
139 // CHECK-LABEL: test_with_non_trivial_const_lvalue:
test_with_non_trivial_const_lvalue()140 extern "C" void test_with_non_trivial_const_lvalue() {
141   const NotTriviallyCopyable Obj(ExternInt);
142   benchmark::DoNotOptimize(Obj);
143   // CHECK: mov{{q|l}} ExternInt(%rip)
144   // CHECK: ret
145 }
146 
147 // CHECK-LABEL: test_div_by_two:
test_div_by_two(int input)148 extern "C" int test_div_by_two(int input) {
149   int divisor = 2;
150   benchmark::DoNotOptimize(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:
test_inc_integer()158 extern "C" int test_inc_integer() {
159   int x = 0;
160   for (int i = 0; i < 5; ++i) benchmark::DoNotOptimize(++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
test_pointer_rvalue()172 extern "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(&x);
179 }
180 
181 // CHECK-LABEL: test_pointer_const_lvalue:
test_pointer_const_lvalue()182 extern "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(xp);
190 }
191 
192 // CHECK-LABEL: test_pointer_lvalue:
test_pointer_lvalue()193 extern "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(xp);
201 }
202