Open davidbolvansky opened 6 years ago
[[likely]] in C++20 supports cases but Clang ignores it yet?
Clang ignores likely hints?
// switch like char * b(int e) { if (likely(e == 0)) return "0"; else if (e == 1) return "1"; else return "f"; }
Clang: b: # @b cmp edi, 1 mov eax, offset .L.str.1 mov ecx, offset .L.str.2 cmove rcx, rax test edi, edi mov eax, offset .L.str cmovne rax, rcx ret
GCC: b: mov eax, OFFSET FLAT:.LC0 test edi, edi jne .L7 ret .L7: cmp edi, 1 mov edx, OFFSET FLAT:.LC2 mov eax, OFFSET FLAT:.LC1 cmovne rax, rdx ret
Seems like GCC prefers first case, Clang prefers nothing.
Any annotation or attribute to mark the case as "hot/likely"?
Sorry, somehow I didnt applied Clang with O3, godbolt somehow removes it.
But even with it in case: char * a(int e) { switch (e) { case 0: return "0"; case 1: return "1"; default: return "default"; } }
Clang: a: # @a cmp edi, 1 mov eax, offset .L.str.1 mov ecx, offset .L.str.2 cmove rcx, rax test edi, edi mov eax, offset .L.str cmovne rax, rcx ret
GCC: a: mov eax, OFFSET FLAT:.LC1 test edi, edi je .L1 cmp edi, 1 mov eax, OFFSET FLAT:.LC2 mov edx, OFFSET FLAT:.LC0 cmovne rax, rdx .L1: ret
Extended Description
Hello,
When we have small "switch"-es with two or three cases, clang could generate a smarter code.
Example: char * a(int e) { switch (e) { case 0: return "0"; default: return "default"; } }
Clang's output: a: # @a push rbp mov rbp, rsp mov dword ptr [rbp - 12], edi mov edi, dword ptr [rbp - 12] test edi, edi jne .LBB0_2 jmp .LBB0_1 .LBB0_1: movabs rax, offset .L.str mov qword ptr [rbp - 8], rax jmp .LBB0_3 .LBB0_2: movabs rax, offset .L.str.1 mov qword ptr [rbp - 8], rax .LBB0_3: mov rax, qword ptr [rbp - 8] pop rbp ret
Better code (GCC does it): a: test edi, edi mov edx, OFFSET FLAT:.LC1 mov eax, OFFSET FLAT:.LC0 cmovne rax, rdx ret
Also for this example: char * a(int e) { switch (e) { case 0: return "0"; case 1: return "1"; default: return "default"; } }
A better code can be generated like: a: mov eax, OFFSET FLAT:.LC1 test edi, edi je .L1 cmp edi, 1 mov eax, OFFSET FLAT:.LC2 mov edx, OFFSET FLAT:.LC0 cmovne rax, rdx .L1: ret
Thanks