[BUG] benchmark::DoNotOptimize does not prevent a reference from being optimized away.
- Dominant language
- C++
- Stars
- 10.4k
- Forks
- 1.8k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 8
Description
**Describe the bug**
`benchmark::DoNotOptimize()` does not prevent a reference from being optimized away.
**System**
OS: Ubuntu 20.04 LTS, Compiler explorer
Compiler: GCC 9.04, GCC trunk, Clang trunk
**To reproduce**
Compiler Explorer that works: https://godbolt.org/z/c3d5sc8s3
Compiler Explorer that does not: https://godbolt.org/z/3bMMvaecr
Alternatively, compile the following code
```c++
#include
#include
static void bm_traverse(benchmark::State& state) {
const size_t N = 500;
std::vector vec;
for (size_t j = 0; j < N; ++j) vec.push_back(j);
for (auto _ : state) {
for (auto& value : vec) {
asm("nop"); // just to locate asm point faster
benchmark::DoNotOptimize(value);
}
benchmark::DoNotOptimize(vec);
}
state.SetComplexityN(N);
}
BENCHMARK(bm_traverse);
BENCHMARK_MAIN();
```
**Expected behavior**
DoNotOptimize should have preserved the loop read. I understand that the reference is basically a pointer but users typically would expect that the reference represents the actual lvalue.
**Screenshots**
With the "&" reference in the inner loop, a vec load is not generated.
```asm
.LBB0_31: # Parent Loop BB0_6 Depth=1
nop
addq $4, %rax
cmpq %rcx, %rax
jne .LBB0_31
```
If you remove the reference the vec load is generated.
```asm
.LBB0_31: # Parent Loop BB0_6 Depth=1
movl (%rax), %edx # <<<< HERE
movl %edx, 12(%rsp)
nop
addq $4, %rax
cmpq %rcx, %rax
jne .LBB0_31
```
**Additional context**
I understand this is a matter of semantics that might have been discussed in the past. In this case, I'd just like confirmation of this behavior.
Contributor guide
Assessment
This issue has not been assessed yet.