optimization/6822: GCC 3.1.1 - Internal compiler error in extract_insn, at recog.c:2132

Glen Nakamura glen@imodulo.com
Tue May 28 20:33:00 GMT 2002


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)'.

-------------- next part --------------
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:


More information about the Gcc-bugs mailing list