[PATCH] Fix up extract_muldiv for NEGATE_EXPR (PR tree-optimization/56250)

Jakub Jelinek jakub@redhat.com
Fri Feb 8 14:20:00 GMT 2013


Hi!

As the testcase shows, treating (-something_unsigned) / c as
-(something_unsigned / c) is wrong for unsigned types, seems to be
fine for signed types even for -fwrapv and for multiplication
instead of / or % looks fine to me too.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2013-02-08  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/56250
	* fold-const.c (extract_muldiv_1) <case NEGATE_EXPR>: Don't optimize
	if type is unsigned and code isn't MULT_EXPR.

	* gcc.c-torture/execute/pr56250.c: New test.

--- gcc/fold-const.c.jj	2013-02-01 16:00:23.000000000 +0100
+++ gcc/fold-const.c	2013-02-08 11:58:07.063147647 +0100
@@ -5695,6 +5695,11 @@ extract_muldiv_1 (tree t, tree c, enum t
         break;
       /* FALLTHROUGH */
     case NEGATE_EXPR:
+      /* For division and modulus, type can't be unsigned, as e.g.
+	 (-(x / 2U)) / 2U isn't equal to -((x / 2U) / 2U) for x >= 2.
+	 For signed types, even with wrapping overflow, this is fine.  */
+      if (code != MULT_EXPR && TYPE_UNSIGNED (type))
+	break;
       if ((t1 = extract_muldiv (op0, c, code, wide_type, strict_overflow_p))
 	  != 0)
 	return fold_build1 (tcode, ctype, fold_convert (ctype, t1));
--- gcc/testsuite/gcc.c-torture/execute/pr56250.c.jj	2013-02-08 12:12:43.477013120 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr56250.c	2013-02-08 11:58:20.000000000 +0100
@@ -0,0 +1,13 @@
+/* PR tree-optimization/56250 */
+
+extern void abort (void);
+
+int
+main ()
+{
+  unsigned int x = 2;
+  unsigned int y = (0U - x / 2) / 2;
+  if (-1U / x != y)
+    abort ();
+  return 0;
+}

	Jakub



More information about the Gcc-patches mailing list