1 #include <benchmark/benchmark.h>
2 
3 #ifdef __clang__
4 #pragma clang diagnostic ignored "-Wreturn-type"
5 #endif
6 
7 // clang-format off
8 extern "C" {
9   extern int ExternInt;
10   benchmark::State& GetState();
11   void Fn();
12 }
13 // clang-format on
14 
15 using benchmark::State;
16 
17 // CHECK-LABEL: test_for_auto_loop:
test_for_auto_loop()18 extern "C" int test_for_auto_loop() {
19   State& S = GetState();
20   int x = 42;
21   // CHECK: 	[[CALL:call(q)*]]	_ZN9benchmark5State16StartKeepRunningEv
22   // CHECK-NEXT: testq %rbx, %rbx
23   // CHECK-NEXT: je [[LOOP_END:.*]]
24 
25   for (auto _ : S) {
26     // CHECK: .L[[LOOP_HEAD:[a-zA-Z0-9_]+]]:
27     // CHECK-GNU-NEXT: subq $1, %rbx
28     // CHECK-CLANG-NEXT: {{(addq \$1, %rax|incq %rax|addq \$-1, %rbx)}}
29     // CHECK-NEXT: jne .L[[LOOP_HEAD]]
30     benchmark::DoNotOptimize(x);
31   }
32   // CHECK: [[LOOP_END]]:
33   // CHECK: [[CALL]]	_ZN9benchmark5State17FinishKeepRunningEv
34 
35   // CHECK: movl $101, %eax
36   // CHECK: ret
37   return 101;
38 }
39 
40 // CHECK-LABEL: test_while_loop:
test_while_loop()41 extern "C" int test_while_loop() {
42   State& S = GetState();
43   int x = 42;
44 
45   // CHECK: j{{(e|mp)}} .L[[LOOP_HEADER:[a-zA-Z0-9_]+]]
46   // CHECK-NEXT: .L[[LOOP_BODY:[a-zA-Z0-9_]+]]:
47   while (S.KeepRunning()) {
48     // CHECK-GNU-NEXT: subq $1, %[[IREG:[a-z]+]]
49     // CHECK-CLANG-NEXT: {{(addq \$-1,|decq)}} %[[IREG:[a-z]+]]
50     // CHECK: movq %[[IREG]], [[DEST:.*]]
51     benchmark::DoNotOptimize(x);
52   }
53   // CHECK-DAG: movq [[DEST]], %[[IREG]]
54   // CHECK-DAG: testq %[[IREG]], %[[IREG]]
55   // CHECK-DAG: jne .L[[LOOP_BODY]]
56   // CHECK-DAG: .L[[LOOP_HEADER]]:
57 
58   // CHECK: cmpb $0
59   // CHECK-NEXT: jne .L[[LOOP_END:[a-zA-Z0-9_]+]]
60   // CHECK: [[CALL:call(q)*]] _ZN9benchmark5State16StartKeepRunningEv
61 
62   // CHECK: .L[[LOOP_END]]:
63   // CHECK: [[CALL]] _ZN9benchmark5State17FinishKeepRunningEv
64 
65   // CHECK: movl $101, %eax
66   // CHECK: ret
67   return 101;
68 }
69