aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-01-04 13:25:28 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-01-04 13:25:28 +0000
commitf5a3d840b627810a521d15c4144cb5da721d9718 (patch)
tree1a1582548b6899bb4dc7ba44390c5312e814253b /gcc
parent299c4b5f8853aa54f17ed38602aced0af0f5b503 (diff)
downloadgcc-f5a3d840b627810a521d15c4144cb5da721d9718.zip
gcc-f5a3d840b627810a521d15c4144cb5da721d9718.tar.gz
gcc-f5a3d840b627810a521d15c4144cb5da721d9718.tar.bz2
re PR middle-end/51750 (FAIL: 25_algorithms/heap/moveable*.cc execution test)
2012-01-04 Richard Guenther <rguenther@suse.de> PR middle-end/51750 * tree.c (size_low_cst): New function. * tree.h (size_low_cst): Declare. * fold-const.c (fold_comparison): Use it to extract the low part of the POINTER_PLUS_EXPR offset. From-SVN: r182872
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/fold-const.c30
-rw-r--r--gcc/tree.c11
-rw-r--r--gcc/tree.h1
4 files changed, 38 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e34cfa0..33caab1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2012-01-04 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/51750
+ * tree.c (size_low_cst): New function.
+ * tree.h (size_low_cst): Declare.
+ * fold-const.c (fold_comparison): Use it to extract the low
+ part of the POINTER_PLUS_EXPR offset.
+
2012-01-04 Georg-Johann Lay <avr@gjlay.de>
Fix clearing ZERO_REG
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index b88b5d7..40a0986 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8886,13 +8886,16 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
indirect_base0 = true;
}
offset0 = TREE_OPERAND (arg0, 1);
- if (host_integerp (offset0, 0)
- && ((HOST_WIDE_INT) (TREE_INT_CST_LOW (offset0) * BITS_PER_UNIT)
- / BITS_PER_UNIT
- == (HOST_WIDE_INT) TREE_INT_CST_LOW (offset0)))
+ if (host_integerp (offset0, 0))
{
- bitpos0 = TREE_INT_CST_LOW (offset0) * BITS_PER_UNIT;
- offset0 = NULL_TREE;
+ HOST_WIDE_INT off = size_low_cst (offset0);
+ if ((HOST_WIDE_INT) (((unsigned HOST_WIDE_INT) off)
+ * BITS_PER_UNIT)
+ / BITS_PER_UNIT == (HOST_WIDE_INT) off)
+ {
+ bitpos0 = off * BITS_PER_UNIT;
+ offset0 = NULL_TREE;
+ }
}
}
@@ -8917,13 +8920,16 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
indirect_base1 = true;
}
offset1 = TREE_OPERAND (arg1, 1);
- if (host_integerp (offset1, 0)
- && ((HOST_WIDE_INT) (TREE_INT_CST_LOW (offset1) * BITS_PER_UNIT)
- / BITS_PER_UNIT
- == (HOST_WIDE_INT) TREE_INT_CST_LOW (offset1)))
+ if (host_integerp (offset1, 0))
{
- bitpos1 = TREE_INT_CST_LOW (offset1) * BITS_PER_UNIT;
- offset1 = NULL_TREE;
+ HOST_WIDE_INT off = size_low_cst (offset1);
+ if ((HOST_WIDE_INT) (((unsigned HOST_WIDE_INT) off)
+ * BITS_PER_UNIT)
+ / BITS_PER_UNIT == (HOST_WIDE_INT) off)
+ {
+ bitpos1 = off * BITS_PER_UNIT;
+ offset1 = NULL_TREE;
+ }
}
}
diff --git a/gcc/tree.c b/gcc/tree.c
index d7bbae3..76488f7 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -6509,6 +6509,17 @@ tree_low_cst (const_tree t, int pos)
return TREE_INT_CST_LOW (t);
}
+/* Return the HOST_WIDE_INT least significant bits of T, a sizetype
+ kind INTEGER_CST. This makes sure to properly sign-extend the
+ constant. */
+
+HOST_WIDE_INT
+size_low_cst (const_tree t)
+{
+ double_int d = tree_to_double_int (t);
+ return double_int_sext (d, TYPE_PRECISION (TREE_TYPE (t))).low;
+}
+
/* Return the most significant (sign) bit of T. */
int
diff --git a/gcc/tree.h b/gcc/tree.h
index 7a0046b..2ea03a0 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4428,6 +4428,7 @@ tree_low_cst (const_tree t, int pos)
return TREE_INT_CST_LOW (t);
}
#endif
+extern HOST_WIDE_INT size_low_cst (const_tree);
extern int tree_int_cst_sgn (const_tree);
extern int tree_int_cst_sign_bit (const_tree);
extern unsigned int tree_int_cst_min_precision (tree, bool);