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