Subject: bin/7066: GCC code generator bug with -O
To: None <gnats-bugs@gnats.netbsd.org, bug-gcc@prep.ai.mit.edu, harte@xs4all.nl,>
From: Felix A. Croes <felix@dworkin.nl>
List: netbsd-bugs
Date: 03/01/1999 01:47:32
>Number: 7066
>Category: bin
>Synopsis: GCC code generator bug with -O
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Feb 28 18:20:01 1999
>Last-Modified:
>Originator: Felix A. Croes
>Organization:
Dworkin B.V.
>Release: 1.3.3
>Environment:
System: NetBSD pattern 1.3.3 NetBSD 1.3.3 (PATTERN) #1: Sun Jan 31 13:19:17 CET 1999 felix@pattern:/usr/src/sys/arch/i386/compile/PATTERN i386
>Description:
fold_truthop() forgets to apply previously computed bitmasks when
merging two successive fields into one wider field. As a result,
wrong code is generated for the following:
if (x.a == (y.a & mask) && x.b == y.b) { ...
Code is generated instead for the following:
if (x.a == y.a && x.b == y.b) { ...
I verified that this bug exists in gcc 2.7.2.2, 2.7.2.3 and 2.8.1.
It may also exist in egcs.
>How-To-Repeat:
Compile the following code with gcc -O:
struct foo {
char a, b;
short c;
};
int main()
{
static struct foo x = { 1, 2 }, y = { 65, 2 };
return !(x.a == (y.a & ~64) && x.b == y.b);
}
If the bug is present, the program will exit with status 1.
>Fix:
*** fold-const.c.old Tue May 5 08:33:36 1998
--- fold-const.c Mon Mar 1 02:34:26 1999
***************
*** 2978,2993 ****
&& lr_bitsize + lr_bitpos == rr_bitpos)
|| (ll_bitpos == rl_bitpos + rl_bitsize
&& lr_bitpos == rr_bitpos + rr_bitsize))
! return build (wanted_code, truth_type,
! make_bit_field_ref (ll_inner, type,
! ll_bitsize + rl_bitsize,
! MIN (ll_bitpos, rl_bitpos),
! ll_unsignedp),
! make_bit_field_ref (lr_inner, type,
! lr_bitsize + rr_bitsize,
! MIN (lr_bitpos, rr_bitpos),
! lr_unsignedp));
return 0;
}
--- 2978,2995 ----
&& lr_bitsize + lr_bitpos == rr_bitpos)
|| (ll_bitpos == rl_bitpos + rl_bitsize
&& lr_bitpos == rr_bitpos + rr_bitsize))
! {
! lhs = make_bit_field_ref (ll_inner, type, ll_bitsize + rl_bitsize,
! MIN (ll_bitpos, rl_bitpos), ll_unsignedp);
! rhs = make_bit_field_ref (lr_inner, type, lr_bitsize + rr_bitsize,
! MIN (lr_bitpos, rr_bitpos), lr_unsignedp);
! if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
! lhs = build (BIT_AND_EXPR, type, lhs, ll_mask);
! if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
! rhs = build (BIT_AND_EXPR, type, rhs, lr_mask);
! return build (wanted_code, truth_type, lhs, rhs);
+ }
return 0;
}
>Audit-Trail:
>Unformatted: