re PR tree-optimization/57124 (254.gap@spec2000 got miscompare after r198413)
authorJeff Law <law@redhat.com>
Fri, 24 May 2013 17:13:38 +0000 (11:13 -0600)
committerJeff Law <law@gcc.gnu.org>
Fri, 24 May 2013 17:13:38 +0000 (11:13 -0600)
PR tree-optimization/57124
* tree-vrp.c (simplify_cond_using_ranges): Only simplify a
conversion feeding a condition if the range has an overflow
if -fstrict-overflow.  Add warnings for when we do make the
transformation.

PR tree-optimization/57124
* gcc.c-torture/execute/pr57124.c: New test.
* gcc.c-torture/execute/pr57124.x: Set -fno-strict-overflow.

From-SVN: r199305

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr57124.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr57124.x [new file with mode: 0644]
gcc/tree-vrp.c

index f5cffee34cc3078aaa35af0917006ed7d933d289..3d665c3d9d9c1acd58e2c80d49969d73b272e0a1 100644 (file)
@@ -1,3 +1,11 @@
+2013-05-24  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/57124
+       * tree-vrp.c (simplify_cond_using_ranges): Only simplify a
+       conversion feeding a condition if the range has an overflow
+       if -fstrict-overflow.  Add warnings for when we do make the
+       transformation.
+
 2013-05-24  Dehao Chen  <dehao@google.com>
 
        * gcc/tree-cfg.c (locus_discrim_map): Fix the typo.
index af4b16e2f11720e8e4f862133924d5831a80e8bc..8c2e2939561d958bf3a989d654d94f5c37610346 100644 (file)
@@ -1,3 +1,9 @@
+2013-05-24  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/57124
+       * gcc.c-torture/execute/pr57124.c: New test.
+       * gcc.c-torture/execute/pr57124.x: Set -fno-strict-overflow.
+
 2013-05-24  Martin Jambor  <mjambor@suse.cz>
 
        PR tree-optimization/57294
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57124.c b/gcc/testsuite/gcc.c-torture/execute/pr57124.c
new file mode 100644 (file)
index 0000000..835d249
--- /dev/null
@@ -0,0 +1,27 @@
+__attribute__ ((noinline))
+foo(short unsigned int *p1, short unsigned int *p2)
+{
+  short unsigned int x1, x4;
+  int x2, x3, x5, x6;
+  unsigned int x7;
+  
+  x1 = *p1;
+  x2 = (int) x1;
+  x3 = x2 * 65536;
+  x4 = *p2;
+  x5 = (int) x4;
+  x6 = x3 + x4;
+  x7 = (unsigned int) x6;
+  if (x7 <= 268435455U)
+    abort ();
+  exit (0);
+}
+
+main()
+{
+  short unsigned int x, y;
+  x = -5;
+  y = -10;
+  foo (&x, &y);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57124.x b/gcc/testsuite/gcc.c-torture/execute/pr57124.x
new file mode 100644 (file)
index 0000000..d8cacbe
--- /dev/null
@@ -0,0 +1,2 @@
+set additional_flags "-fno-strict-overflow"
+return 0
index 66c50ca4b310d8b9284f0f9b33db87b2d625797c..ec7ef8f754858f7bb059d6a8528485323fa68cde 100644 (file)
@@ -8670,8 +8670,32 @@ simplify_cond_using_ranges (gimple stmt)
              && range_fits_type_p (vr,
                                    TYPE_PRECISION (TREE_TYPE (op0)),
                                    TYPE_UNSIGNED (TREE_TYPE (op0)))
-             && int_fits_type_p (op1, TREE_TYPE (innerop)))
+             && int_fits_type_p (op1, TREE_TYPE (innerop))
+             /* The range must not have overflowed, or if it did overflow
+                we must not be wrapping/trapping overflow and optimizing
+                with strict overflow semantics.  */
+             && ((!is_negative_overflow_infinity (vr->min)
+                  && !is_positive_overflow_infinity (vr->max))
+                 || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (innerop))))
            {
+             /* If the range overflowed and the user has asked for warnings
+                when strict overflow semantics were used to optimize code,
+                issue an appropriate warning.  */
+             if ((is_negative_overflow_infinity (vr->min)
+                  || is_positive_overflow_infinity (vr->max))
+                 && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_CONDITIONAL))
+               {
+                 location_t location;
+
+                 if (!gimple_has_location (stmt))
+                   location = input_location;
+                 else
+                   location = gimple_location (stmt);
+                 warning_at (location, OPT_Wstrict_overflow,
+                     "assuming signed overflow does not occur when "
+                     "simplifying conditional");
+               }
+
              tree newconst = fold_convert (TREE_TYPE (innerop), op1);
              gimple_cond_set_lhs (stmt, innerop);
              gimple_cond_set_rhs (stmt, newconst);