https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83389
Bug ID: 83389 Summary: std::tie generates sub-optimal code when used to compare POD fields Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: lucanus81 at gmail dot com Target Milestone: --- Created attachment 42845 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42845&action=edit cpp file with the example Let's consider a simple struct with two integers: struct data { int x, y; }; Let's suppose we want to write a comparison operator. A first attempt might be bool operator==(data const& d1, data const& d2) { return d1.x == d2.x && d1.y == d2.y } An alternative approach (maybe this is a "bad" approach? )might be to use std::tie. bool operator==(data const& d1, data const& d2) { return std::tie(d1.x, d1.y) == std::tie(d2.x, d2.y); } At O3 gcc 7.2 generates exactly the same code. So far so good. Let's suppose now that we want to add a couple of char fields: struct data { int x, y; char c1, c2; }; At this point gcc starts generating sub-optimal assembler in the sense it fails to see that c1 and c2 are stored into a contiguous memory address and could be compared with a single CMP WORD PTR instruction instead of two CMP BYTE PTR (one for each byte). For operator==() I see the compiler was able to generate a cmpw (where both bytes are packed and compared together) movl 4(%rsi), %ecx cmpl %ecx, 4(%rdi) jne .L1 movzwl 8(%rsi), %eax cmpw %ax, 8(%rdi) sete %al ret while for the std::tie example we generate two cmpb instructions: movl 4(%rsi), %ecx cmpl %ecx, 4(%rdi) jne .L7 movzbl 8(%rsi), %ecx cmpb %cl, 8(%rdi) jne .L7 movzbl 9(%rsi), %eax cmpb %al, 9(%rdi) sete %al ret I don't really fully understand if this is a potential problem or simply it's a "Working As Designed" but I believe that the compiler for std::tie when all types are POD should be able to generate exactly the same code as operator==().