This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
Re: optimization/6822: GCC 3.1.1 - Internal compiler error in extract_insn, at recog.c:2132
- From: Glen Nakamura <glen at imodulo dot com>
- To: nobody at gcc dot gnu dot org
- Cc: gcc-prs at gcc dot gnu dot org,
- Date: 29 May 2002 03:36:00 -0000
- Subject: Re: optimization/6822: GCC 3.1.1 - Internal compiler error in extract_insn, at recog.c:2132
- Reply-to: Glen Nakamura <glen at imodulo dot com>
The following reply was made to PR optimization/6822; it has been noted by GNATS.
From: Glen Nakamura <glen@imodulo.com>
To: Eric Botcazou <ebotcazou@libertysurf.fr>
Cc: Richard Henderson <rth@redhat.com>, gcc-gnats@gcc.gnu.org,
gcc-bugs@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: optimization/6822: GCC 3.1.1 - Internal compiler error in extract_insn, at recog.c:2132
Date: Tue, 28 May 2002 17:33:01 -1000
--1yeeQ81UyVL57Vl7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6822
Here is the updated patch...
2002-05-28 Glen Nakamura <glen@imodulo.com>
* fold-const.c (fold): Modify the transformation of a comparison
against the highest or lowest integer value to adjust for the
previous transformation which converts 'X >= CST to X > (CST - 1)'
and 'X < CST to X <= (CST - 1)'.
--1yeeQ81UyVL57Vl7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fold2.diff"
Index: fold-const.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.185.2.2
diff -c -3 -p -u -r1.185.2.2 fold-const.c
--- fold-const.c 23 Apr 2002 23:20:00 -0000 1.185.2.2
+++ fold-const.c 29 May 2002 03:04:20 -0000
@@ -6490,7 +6490,14 @@ fold (expr)
}
}
- /* Change X >= CST to X > (CST - 1) if CST is positive. */
+ /* Change X >= CST to X > (CST - 1) and X < CST to X <= (CST - 1)
+ if CST is positive. This transformation affects the cases which are
+ handled in later optimizations involving comparisons with non-negative
+ constants. Remember to handle the equivalent > and <= cases instead
+ of the >= and < cases. Refer to the optimizations involving
+ comparisons with 0 and comparisons with the highest possible integer
+ of a specified type below for details of how this transformation
+ affects them. */
if (TREE_CODE (arg1) == INTEGER_CST
&& TREE_CODE (arg0) != INTEGER_CST
&& tree_int_cst_sgn (arg1) > 0)
@@ -6702,7 +6709,11 @@ fold (expr)
}
}
- /* An unsigned comparison against 0 can be simplified. */
+ /* An unsigned comparison against 0 can be simplified.
+ This optimization also applies to X >= 1 and X < 1 since those cases
+ are converted to X > 0 and X <= 0 by a previous transformation
+ which changes X >= CST to X > (CST - 1) and X < CST to X <= (CST - 1)
+ if CST is positive. */
if (integer_zerop (arg1)
&& (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
|| POINTER_TYPE_P (TREE_TYPE (arg1)))
@@ -6754,6 +6765,7 @@ fold (expr)
convert (type, integer_zero_node),
arg0);
case GE_EXPR:
+ code = EQ_EXPR;
TREE_SET_CODE (t, EQ_EXPR);
break;
@@ -6762,16 +6774,45 @@ fold (expr)
convert (type, integer_one_node),
arg0);
case LT_EXPR:
+ code = NE_EXPR;
TREE_SET_CODE (t, NE_EXPR);
break;
+ /* The GE_EXPR and LT_EXPR cases above are not normally
+ reached because a previous transformation changes
+ X >= CST to X > (CST - 1) and X < CST to X <= (CST - 1)
+ if CST is positive. The two new cases are handled
+ in the next switch statement. */
+
+ default:
+ break;
+ }
+
+ else if (TREE_INT_CST_HIGH (arg1) == 0
+ && (TREE_INT_CST_LOW (arg1)
+ == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 2)
+ && ! TREE_UNSIGNED (TREE_TYPE (arg1)))
+ switch (TREE_CODE (t))
+ {
+ case GT_EXPR:
+ code = EQ_EXPR;
+ arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
+ t = build (code, type, TREE_OPERAND (t, 0), arg1);
+ break;
+
+ case LE_EXPR:
+ code = NE_EXPR;
+ arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
+ t = build (code, type, TREE_OPERAND (t, 0), arg1);
+ break;
+
default:
break;
}
else if (TREE_INT_CST_HIGH (arg1) == -1
&& (TREE_INT_CST_LOW (arg1)
- == ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
+ == ((unsigned HOST_WIDE_INT) -1 << (width - 1)))
&& ! TREE_UNSIGNED (TREE_TYPE (arg1)))
switch (TREE_CODE (t))
{
@@ -6780,6 +6821,7 @@ fold (expr)
convert (type, integer_zero_node),
arg0);
case LE_EXPR:
+ code = EQ_EXPR;
TREE_SET_CODE (t, EQ_EXPR);
break;
@@ -6788,6 +6830,7 @@ fold (expr)
convert (type, integer_one_node),
arg0);
case GT_EXPR:
+ code = NE_EXPR;
TREE_SET_CODE (t, NE_EXPR);
break;
@@ -6804,12 +6847,18 @@ fold (expr)
switch (TREE_CODE (t))
{
case LE_EXPR:
+ /* This case also applies to X < (1 << (width - 1))
+ since a previous transformation changes
+ X < CST to X <= (CST - 1) if CST is positive. */
return fold (build (GE_EXPR, type,
convert (signed_type (TREE_TYPE (arg0)),
arg0),
convert (signed_type (TREE_TYPE (arg1)),
integer_zero_node)));
case GT_EXPR:
+ /* This case also applies to X >= (1 << (width - 1))
+ since a previous transformation changes
+ X >= CST to X > (CST - 1) if CST is positive. */
return fold (build (LT_EXPR, type,
convert (signed_type (TREE_TYPE (arg0)),
arg0),
@@ -6831,6 +6880,7 @@ fold (expr)
convert (type, integer_zero_node),
arg0);
case GE_EXPR:
+ code = EQ_EXPR;
TREE_SET_CODE (t, EQ_EXPR);
break;
@@ -6839,7 +6889,36 @@ fold (expr)
convert (type, integer_one_node),
arg0);
case LT_EXPR:
+ code = NE_EXPR;
TREE_SET_CODE (t, NE_EXPR);
+ break;
+
+ /* The GE_EXPR and LT_EXPR cases above are not normally
+ reached because a previous transformation changes
+ X >= CST to X > (CST - 1) and X < CST to X <= (CST - 1)
+ if CST is positive. The two new cases are handled
+ in the next switch statement. */
+
+ default:
+ break;
+ }
+
+ else if (TREE_INT_CST_HIGH (arg1) == 0
+ && (TREE_INT_CST_LOW (arg1)
+ == ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 2)
+ && TREE_UNSIGNED (TREE_TYPE (arg1)))
+ switch (TREE_CODE (t))
+ {
+ case GT_EXPR:
+ code = EQ_EXPR;
+ arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
+ t = build (code, type, TREE_OPERAND (t, 0), arg1);
+ break;
+
+ case LE_EXPR:
+ code = NE_EXPR;
+ arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
+ t = build (code, type, TREE_OPERAND (t, 0), arg1);
break;
default:
--1yeeQ81UyVL57Vl7--