[Bug middle-end/79675] New: Pointless reg1 <- reg2; reg2 <- reg1 moves inside loop
ktkachov at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Feb 22 12:17:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79675
Bug ID: 79675
Summary: Pointless reg1 <- reg2; reg2 <- reg1 moves inside loop
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: ktkachov at gcc dot gnu.org
Target Milestone: ---
I'm looking at the code:
char *
foo (char *s1, char *s2, unsigned int n)
{
char c1, c2;
c2 = *(char *)s2++;
do
{
do
{
c1 = *s1++;
if (c1 == 0)
return 0;
}
while (c1 != c2);
}
while (__builtin_strncmp (s1, (char *)s2, n) != 0);
return --s1;
}
On aarch64 at -O2 this generates some bad code for the inner loop:
...
.L9:
cmp w21, w1
beq .L8
.L4:
mov x20, x19 // (1)
mov x19, x20 // (2)
ldrb w1, [x19], 1 (3)
cbnz w1, .L9
...
Note the moves between x20 and x19, (1) and (2)
Looking at the RTL dumps the two moves were in separate basic blocks but were
moved together at some point.
Instructions (2) and (3) were transformed by autoincdec from:
add x19, x20, #1
ldrb w1, [x19, #-1]
but nothing eliminated (2) because x19 is later used as an argument to strncmp
and in another basic block.
Doesn't the peephole2 pass try to eliminate such back-to-back copies?
More information about the Gcc-bugs
mailing list