This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
A patch for a bad combine bug
- To: hymie at prolifics dot com
- Subject: A patch for a bad combine bug
- From: hjl at lucon dot org (H.J. Lu)
- Date: Fri, 12 Jun 1998 14:17:26 -0700 (PDT)
- Cc: egcs-patches at cygnus dot com, kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner), law at cygnus dot com
Hi,
Here is the testcase and a patch. On x86, I got
# gcc -O foo.c
# a.out
FAILED!
The bug is introduced by
Wed Mar 18 05:54:25 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* combine.c (simplify_comparison, case AND): Commute AND and
SUBREG.
I am not sure if my patch is correct. But Kenner's change is wrong.
--
H.J. Lu (hjl@gnu.org)
---
struct fd
{
unsigned char a;
unsigned char b;
} f = { 5 };
struct fd *g() { return &f; }
int h() { return -1; }
int main(int c, char **v)
{
extern int printf(char *, ...);
struct fd *f = g();
f->b = h();
if (((f->a & 0x7f) & ~0x10) <= 2)
printf("FAILED!\n");
return 0;
}
-----
Fri Jun 12 08:01:35 1998 H.J. Lu (hjl@gnu.org)
* combine.c (simplify_comparison): Don't commute AND and SUBREG
if SUBREG is paradoxical.
Index: combine.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/combine.c,v
retrieving revision 1.1.1.16
diff -u -p -r1.1.1.16 combine.c
--- combine.c 1998/04/05 19:06:30 1.1.1.16
+++ combine.c 1998/06/12 21:03:33
@@ -10136,13 +10136,13 @@ simplify_comparison (code, pop0, pop1)
}
/* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1 fits
- in both M1 and M2 and the SUBREG is either paradoxical or
+ in both M1 and M2 and the SUBREG is not paradoxical and
represents the low part, permute the SUBREG and the AND and
try again. */
if (GET_CODE (XEXP (op0, 0)) == SUBREG
- && ((mode_width
- >= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))
- || subreg_lowpart_p (XEXP (op0, 0)))
+ && mode_width
+ <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
+ && subreg_lowpart_p (XEXP (op0, 0))
&& GET_CODE (XEXP (op0, 1)) == CONST_INT
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))