aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-12-05 23:24:08 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2007-12-05 23:24:08 +0100
commit517ddae96b847521c7761f74bb9ac522ed70f038 (patch)
treed91874c1661fc111f66e2b41c03740a7db664cb9
parente8608df46e1f096a942e0fff741fcdf2d9120df0 (diff)
downloadgcc-517ddae96b847521c7761f74bb9ac522ed70f038.zip
gcc-517ddae96b847521c7761f74bb9ac522ed70f038.tar.gz
gcc-517ddae96b847521c7761f74bb9ac522ed70f038.tar.bz2
re PR middle-end/34337 (Internal error while building gtkwhiteboardc.c from pidgin 2.3.0)
PR middle-end/34337 * fold-const.c (fold_binary) <case BIT_IOR_EXPR>: Don't minimize number of bits set in C1 if a mode mask for some mode can be used instead. * gcc.c-torture/execute/20071205-1.c: New test. From-SVN: r130635
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c31
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20071205-1.c17
4 files changed, 54 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index da6a6c3..189286b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2007-12-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/34337
+ * fold-const.c (fold_binary) <case BIT_IOR_EXPR>: Don't minimize
+ number of bits set in C1 if a mode mask for some mode can be used
+ instead.
+
2007-12-05 Bernhard Fischer <aldot@gcc.gnu.org>
* varasm.c (merge_weak, weak_finish, assemble_alias): Commentary typo
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 1502994..8519e68 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10570,8 +10570,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& TREE_CODE (arg1) == INTEGER_CST
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
{
- unsigned HOST_WIDE_INT hi1, lo1, hi2, lo2, mlo, mhi;
- int width = TYPE_PRECISION (type);
+ unsigned HOST_WIDE_INT hi1, lo1, hi2, lo2, hi3, lo3, mlo, mhi;
+ int width = TYPE_PRECISION (type), w;
hi1 = TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1));
lo1 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1));
hi2 = TREE_INT_CST_HIGH (arg1);
@@ -10599,16 +10599,35 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
return fold_build2 (BIT_IOR_EXPR, type,
TREE_OPERAND (arg0, 0), arg1);
- /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2. */
+ /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2,
+ unless (C1 & ~C2) | (C2 & C3) for some C3 is a mask of some
+ mode which allows further optimizations. */
hi1 &= mhi;
lo1 &= mlo;
- if ((hi1 & ~hi2) != hi1 || (lo1 & ~lo2) != lo1)
+ hi2 &= mhi;
+ lo2 &= mlo;
+ hi3 = hi1 & ~hi2;
+ lo3 = lo1 & ~lo2;
+ for (w = BITS_PER_UNIT;
+ w <= width && w <= HOST_BITS_PER_WIDE_INT;
+ w <<= 1)
+ {
+ unsigned HOST_WIDE_INT mask
+ = (unsigned HOST_WIDE_INT) -1 >> (HOST_BITS_PER_WIDE_INT - w);
+ if (((lo1 | lo2) & mask) == mask
+ && (lo1 & ~mask) == 0 && hi1 == 0)
+ {
+ hi3 = 0;
+ lo3 = mask;
+ break;
+ }
+ }
+ if (hi3 != hi1 || lo3 != lo1)
return fold_build2 (BIT_IOR_EXPR, type,
fold_build2 (BIT_AND_EXPR, type,
TREE_OPERAND (arg0, 0),
build_int_cst_wide (type,
- lo1 & ~lo2,
- hi1 & ~hi2)),
+ lo3, hi3)),
arg1);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1acb944..70aa1df 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-12-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/34337
+ * gcc.c-torture/execute/20071205-1.c: New test.
+
2007-12-05 Kaz Kojima <kkojima@gcc.gnu.org>
* gfortran.dg/module_nan.f90: Add -mieee for sh.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20071205-1.c b/gcc/testsuite/gcc.c-torture/execute/20071205-1.c
new file mode 100644
index 0000000..fa19ec0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20071205-1.c
@@ -0,0 +1,17 @@
+/* PR middle-end/34337 */
+
+extern void abort (void);
+
+int
+foo (int x)
+{
+ return ((x << 8) & 65535) | 255;
+}
+
+int
+main (void)
+{
+ if (foo (0x32) != 0x32ff || foo (0x174) != 0x74ff)
+ abort ();
+ return 0;
+}