Bug 27176 - [4.1 Regression] Sun disklabel checksum code isn't being generated properly.
Summary: [4.1 Regression] Sun disklabel checksum code isn't being generated properly.
Status: RESOLVED DUPLICATE of bug 26763
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.1.0
: P3 normal
Target Milestone: 4.1.1
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2006-04-15 21:23 UTC by Joe Ciccone
Modified: 2006-04-17 10:10 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.0.3 4.2.0
Known to fail: 4.1.0
Last reconfirmed: 2006-04-17 09:51:04


Attachments
The test case source (580 bytes, text/x-csrc)
2006-04-15 21:24 UTC, Joe Ciccone
Details
The .i file from gcc -O2 test.c (8.54 KB, application/octet-stream)
2006-04-15 21:25 UTC, Joe Ciccone
Details
The .i file from gcc -Os test.c (7.22 KB, application/octet-stream)
2006-04-15 21:25 UTC, Joe Ciccone
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Joe Ciccone 2006-04-15 21:23:46 UTC
I have gcc-4.1 configured with ../gcc-4.1.0/configure --prefix=/usr --libexecdir=/usr/lib --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-c99 --enable-long-long --enable-clocale=gnu --enable-languages=c,c++ --disable-multilib --disable-libstdcxx-pch

The following test generates the checksum of a dummy sun disk label.
cat > test.c << "EOF"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef unsigned short __be16;
typedef unsigned int __be32;

struct sun_disklabel {
        unsigned char info[128];   /* Informative text string */
        unsigned char spare0[14];
        struct sun_info {
                unsigned char spare1;
                unsigned char id;
                unsigned char spare2;
                unsigned char flags;
        } infos[8];
        unsigned char spare[246];  /* Boot information etc. */
        __be16 rspeed;     /* Disk rotational speed */
        __be16 pcylcount;  /* Physical cylinder count */
        __be16 sparecyl;   /* extra sects per cylinder */
        unsigned char spare2[4];   /* More magic... */
        __be16 ilfact;     /* Interleave factor */
        __be16 ncyl;       /* Data cylinder count */
        __be16 nacyl;      /* Alt. cylinder count */
        __be16 ntrks;      /* Tracks per cylinder */
        __be16 nsect;      /* Sectors per track */
        unsigned char spare3[4];   /* Even more magic... */
        struct sun_partition {
                __be32 start_cylinder;
                __be32 num_sectors;
        } partitions[8];
        __be16 magic;      /* Magic number */
        __be16 csum;       /* Label xor'd checksum */
};

int main(void)
{
        struct sun_disklabel label;
        __be16 csum, *ush;

        memset(&label, 0xff, sizeof(label));

        ush = ((__be16 *) (&label + 1)) - 1;
        for (csum = 0; ush >= ((__be16 *) &label); )
                csum ^= *ush--;

        printf("Test checksum is %x\n", csum);

        exit(0);
}
EOF

When this test is compiled with 'gcc test.c' or 'gcc -Os test.c' the checksum is 0. The checksum is supposed to be 0. When the test is compiled with 'gcc -O2 test.c' the checksum is 0xffff. The same goes for -O1 and -O3. Compiling with -Wall doesn't ouput any warnings. The last known version to work is gcc-4.0.2.

As far as I know the problem is in this loop:
 for (csum = 0; ush >= ((__be16 *) &label); )
The problem also exists if the loop is changed to this:
  while (ush >= ((__be16 *) &label))
Comment 1 Joe Ciccone 2006-04-15 21:24:26 UTC
Created attachment 11276 [details]
The test case source
Comment 2 Joe Ciccone 2006-04-15 21:25:14 UTC
Created attachment 11277 [details]
The .i file from gcc -O2 test.c
Comment 3 Joe Ciccone 2006-04-15 21:25:40 UTC
Created attachment 11278 [details]
The .i file from gcc -Os test.c
Comment 4 Andrew Pinski 2006-04-16 02:11:21 UTC
        ush = ((__be16 *) (&label + 1)) - 1;


That is undefined code (at least with strict aliasing turned on).  But that should not have an effect at -O1.
Comment 5 Richard Biener 2006-04-17 09:51:04 UTC
Confirmed.  Number of iteration analysis concludes the loop

  ush_4 = label.23_3 + 510B;
  if (label.23_3 <= ush_4) goto <L6>; else goto <L2>;

<L6>:;

  # ush_16 = PHI <ush_10(3), ush_4(1)>;
  # csum_14 = PHI <csum_9(3), 0(1)>;
<L0>:;
  #   VUSE <label_12>;
  D.2866_8 = *ush_16;
  csum_9 = D.2866_8 ^ csum_14;
  ush_10 = ush_16 - 2B;
  if (label.23_3 <= ush_10) goto <L8>; else goto <L9>;

<L8>:;
  goto <bb 2> (<L0>);

runs once: (.t75.ivcanon)

  (set_nb_iterations_in_loop = 1B))
Loop 1 iterates 0B times.
Unrolled loop 1 completely.

and the loop is gone.  I guess its some signedness problem again:

(add_to_evolution
  (loop_nb = 1)
  (chrec_before = ush_4)
  (to_add = 2B)
  (res = {ush_4, +, -2B}_1))
  (evolution_function = {ush_4, +, -2B}_1))
(set_scalar_evolution
  (scalar = ush_16)
  (scalar_evolution = {ush_4, +, -2B}_1))
)
(analyze_scalar_evolution
  (loop_nb = 1)
  (scalar = 2B)
(get_scalar_evolution
  (scalar = 2B)
  (scalar_evolution = 2B))
)
(set_scalar_evolution
  (scalar = ush_10)
  (scalar_evolution = {ush_4 - 2B, +, -2B}_1))
)
Comment 6 Richard Biener 2006-04-17 10:10:32 UTC
This is a dup of PR26763, which is fixed for 4.1.1.

*** This bug has been marked as a duplicate of 26763 ***