Skip to contentSkip to conversation

Error in gcc version 2.96 20000731

DISCUSSION Kjeld Borch Egevang 3 participants 10 messages Sep 13, 2001 – Sep 14, 2001 MIPS

lore
Share & tools
lore
#0 lore raw

Hi all.

I discovered an optimization error in the current gcc for MIPS.

When I compile the code below with -O2 it clears the code-field just after setting it. The instructions are mixed up. It works fine with -O1 and -O0.

If the "//" is removed in front of the first printf, it works too.

/Kjeld

--------------- cut here -----------------
#include <stdio.h>

typedef struct rtx_def
{
short code;
int dummy;
} rtx;

void put_code (rtx *rt, short code)
{
register int length;

length = 1;
for (; length >= 0; length--)
((int *) rt)[length] = 0;

// printf("put_code before\n");
rt->code = code;
printf("put_code after, code=%d %d\n", code, rt->code); }

int main()
{
rtx rt;

put_code(&rt, 5);
printf("gen_rtx, code=%d\n", rt.code);
}
--------------- cut here -----------------

The assembler looks like:

.rdata
.align 2
$LC0:

      .ascii  "put_code after, code=%d %d\n\000"
      .text
      .align  2
      .globl  put_code
      .ent    put_code
      .type    put_code,@function
put_code:
      .frame  $sp,32,$31              # vars= 0, regs= 2/0, args= 16, 
extra= 8
      .mask   0x90000000,-4
      .fmask  0x00000000,0
      .set    noreorder
      .cpload $25
      .set    reorder
      subu    $sp,$sp,32
      .cprestore 16
      move    $2,$5
      sll     $2,$2,16
      sra     $2,$2,16
      move    $5,$2
      la      $3,$LC0
      sw      $31,28($sp)
      sw      $28,24($sp)
      move    $6,$5
      sh      $2,0($4)     <----- sets code field
      sw      $0,4($4)     <----- clears structure
      sw      $0,0($4)     <----- clears structure
      move    $4,$3
      la      $25,printf
      jal     $31,$25
      lw      $31,28($sp)
      #nop
      .set    noreorder
      .set    nomacro
      j       $31
      addu    $sp,$sp,32
      .set    macro
      .set    reorder

      .end    put_code
#1 lore raw
Quoted 10 lines · Kjeld Borch Egevang

Hi all.

I discovered an optimization error in the current gcc for MIPS.

When I compile the code below with -O2 it clears the code-field just after setting it. The instructions are mixed up. It works fine with -O1 and -O0.

If the "//" is removed in front of the first printf, it works too.

The code isn't ISO C. You cannot declare something as short and then access it as int. On x86:

# gcc alias.c -O
put_code after, code=5 5
gen_rtx, code=5
# gcc alias.c -O2
put_code after, code=5 0
gen_rtx, code=0

On mips,

# gcc alias.c -O
put_code after, code=5 5
gen_rtx, code=5
# gcc alias.c -O2
put_code after, code=5 5
gen_rtx, code=0

You can fix the code or add -fno-strict-aliasing

# gcc alias.c -O2 -fno-strict-aliasing
put_code after, code=5 5
gen_rtx, code=5

H.J.

#2 lore raw

Perhaps I don't get you point, but I get the same with:

int main()
{
rtx rt;

put_code(&rt, (short)5);
printf("gen_rtx, code=%d\n", (int)rt.code);
}

/Kjeld

-----Original Message-----
From: [email protected] [mailto:[email protected]]On Behalf Of H . J . Lu
Sent: 13. september 2001 17:11
To: Kjeld Borch Egevang
Cc: [email protected]
Subject: Re: Error in gcc version 2.96 20000731

Quoted 10 lines · Kjeld Borch Egevang

Hi all.

I discovered an optimization error in the current gcc for MIPS.

When I compile the code below with -O2 it clears the code-field just after setting it. The instructions are mixed up. It works fine with -O1 and -O0.

If the "//" is removed in front of the first printf, it works too.

The code isn't ISO C. You cannot declare something as short and then access it as int. On x86:

# gcc alias.c -O
put_code after, code=5 5
gen_rtx, code=5
# gcc alias.c -O2
put_code after, code=5 0
gen_rtx, code=0

On mips,

# gcc alias.c -O
put_code after, code=5 5
gen_rtx, code=5
# gcc alias.c -O2
put_code after, code=5 5
gen_rtx, code=0

You can fix the code or add -fno-strict-aliasing

# gcc alias.c -O2 -fno-strict-aliasing
put_code after, code=5 5
gen_rtx, code=5

