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: unassig...@gcc.gnu.org
        ReportedBy: eriks...@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.

Reply via email to