https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103002
Bug ID: 103002
Summary: Missed loop unrolling opportunity
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: david.bolvansky at gmail dot com
Target Milestone: ---
#define C 3
struct node {
struct node *next;
int payload;
};
static int count_nodes(const node* p) {
int size = 0;
while (p) {
p = p->next;
size++;
}
return size;
}
bool has_one_node(const node* p) {
return count_nodes(p) == 1;
}
bool has_C_nodes(const node* p) {
return count_nodes(p) == C;
}
has_one_node(node const*): # @has_one_node(node const*)
test rdi, rdi
je .LBB0_1
mov eax, 1
.LBB0_3: # =>This Inner Loop Header: Depth=1
mov rdi, qword ptr [rdi]
add eax, -1
test rdi, rdi
jne .LBB0_3
test eax, eax
sete al
ret
.LBB0_1:
xor eax, eax
ret
has_C_nodes(node const*): # @has_C_nodes(node const*)
test rdi, rdi
je .LBB1_1
mov eax, 3
.LBB1_3: # =>This Inner Loop Header: Depth=1
mov rdi, qword ptr [rdi]
add eax, -1
test rdi, rdi
jne .LBB1_3
test eax, eax
sete al
ret
.LBB1_1:
xor eax, eax
ret
has_C_nodes is simple with some kind of loop deletion pass, but generally,
these loops can be unrolled for some reasonable C values.
https://godbolt.org/z/do656c17b