xref: /llvm-project/third-party/benchmark/test/donotoptimize_assembly_test.cc (revision a5b797172cc902db166e9a695716fb81405f86e4)
15dda2efdSMircea Trofin #include <benchmark/benchmark.h>
25dda2efdSMircea Trofin 
35dda2efdSMircea Trofin #ifdef __clang__
45dda2efdSMircea Trofin #pragma clang diagnostic ignored "-Wreturn-type"
55dda2efdSMircea Trofin #endif
6*a5b79717SMircea Trofin BENCHMARK_DISABLE_DEPRECATED_WARNING
75dda2efdSMircea Trofin 
85dda2efdSMircea Trofin extern "C" {
95dda2efdSMircea Trofin 
105dda2efdSMircea Trofin extern int ExternInt;
115dda2efdSMircea Trofin extern int ExternInt2;
125dda2efdSMircea Trofin extern int ExternInt3;
13*a5b79717SMircea Trofin extern int BigArray[2049];
14*a5b79717SMircea Trofin 
15*a5b79717SMircea Trofin const int ConstBigArray[2049]{};
165dda2efdSMircea Trofin 
175dda2efdSMircea Trofin inline int Add42(int x) { return x + 42; }
185dda2efdSMircea Trofin 
195dda2efdSMircea Trofin struct NotTriviallyCopyable {
205dda2efdSMircea Trofin   NotTriviallyCopyable();
215dda2efdSMircea Trofin   explicit NotTriviallyCopyable(int x) : value(x) {}
225dda2efdSMircea Trofin   NotTriviallyCopyable(NotTriviallyCopyable const &);
235dda2efdSMircea Trofin   int value;
245dda2efdSMircea Trofin };
255dda2efdSMircea Trofin 
265dda2efdSMircea Trofin struct Large {
275dda2efdSMircea Trofin   int value;
285dda2efdSMircea Trofin   int data[2];
295dda2efdSMircea Trofin };
30*a5b79717SMircea Trofin 
31*a5b79717SMircea Trofin struct ExtraLarge {
32*a5b79717SMircea Trofin   int arr[2049];
33*a5b79717SMircea Trofin };
345dda2efdSMircea Trofin }
35*a5b79717SMircea Trofin 
36*a5b79717SMircea Trofin extern ExtraLarge ExtraLargeObj;
37*a5b79717SMircea Trofin const ExtraLarge ConstExtraLargeObj{};
38*a5b79717SMircea Trofin 
395dda2efdSMircea Trofin // CHECK-LABEL: test_with_rvalue:
test_with_rvalue()405dda2efdSMircea Trofin extern "C" void test_with_rvalue() {
415dda2efdSMircea Trofin   benchmark::DoNotOptimize(Add42(0));
425dda2efdSMircea Trofin   // CHECK: movl $42, %eax
435dda2efdSMircea Trofin   // CHECK: ret
445dda2efdSMircea Trofin }
455dda2efdSMircea Trofin 
465dda2efdSMircea Trofin // CHECK-LABEL: test_with_large_rvalue:
test_with_large_rvalue()475dda2efdSMircea Trofin extern "C" void test_with_large_rvalue() {
485dda2efdSMircea Trofin   benchmark::DoNotOptimize(Large{ExternInt, {ExternInt, ExternInt}});
495dda2efdSMircea Trofin   // CHECK: ExternInt(%rip)
505dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]]
515dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
525dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
535dda2efdSMircea Trofin   // CHECK: ret
545dda2efdSMircea Trofin }
555dda2efdSMircea Trofin 
565dda2efdSMircea Trofin // CHECK-LABEL: test_with_non_trivial_rvalue:
test_with_non_trivial_rvalue()575dda2efdSMircea Trofin extern "C" void test_with_non_trivial_rvalue() {
585dda2efdSMircea Trofin   benchmark::DoNotOptimize(NotTriviallyCopyable(ExternInt));
595dda2efdSMircea Trofin   // CHECK: mov{{l|q}} ExternInt(%rip)
605dda2efdSMircea Trofin   // CHECK: ret
615dda2efdSMircea Trofin }
625dda2efdSMircea Trofin 
635dda2efdSMircea Trofin // CHECK-LABEL: test_with_lvalue:
test_with_lvalue()645dda2efdSMircea Trofin extern "C" void test_with_lvalue() {
655dda2efdSMircea Trofin   int x = 101;
665dda2efdSMircea Trofin   benchmark::DoNotOptimize(x);
675dda2efdSMircea Trofin   // CHECK-GNU: movl $101, %eax
685dda2efdSMircea Trofin   // CHECK-CLANG: movl $101, -{{[0-9]+}}(%[[REG:[a-z]+]])
695dda2efdSMircea Trofin   // CHECK: ret
705dda2efdSMircea Trofin }
715dda2efdSMircea Trofin 
725dda2efdSMircea Trofin // CHECK-LABEL: test_with_large_lvalue:
test_with_large_lvalue()735dda2efdSMircea Trofin extern "C" void test_with_large_lvalue() {
745dda2efdSMircea Trofin   Large L{ExternInt, {ExternInt, ExternInt}};
755dda2efdSMircea Trofin   benchmark::DoNotOptimize(L);
765dda2efdSMircea Trofin   // CHECK: ExternInt(%rip)
775dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]])
785dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
795dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
805dda2efdSMircea Trofin   // CHECK: ret
815dda2efdSMircea Trofin }
825dda2efdSMircea Trofin 
83*a5b79717SMircea Trofin // CHECK-LABEL: test_with_extra_large_lvalue_with_op:
test_with_extra_large_lvalue_with_op()84*a5b79717SMircea Trofin extern "C" void test_with_extra_large_lvalue_with_op() {
85*a5b79717SMircea Trofin   ExtraLargeObj.arr[16] = 42;
86*a5b79717SMircea Trofin   benchmark::DoNotOptimize(ExtraLargeObj);
87*a5b79717SMircea Trofin   // CHECK: movl $42, ExtraLargeObj+64(%rip)
88*a5b79717SMircea Trofin   // CHECK: ret
89*a5b79717SMircea Trofin }
90*a5b79717SMircea Trofin 
91*a5b79717SMircea Trofin // CHECK-LABEL: test_with_big_array_with_op
test_with_big_array_with_op()92*a5b79717SMircea Trofin extern "C" void test_with_big_array_with_op() {
93*a5b79717SMircea Trofin   BigArray[16] = 42;
94*a5b79717SMircea Trofin   benchmark::DoNotOptimize(BigArray);
95*a5b79717SMircea Trofin   // CHECK: movl $42, BigArray+64(%rip)
96*a5b79717SMircea Trofin   // CHECK: ret
97*a5b79717SMircea Trofin }
98*a5b79717SMircea Trofin 
995dda2efdSMircea Trofin // CHECK-LABEL: test_with_non_trivial_lvalue:
test_with_non_trivial_lvalue()1005dda2efdSMircea Trofin extern "C" void test_with_non_trivial_lvalue() {
1015dda2efdSMircea Trofin   NotTriviallyCopyable NTC(ExternInt);
1025dda2efdSMircea Trofin   benchmark::DoNotOptimize(NTC);
1035dda2efdSMircea Trofin   // CHECK: ExternInt(%rip)
1045dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]])
1055dda2efdSMircea Trofin   // CHECK: ret
1065dda2efdSMircea Trofin }
1075dda2efdSMircea Trofin 
1085dda2efdSMircea Trofin // CHECK-LABEL: test_with_const_lvalue:
test_with_const_lvalue()1095dda2efdSMircea Trofin extern "C" void test_with_const_lvalue() {
1105dda2efdSMircea Trofin   const int x = 123;
1115dda2efdSMircea Trofin   benchmark::DoNotOptimize(x);
1125dda2efdSMircea Trofin   // CHECK: movl $123, %eax
1135dda2efdSMircea Trofin   // CHECK: ret
1145dda2efdSMircea Trofin }
1155dda2efdSMircea Trofin 
1165dda2efdSMircea Trofin // CHECK-LABEL: test_with_large_const_lvalue:
test_with_large_const_lvalue()1175dda2efdSMircea Trofin extern "C" void test_with_large_const_lvalue() {
1185dda2efdSMircea Trofin   const Large L{ExternInt, {ExternInt, ExternInt}};
1195dda2efdSMircea Trofin   benchmark::DoNotOptimize(L);
1205dda2efdSMircea Trofin   // CHECK: ExternInt(%rip)
1215dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG:[a-z]+]])
1225dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
1235dda2efdSMircea Trofin   // CHECK: movl %eax, -{{[0-9]+}}(%[[REG]])
1245dda2efdSMircea Trofin   // CHECK: ret
1255dda2efdSMircea Trofin }
1265dda2efdSMircea Trofin 
127*a5b79717SMircea Trofin // CHECK-LABEL: test_with_const_extra_large_obj:
test_with_const_extra_large_obj()128*a5b79717SMircea Trofin extern "C" void test_with_const_extra_large_obj() {
129*a5b79717SMircea Trofin   benchmark::DoNotOptimize(ConstExtraLargeObj);
130*a5b79717SMircea Trofin   // CHECK: ret
131*a5b79717SMircea Trofin }
132*a5b79717SMircea Trofin 
133*a5b79717SMircea Trofin // CHECK-LABEL: test_with_const_big_array
test_with_const_big_array()134*a5b79717SMircea Trofin extern "C" void test_with_const_big_array() {
135*a5b79717SMircea Trofin   benchmark::DoNotOptimize(ConstBigArray);
136*a5b79717SMircea Trofin   // CHECK: ret
137*a5b79717SMircea Trofin }
138*a5b79717SMircea Trofin 
1395dda2efdSMircea Trofin // CHECK-LABEL: test_with_non_trivial_const_lvalue:
test_with_non_trivial_const_lvalue()1405dda2efdSMircea Trofin extern "C" void test_with_non_trivial_const_lvalue() {
1415dda2efdSMircea Trofin   const NotTriviallyCopyable Obj(ExternInt);
1425dda2efdSMircea Trofin   benchmark::DoNotOptimize(Obj);
1435dda2efdSMircea Trofin   // CHECK: mov{{q|l}} ExternInt(%rip)
1445dda2efdSMircea Trofin   // CHECK: ret
1455dda2efdSMircea Trofin }
1465dda2efdSMircea Trofin 
1475dda2efdSMircea Trofin // CHECK-LABEL: test_div_by_two:
test_div_by_two(int input)1485dda2efdSMircea Trofin extern "C" int test_div_by_two(int input) {
1495dda2efdSMircea Trofin   int divisor = 2;
1505dda2efdSMircea Trofin   benchmark::DoNotOptimize(divisor);
1515dda2efdSMircea Trofin   return input / divisor;
1525dda2efdSMircea Trofin   // CHECK: movl $2, [[DEST:.*]]
1535dda2efdSMircea Trofin   // CHECK: idivl [[DEST]]
1545dda2efdSMircea Trofin   // CHECK: ret
1555dda2efdSMircea Trofin }
1565dda2efdSMircea Trofin 
1575dda2efdSMircea Trofin // CHECK-LABEL: test_inc_integer:
test_inc_integer()1585dda2efdSMircea Trofin extern "C" int test_inc_integer() {
1595dda2efdSMircea Trofin   int x = 0;
160a290770fSMircea Trofin   for (int i = 0; i < 5; ++i) benchmark::DoNotOptimize(++x);
1615dda2efdSMircea Trofin   // CHECK: movl $1, [[DEST:.*]]
1625dda2efdSMircea Trofin   // CHECK: {{(addl \$1,|incl)}} [[DEST]]
1635dda2efdSMircea Trofin   // CHECK: {{(addl \$1,|incl)}} [[DEST]]
1645dda2efdSMircea Trofin   // CHECK: {{(addl \$1,|incl)}} [[DEST]]
1655dda2efdSMircea Trofin   // CHECK: {{(addl \$1,|incl)}} [[DEST]]
1665dda2efdSMircea Trofin   // CHECK-CLANG: movl [[DEST]], %eax
1675dda2efdSMircea Trofin   // CHECK: ret
1685dda2efdSMircea Trofin   return x;
1695dda2efdSMircea Trofin }
1705dda2efdSMircea Trofin 
1715dda2efdSMircea Trofin // CHECK-LABEL: test_pointer_rvalue
test_pointer_rvalue()1725dda2efdSMircea Trofin extern "C" void test_pointer_rvalue() {
1735dda2efdSMircea Trofin   // CHECK: movl $42, [[DEST:.*]]
1745dda2efdSMircea Trofin   // CHECK: leaq [[DEST]], %rax
1755dda2efdSMircea Trofin   // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]])
1765dda2efdSMircea Trofin   // CHECK: ret
1775dda2efdSMircea Trofin   int x = 42;
1785dda2efdSMircea Trofin   benchmark::DoNotOptimize(&x);
1795dda2efdSMircea Trofin }
1805dda2efdSMircea Trofin 
1815dda2efdSMircea Trofin // CHECK-LABEL: test_pointer_const_lvalue:
test_pointer_const_lvalue()1825dda2efdSMircea Trofin extern "C" void test_pointer_const_lvalue() {
1835dda2efdSMircea Trofin   // CHECK: movl $42, [[DEST:.*]]
1845dda2efdSMircea Trofin   // CHECK: leaq [[DEST]], %rax
1855dda2efdSMircea Trofin   // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]])
1865dda2efdSMircea Trofin   // CHECK: ret
1875dda2efdSMircea Trofin   int x = 42;
1885dda2efdSMircea Trofin   int *const xp = &x;
1895dda2efdSMircea Trofin   benchmark::DoNotOptimize(xp);
1905dda2efdSMircea Trofin }
1915dda2efdSMircea Trofin 
1925dda2efdSMircea Trofin // CHECK-LABEL: test_pointer_lvalue:
test_pointer_lvalue()1935dda2efdSMircea Trofin extern "C" void test_pointer_lvalue() {
1945dda2efdSMircea Trofin   // CHECK: movl $42, [[DEST:.*]]
1955dda2efdSMircea Trofin   // CHECK: leaq [[DEST]], %rax
1965dda2efdSMircea Trofin   // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z+]+]])
1975dda2efdSMircea Trofin   // CHECK: ret
1985dda2efdSMircea Trofin   int x = 42;
1995dda2efdSMircea Trofin   int *xp = &x;
2005dda2efdSMircea Trofin   benchmark::DoNotOptimize(xp);
2015dda2efdSMircea Trofin }
202