H.J.

#3 lore raw
Quoted 10 lines · Kjeld Borch Egevang

Perhaps I don't get you point, but I get the same with:

int main()
{
rtx rt;

put_code(&rt, (short)5);
printf("gen_rtx, code=%d\n", (int)rt.code);
}

That is not what I meant. You have

typedef struct rtx_def
{
short code;
int dummy;
} rtx;

The first field of rtx_def is short.

  for (; length >= 0; length--)
    ((int *) rt)[length] = 0;

But you access it as int. If you do

  for (; length >= 0; length--)
    ((short *) rt)[length] = 0;

It will be ok.

H.J.

#4 lore raw

I get your point. A bit suprising though. Do you consider it a bug?

/Kjeld

-----Original Message-----
From: [email protected] [mailto:[email protected]]On Behalf Of H . J . Lu
Sent: 13. september 2001 23:15
To: Kjeld Borch Egevang
Cc: [email protected]
Subject: Re: Error in gcc version 2.96 20000731

Quoted 10 lines · Kjeld Borch Egevang

Perhaps I don't get you point, but I get the same with:

int main()
{
rtx rt;

put_code(&rt, (short)5);
printf("gen_rtx, code=%d\n", (int)rt.code);
}

That is not what I meant. You have

typedef struct rtx_def
{
short code;
int dummy;
} rtx;

The first field of rtx_def is short.

  for (; length >= 0; length--)
    ((int *) rt)[length] = 0;

But you access it as int. If you do

  for (; length >= 0; length--)
    ((short *) rt)[length] = 0;

It will be ok.

H.J.

#5 lore raw
Quoted 1 line · Kjeld Borch Egevang

I get your point. A bit suprising though. Do you consider it a bug?

It is an alias bug in your example.

H.J.

#6 lore raw
In reply to Kjeld Borch Egevang
Quoted 1 line · Kjeld Borch Egevang

I discovered an optimization error in the current gcc for MIPS.

Is 2.96 20000731 current? I thought 3.0.1 is.

Quoted 3 lines

When I compile the code below with -O2 it clears the code-field just after setting it. The instructions are mixed up. It works fine with -O1 and -O0.

Use "-fno-strict-aliasing"?

Quoted 1 line

If the "//" is removed in front of the first printf, it works too.

Why don't you use memset() to clear the struct in the first place?

Signature · 3 lines
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [email protected], PGP key available        +
#7 lore raw
Quoted 6 lines · Maciej W. Rozycki
Quoted 1 line · Kjeld Borch Egevang

I discovered an optimization error in the current gcc for MIPS.

Is 2.96 20000731 current? I thought 3.0.1 is.

gcc 3.0.1 lacks many patches in my gcc 2.96 and gcc 3.x. I am trying to get them backported to 3.0.x.

H.J.

#8 lore raw
In reply to Maciej W. Rozycki

Thanks for your reply.

I was trying to port SPEC CPU 2000 (benchmarks), and one of the tests failed. I boiled it down to the attached program. For performance reasons it could be perfectly valid not to use memset(), but I agree that the code looks a bit odd.

/Kjeld

-----Original Message-----
From: Maciej W. Rozycki [mailto:[email protected]]
Sent: 13. september 2001 17:15
To: Kjeld Borch Egevang
Cc: [email protected]
Subject: Re: Error in gcc version 2.96 20000731

Quoted 1 line · Kjeld Borch Egevang

I discovered an optimization error in the current gcc for MIPS.

Is 2.96 20000731 current? I thought 3.0.1 is.

Quoted 3 lines

When I compile the code below with -O2 it clears the code-field just after setting it. The instructions are mixed up. It works fine with -O1 and -O0.

Use "-fno-strict-aliasing"?

Quoted 1 line

If the "//" is removed in front of the first printf, it works too.

Why don't you use memset() to clear the struct in the first place?

--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +

+--------------------------------------------------------------+
+        e-mail: [email protected], PGP key available        +
#9 lore raw
Quoted 4 lines · Kjeld Borch Egevang

I was trying to port SPEC CPU 2000 (benchmarks), and one of the tests failed. I boiled it down to the attached program. For performance reasons it could be perfectly valid not to use memset(), but I agree that the code looks a bit odd.

With a high optimization level and a constant size of the area to set
(you'd likely use sizeof here, which is constant) gcc will happily inline a memset() yielding no worse performance but no bugs and better readability. You may have no loop at all as the result. Check yourself!

Signature · 3 lines
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [email protected], PGP key available        +