This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/46357] New: Unnecessary movzx instruction
- From: "justin.lebar+bug at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 8 Nov 2010 05:52:37 +0000
- Subject: [Bug c/46357] New: Unnecessary movzx instruction
- Auto-submitted: auto-generated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46357
Summary: Unnecessary movzx instruction
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: justin.lebar+bug@gmail.com
Originally reported to the gcc-help list.
Tested with gcc Ubuntu/Linaro 4.5.1-7ubuntu2, but I get the same code with gcc
4.4.
The following C code generates assembly code with what appears to be an
unnecessary call to movzx:
char skip[] = { /* ... */ };
int foo(const unsigned char *str, int len)
{
int result = 0;
int i = 7;
while (i < len) {
if (str[i] == '_' && str[i-1] == 'D') {
result |= 2;
}
i += skip[str[i]];
}
return result;
}
0000000000000000 <foo>:
0: 31 c0 xor eax,eax
2: 83 fe 07 cmp esi,0x7
5: ba 07 00 00 00 mov edx,0x7
a: 7f 14 jg 20 <foo+0x20>
c: eb 32 jmp 40 <foo+0x40>
e: 66 90 xchg ax,ax
// Beginning of loop
10: 0f b6 c9 movzx ecx,cl
13: 0f be 89 00 00 00 00 movsx ecx,BYTE PTR [rcx+0x0]
1a: 01 ca add edx,ecx
1c: 39 d6 cmp esi,edx
1e: 7e 20 jle 40 <foo+0x40>
20: 4c 63 c2 movsxd r8,edx
23: 42 0f b6 0c 07 movzx ecx,BYTE PTR [rdi+r8*1]
28: 80 f9 5f cmp cl,0x5f
2b: 75 e3 jne 10 <foo+0x10>
// Likely end of loop (i.e. branch above is likely taken)
2d: 41 89 c1 mov r9d,eax
30: 41 83 c9 02 or r9d,0x2
34: 41 80 7c 38 ff 44 cmp BYTE PTR [r8+rdi*1-0x1],0x44
3a: 41 0f 44 c1 cmove eax,r9d
3e: eb d0 jmp 10 <foo+0x10>
40: f3 c3 repz ret
The movzx on line 10 sets everything except the least-significant bit of ecx to
zero. This is unnecessary since line 23 dominates line 10, so we're guaranteed
that ecx contains zeros everywhere except in its least-significant bit by the
time we get to line 10.
If I change |str| in the C code to a signed char, then line 10 becomes movsx
(now a necessary instruction). Perhaps this gives a hint as to where the errant
instruction is coming from.