0d16b69
2007-11-12  Richard Guenther  <rguenther@suse.de>
0d16b69
0d16b69
	PR middle-end/34070
0d16b69
	* fold-const.c (fold_binary): If testing for non-negative
0d16b69
	operands with tree_expr_nonnegative_warnv_p make sure to
0d16b69
	use op0 which has all (sign) conversions retained.
0d16b69
0d16b69
	* gcc.c-torture/execute/pr34070-1.c: New testcase.
0d16b69
	* gcc.c-torture/execute/pr34070-2.c: Likewise.
0d16b69
0d16b69
--- gcc/fold-const.c	(revision 130097)
0d16b69
+++ gcc/fold-const.c	(revision 130098)
0d16b69
@@ -8509,7 +8509,7 @@ fold_binary (enum tree_code code, tree t
0d16b69
       /* Simplify A / (B << N) where A and B are positive and B is
0d16b69
 	 a power of 2, to A >> (N + log2(B)).  */
0d16b69
       if (TREE_CODE (arg1) == LSHIFT_EXPR
0d16b69
-	  && (TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (arg0)))
0d16b69
+	  && (TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (op0)))
0d16b69
 	{
0d16b69
 	  tree sval = TREE_OPERAND (arg1, 0);
0d16b69
 	  if (integer_pow2p (sval) && tree_int_cst_sgn (sval) > 0)
0d16b69
@@ -8584,7 +8584,7 @@ fold_binary (enum tree_code code, tree t
0d16b69
       /* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR,
0d16b69
          i.e. "X % C" into "X & (C - 1)", if X and C are positive.  */
0d16b69
       if ((code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR)
0d16b69
-	  && (TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (arg0)))
0d16b69
+	  && (TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (op0)))
0d16b69
 	{
0d16b69
 	  tree c = arg1;
0d16b69
 	  /* Also optimize A % (C << N)  where C is a power of 2,
0d16b69
--- gcc/testsuite/gcc.c-torture/execute/pr34070-1.c	(revision 0)
0d16b69
+++ gcc/testsuite/gcc.c-torture/execute/pr34070-1.c	(revision 130098)
0d16b69
@@ -0,0 +1,13 @@
0d16b69
+extern void abort (void);
0d16b69
+
0d16b69
+int f(unsigned int x)
0d16b69
+{
0d16b69
+    return ((int)x) % 4;
0d16b69
+}
0d16b69
+
0d16b69
+int main()
0d16b69
+{
0d16b69
+  if (f(-1) != -1)
0d16b69
+    abort ();
0d16b69
+  return 0;
0d16b69
+}
0d16b69
--- gcc/testsuite/gcc.c-torture/execute/pr34070-2.c	(revision 0)
0d16b69
+++ gcc/testsuite/gcc.c-torture/execute/pr34070-2.c	(revision 130098)
0d16b69
@@ -0,0 +1,13 @@
0d16b69
+extern void abort (void);
0d16b69
+
0d16b69
+int f(unsigned int x, int n)
0d16b69
+{
0d16b69
+    return ((int)x) / (1 << n);
0d16b69
+}
0d16b69
+
0d16b69
+int main()
0d16b69
+{
0d16b69
+  if (f(-1, 1) != 0)
0d16b69
+    abort ();
0d16b69
+  return 0;
0d16b69
+}