tree-vrp.c (range_fits_type_p): Require the MSB of the double_int to be clear for...
authorRichard Sandiford <rdsandiford@googlemail.com>
Wed, 2 Jan 2013 11:43:22 +0000 (11:43 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 2 Jan 2013 11:43:22 +0000 (11:43 +0000)
gcc/
* tree-vrp.c (range_fits_type_p): Require the MSB of the double_int
to be clear for sign changes.

gcc/testsuite/
* gcc.dg/torture/fp-int-convert-2.c: New test.

From-SVN: r194800

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/fp-int-convert-2.c [new file with mode: 0644]
gcc/tree-vrp.c

index f7b15c308b245daf33e8226b19b8528abf31612a..f686cf6718bb8c56b5914018597f8b93b490b932 100644 (file)
@@ -1,3 +1,8 @@
+2013-01-02  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * tree-vrp.c (range_fits_type_p): Require the MSB of the double_int
+       to be clear for sign changes.
+
 2013-01-01  Jan Hubicka  <jh@suse.cz>
 
        * ipa-inline-analysis.c: Fix formatting.
index 147b1c76e72a8e04b6eeb2f700e936277bd40985..faa12fd5a49046e9424a965db6987e0fe8503d06 100644 (file)
@@ -1,3 +1,7 @@
+2013-01-02  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * gcc.dg/torture/fp-int-convert-2.c: New test.
+
 2013-01-01  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        * gfortran.dg/newunit_3.f90: Add dg-do run.
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-2.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-2.c
new file mode 100644 (file)
index 0000000..4c00e8f
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int128 } */
+
+extern void abort (void);
+
+float __attribute__((noinline))
+f (__uint128_t x)
+{
+  return x + 1;
+}
+
+int
+main (void)
+{
+  if (f (0xffffffffu) == 0)
+    abort ();
+  return 0;
+}
index 4319c60802e83c20d4a032cfbbaf57a8009ec8db..6b8cbf38d847c46141c5ed591f2bb7472ae906ec 100644 (file)
@@ -8766,9 +8766,11 @@ range_fits_type_p (value_range_t *vr, unsigned precision, bool unsigned_p)
       || TREE_CODE (vr->max) != INTEGER_CST)
     return false;
 
-  /* For precision-preserving sign-changes the MSB of the double-int
-     has to be clear.  */
-  if (src_precision == precision
+  /* For sign changes, the MSB of the double_int has to be clear.
+     An unsigned value with its MSB set cannot be represented by
+     a signed double_int, while a negative value cannot be represented
+     by an unsigned double_int.  */
+  if (TYPE_UNSIGNED (src_type) != unsigned_p
       && (TREE_INT_CST_HIGH (vr->min) | TREE_INT_CST_HIGH (vr->max)) < 0)
     return false;