https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127145
Bug ID: 127145
Summary: Suboptimal 3-way comparison of timespec struct when
optimizing for size in x86
Product: gcc
Version: 16.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: hdante at gmail dot com
Target Milestone: ---
Created attachment 65456
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65456&action=edit
Compare function for struct timespec
Hello, I've found a simple case where gcc -Os is not producing a small code in
x86:
struct timespec {
long int tv_sec;
long int tv_nsec;
};
int compare(const void *a_, const void *b_) {
const struct timespec *a = a_;
const struct timespec *b = b_;
int greater;
int less;
greater = (a->tv_sec > b->tv_sec) |
(a->tv_sec == b->tv_sec & a->tv_nsec > b->tv_nsec);
less = (a->tv_sec < b->tv_sec) |
(a->tv_sec == b->tv_sec & a->tv_nsec < b->tv_nsec);
return greater - less;
}
Comparison between gcc and clang:
=== GCC
code size: 0x3d to 0x45 bytes, depending on optimization flags
number of cmp instructions: 4 or more
=== clang
code size: 0x32 bytes with any optimization flags
number of cmp instructions: 2
Example generated gcc code:
[hdante@host1 tmp]$ rm -f cmp.o
[hdante@host1 tmp]$ gcc -c -Os cmp.c
[hdante@host1 tmp]$ objdump -S cmp.o
cmp.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <compare>:
0: 48 89 f0 mov %rsi,%rax
3: 48 89 fa mov %rdi,%rdx
6: 48 8b 37 mov (%rdi),%rsi
9: 48 8b 08 mov (%rax),%rcx
c: 4c 8b 42 08 mov 0x8(%rdx),%r8
10: 48 8b 50 08 mov 0x8(%rax),%rdx
14: 48 39 ce cmp %rcx,%rsi
17: 40 0f 94 c7 sete %dil
1b: 49 39 d0 cmp %rdx,%r8
1e: 0f 9f c0 setg %al
21: 21 f8 and %edi,%eax
23: 48 39 ce cmp %rcx,%rsi
26: 41 0f 9f c1 setg %r9b
2a: 44 09 c8 or %r9d,%eax
2d: 49 39 d0 cmp %rdx,%r8
30: 0f 9c c2 setl %dl
33: 0f b6 c0 movzbl %al,%eax
36: 21 fa and %edi,%edx
38: 48 39 ce cmp %rcx,%rsi
3b: 0f 9c c1 setl %cl
3e: 09 ca or %ecx,%edx
40: 0f b6 d2 movzbl %dl,%edx
43: 29 d0 sub %edx,%eax
45: c3 ret
Example generated clang code:
[hdante@host1 tmp]$ rm -f cmp.o
[hdante@host1 tmp]$ clang -c -Os cmp.c
[hdante@host1 tmp]$ objdump -S cmp.o
cmp.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <compare>:
0: 48 8b 07 mov (%rdi),%rax
3: 48 8b 4f 08 mov 0x8(%rdi),%rcx
7: 48 3b 4e 08 cmp 0x8(%rsi),%rcx
b: 0f 9f c1 setg %cl
e: 0f 9c c2 setl %dl
11: 48 3b 06 cmp (%rsi),%rax
14: 0f 9f c0 setg %al
17: 40 0f 94 c6 sete %sil
1b: 40 0f 9c c7 setl %dil
1f: 40 20 f1 and %sil,%cl
22: 08 c1 or %al,%cl
24: 0f b6 c1 movzbl %cl,%eax
27: 40 20 f2 and %sil,%dl
2a: 40 08 fa or %dil,%dl
2d: 0f b6 ca movzbl %dl,%ecx
30: 29 c8 sub %ecx,%eax
32: c3 ret
Example code follows attached.