[missed optimization opportunity] clang still generates code for empty loop over an std::map object
| Bugzilla Link | 51694 |
| Version | 11.0 |
| OS | FreeBSD |
| Attachments | testcase.cpp |
| CC | @DougGregor,@zygoloid |
Extended Description
The attached testcase iterates through the std::map object with empty for-body.
clang-14 still generates some code in this function when it should be empty.
Replacing the type of the argument with std::vector correctly leads to an empty function.
This still reproduces on post 16 trunk(5cbcaf1678709e4da8b32f075a5c9a3cab028965) https://godbolt.org/z/vEcEfET1E
Slightly simpler code
#include <map>
void f(std::map<int, int> &v) {
for (auto i : v)
{ }
}
Produces the following assembly when compiled with -O3
f(std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >&): # @fff(std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >&)
push rbx
mov rbx, rdi
mov rax, qword ptr [rdi + 24]
add rbx, 8
cmp rax, rbx
je .LBB0_3
.LBB0_1: # =>This Inner Loop Header: Depth=1
mov rdi, rax
call std::_Rb_tree_increment(std::_Rb_tree_node_base*)@PLT
cmp rax, rbx
jne .LBB0_1
.LBB0_3:
pop rbx
ret
If you replace the map with a unordered_map you instead get
mov rdi, qword ptr [rdi]
test rdi, rdi
jne .LBB0_1
ret
And if you replace the map with a vector you get
f(std::vector<int, std::allocator<int> >&): # @f(std::vector<int, std::allocator<int> >&)
ret
Should be fixed by https://github.com/llvm/llvm-project/commit/970bf07d0b184c7ec356ae8f47b193a5e3ff0309. Please feel free to reopen this, should you experience an issue alike.