[Bug target/54290] New: gcc 4.4/4.5/4.6 produces wrong code on sparc with -O2
eriksnga at gmail dot com
gcc-bugzilla@gcc.gnu.org
Thu Aug 16 19:49:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54290
Bug #: 54290
Summary: gcc 4.4/4.5/4.6 produces wrong code on sparc with -O2
Classification: Unclassified
Product: gcc
Version: 4.6.3
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: eriksnga@gmail.com
Created attachment 28031
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=28031
Output from gcc -v
Test system: SunOS 5.10 sun4u sparc SUNW,SPARC-Enterprise Solaris
GCC Config: output from gcc -v is attached for version 4.6.3
########################################################################
# Test case:
# cat ./testcase.c
#define CHECK 1234567890
double vd[2] = {1., 0.};
int vi[2] = {CHECK, 0};
double *pd = vd;
int *pi = vi;
void init (int *n, int *dummy) __attribute__ ((noinline));
void init (int *n, int *dummy)
{
if(0 == n) dummy[0] = 0;
}
int main ()
{
int dummy[1532];
int i = -1, n = 1, s = 0;
init (&n, dummy);
while (i < n) {
if (i == 0) {
if (pd[i] > 0) {
if (pi[i] > 0) {
s += pi[i];
#ifdef VERIFY
return (pi[i] == CHECK? 2 : 3);
#endif
}
}
pd[i] = pi[i];
}
++i;
}
return (s == CHECK? 0 : 1);
}
#
# gcc-4.6.3 -O2 ./testcase.c
# ./a.out; echo $?
1
#
O1 returns expected result (exit code 0).
Problem is reproducible with gcc/g++, 32/64bit ABI with same test case
or slight variations thereof.
Problem is not reproducible on x86_64/Linux.
########################################################################
# Results from other GCC versions:
GCC version 4.3.2: returns 0, ie. correct result
GCC version 4.4.3: returns 1, ie. wrong result
GCC version 4.5.2: returns 1, ie. wrong result
GCC version 4.6.1: returns 1, ie. wrong result
GCC version 4.6.3: returns 1, ie. wrong result
GCC version 4.7.1: returns 0, ie. correct result
On x86_64/Linux, all versions return 0.
########################################################################
# Details:
The code produced by gcc-4.6.3 misses a load (resp. contains erroneous
instructions) resulting in the use of the address of a temp in place of
the value stored at that address.
[..]
fbule,pt %fcc0, .LL10
ld [%o7], %f8 ! %f8 <- pi[i]
sethi %hi(-6144), %i5 ! compute address for temp
or %i5, 4, %i5
add %i5, %fp, %i5
st %f8, [%i5] ! copy from %f8 ...
ld [%i5], %i5 ! ... to %i5 via temp
add %g4, %i5, %o5 ! %o5 <- s+pi[i]
sethi %hi(-6144), %i5 ! recompute address of temp ...
or %i5, 4, %i5 ! ... which is unnecessary; but when doing so
add %i5, %fp, %i5 ! ... value needs to be reloaded as well:
! !
! ld [%i5], %i5 ! missing instruction
! !
cmp %i5, 0 ! supposedly (pi[i] <=> 0), except %i5 contains
! ! address of temp instead of its value
movg %icc, %o5, %g4 ! pi[i] > 0 : s <- s+pi[i]
.LL10:
fitod %f8, %f8
[..]
As an apparent pre-requisite, the offset for the temp needs to be too
large to fit into an immediate constant. Any array size greater equal to
1022(m32) resp. 1532(m64) for "dummy" in the test case seems to fit the bill.
More information about the Gcc-bugs
mailing list