-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
| Bugzilla Link | 1160 |
| Resolution | LATER |
| Resolved on | Sep 26, 2007 01:31 |
| Version | trunk |
| OS | Linux |
| CC | @asl,@lattner |
Extended Description
This small program produces bad x86 assembly code:
unsigned int huge[2048];
unsigned int target[2048];
extern void foo();
int main(int argc, char *argv[])
{
foo();
for (unsigned int i = 0; i < 2048; i++)
{
target[i] |= huge[i];
}
unsigned int x = 0;
for (unsigned int i = 0; i < 2048; i++)
{
x += target[i];
}
return x;
}
There are two problems with the resulting x86 assembly.
For the body of the first loop, LLVM produces:
movl huge(,%eax,4), %ecx
orl target(,%eax,4), %ecx
movl %ecx, target(,%eax,4)
when it should really be loading from huge, then or'ing into target.
In the second loop, LLVM mis-predicts the exit branch, which is inexcusable
seeing as the loop is countable:
.LBB1_5: #bb23
cmpl $2048, %ecx
jne .LBB1_3 #bb15 <--- should be reversed
.LBB1_6: #bb27
addl $4, %esp
ret
.LBB1_3: #bb15
addl target(,%ecx,4), %eax
incl %ecx
jmp .LBB1_5 #bb23