This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug optimization/14669] [3.4/3.5 Regression] Wrong code with -O for enum values expression E4 <= t && t <= E6


------- Additional Comments From kazu at cs dot umass dot edu  2004-03-22 00:52 -------
This bug now seems to be a latent one.
Here is an except from a part of fold() that folds comparisons.

      /* If we are widening one operand of an integer comparison,
	 see if the other operand is similarly being widened.  Perhaps we
	 can do the comparison in the narrower type.  */
      else if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
	       && TREE_CODE (arg0) == NOP_EXPR
	       && (tem = get_unwidened (arg0, NULL_TREE)) != arg0
	       && (t1 = get_unwidened (arg1, TREE_TYPE (tem))) != 0
	       && (TREE_TYPE (t1) == TREE_TYPE (tem)
		   || (TREE_CODE (t1) == INTEGER_CST
		       && int_fits_type_p (t1, TREE_TYPE (tem)))))
	return fold (build (code, type, tem,
			    fold_convert (TREE_TYPE (tem), t1)));

Note that the first call to get_unwidened does not preserve signedness.
So if code == LE_EXPR, for example, the meaning of the comparison changes.

I've worked around the problem with the following patch, but this approach
seems lossy, though.  That is, if get_unwidened changes the signdness,
we can restore the signedness back.

Index: fold-const.c
===================================================================
RCS file: /home/kazu/nobackup/gcc-cvs/gcc/gcc/fold-const.c,v
retrieving revision 1.328
diff -u -r1.328 fold-const.c
--- fold-const.c	7 Feb 2004 18:57:29 -0000	1.328
+++ fold-const.c	22 Mar 2004 00:44:15 -0000
@@ -7599,6 +7599,9 @@
       else if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
 	       && TREE_CODE (arg0) == NOP_EXPR
 	       && (tem = get_unwidened (arg0, NULL_TREE)) != arg0
+	       && (code == EQ_EXPR || code == NE_EXPR
+		   || (TREE_UNSIGNED (TREE_TYPE (arg0))
+		       == TREE_UNSIGNED (TREE_TYPE (tem))))
 	       && (t1 = get_unwidened (arg1, TREE_TYPE (tem))) != 0
 	       && (TREE_TYPE (t1) == TREE_TYPE (tem)
 		   || (TREE_CODE (t1) == INTEGER_CST

To address the above issue, I wrote another patch like so

Index: fold-const.c
===================================================================
RCS file: /home/kazu/nobackup/gcc-cvs/gcc/gcc/fold-const.c,v
retrieving revision 1.328
diff -u -r1.328 fold-const.c
--- fold-const.c	7 Feb 2004 18:57:29 -0000	1.328
+++ fold-const.c	22 Mar 2004 00:40:23 -0000
@@ -7599,6 +7599,9 @@
       else if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
 	       && TREE_CODE (arg0) == NOP_EXPR
 	       && (tem = get_unwidened (arg0, NULL_TREE)) != arg0
+	       && (tem = (TREE_UNSIGNED (TREE_TYPE (arg0))
+			  ? fold_convert (lang_hooks.types.unsigned_type (TREE_TYPE (tem)), tem)
+			  : fold_convert (lang_hooks.types.signed_type   (TREE_TYPE (tem)), tem)))
 	       && (t1 = get_unwidened (arg1, TREE_TYPE (tem))) != 0
 	       && (TREE_TYPE (t1) == TREE_TYPE (tem)
 		   || (TREE_CODE (t1) == INTEGER_CST

But GCC with this patch segfaults.  Seems like it goes into an infinite
recursion or something.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14669


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]