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