sgallagh / rpms / gcc

Forked from rpms/gcc 4 years ago
Clone
Blob Blame History Raw
2009-04-24  Paolo Bonzini  <bonzini@gnu.org>

	PR middle-end/39867
	* fold-const.c (fold_cond_expr_with_comparison): When folding
	> and >= to MAX, make sure the MAX uses the same type as the
	comparison's operands.

	* gcc.dg/pr39867.c: New.

--- gcc/fold-const.c	(revision 146581)
+++ gcc/fold-const.c	(working copy)
@@ -5337,31 +5337,34 @@ fold_cond_expr_with_comparison (tree typ
 	break;
 
       case GT_EXPR:
-	/* If C1 is C2 - 1, this is max(A, C2).  */
+	/* If C1 is C2 - 1, this is max(A, C2), but use ARG00's type for
+	   MAX_EXPR, to preserve the signedness of the comparison.  */
 	if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
 			       OEP_ONLY_CONST)
 	    && operand_equal_p (arg01,
 				const_binop (MINUS_EXPR, arg2,
 					     build_int_cst (type, 1), 0),
 				OEP_ONLY_CONST))
-	  return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
-						   type,
-						   fold_convert (type, arg1),
-						   arg2));
+	  return pedantic_non_lvalue (fold_convert (type,
+				      fold_build2 (MAX_EXPR, TREE_TYPE (arg00),
+						   arg00,
+						   fold_convert (TREE_TYPE (arg00),
+							         arg2))));
 	break;
 
       case GE_EXPR:
-	/* If C1 is C2 + 1, this is max(A, C2).  */
+	/* If C1 is C2 + 1, this is max(A, C2), with the same care as above.  */
 	if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
 			       OEP_ONLY_CONST)
 	    && operand_equal_p (arg01,
 				const_binop (PLUS_EXPR, arg2,
 					     build_int_cst (type, 1), 0),
 				OEP_ONLY_CONST))
-	  return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
-						   type,
-						   fold_convert (type, arg1),
-						   arg2));
+	  return pedantic_non_lvalue (fold_convert (type,
+				      fold_build2 (MAX_EXPR, TREE_TYPE (arg00),
+						   arg00,
+						   fold_convert (TREE_TYPE (arg00),
+							         arg2))));
 	break;
       case NE_EXPR:
 	break;
--- gcc/testsuite/gcc.dg/pr39867.c	2009-04-21 23:33:56.143009234 +0200
+++ gcc/testsuite/gcc.dg/pr39867.c	2009-04-24 09:20:07.000000000 +0200
@@ -0,0 +1,11 @@
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+
+int main (void)
+{
+  int exp = -1;
+  /* Wrong folding of the LHS to an unsigned MAX leads to 4294967295 > 2.  */
+  if ((exp < 2 ? 2U : (unsigned int) exp) != 2)
+    link_error ();
+  return 0;
+}