This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Bug tree-optimization/32461] [4.3 Regression] Segmentation fault in build_classic_dist_vector_1() at tree-data-ref.c:2700
On 6/24/07, Richard Guenther <richard.guenther@gmail.com> wrote:
An alternative is to use
if (TREE_CODE (arg1) == BIT_NOT_EXPR
&& !TYPE_OVERFLOW_TRAPS (type))
{
tem = TREE_OPERAND (arg1, 0);
STRIP_NOPS (tem);
if (operand_equal_p (arg0, tem, 0))
...
which would be even better and shouldn't cause other missed
optimizations.
Okay, attached is the patch that implements this.
I'm bootstrapping and testing it on i686-linux.
Sebastian
2007-06-24 Sebastian Pop <sebpop@gmail.com>
PR middle-end/32461
* fold-const.c (fold_binary): Strip nops of operand 0
of BIT_NOT_EXPR before calling operand_equal_p.
* testsuite/gcc.dg/tree-ssa/pr32461-1.c: New.
* testsuite/gcc.dg/tree-ssa/pr32461-2.c: New.
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c (revision 125970)
+++ gcc/fold-const.c (working copy)
@@ -9260,21 +9260,31 @@ fold_binary (enum tree_code code, tree t
/* ~X + X is -1. */
if (TREE_CODE (arg0) == BIT_NOT_EXPR
- && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
&& !TYPE_OVERFLOW_TRAPS (type))
{
- t1 = build_int_cst_type (type, -1);
- return omit_one_operand (type, t1, arg1);
+ tree tem = TREE_OPERAND (arg0, 0);
+
+ STRIP_NOPS (tem);
+ if (operand_equal_p (tem, arg1, 0))
+ {
+ t1 = build_int_cst_type (type, -1);
+ return omit_one_operand (type, t1, arg1);
+ }
}
/* X + ~X is -1. */
if (TREE_CODE (arg1) == BIT_NOT_EXPR
- && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)
&& !TYPE_OVERFLOW_TRAPS (type))
{
- t1 = build_int_cst_type (type, -1);
- return omit_one_operand (type, t1, arg0);
- }
+ tree tem = TREE_OPERAND (arg1, 0);
+
+ STRIP_NOPS (tem);
+ if (operand_equal_p (arg0, tem, 0))
+ {
+ t1 = build_int_cst_type (type, -1);
+ return omit_one_operand (type, t1, arg0);
+ }
+ }
/* If we are adding two BIT_AND_EXPR's, both of which are and'ing
with a constant, and the two constants have no bits in common,
Index: gcc/testsuite/gcc.dg/tree-ssa/pr32461-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr32461-2.c (revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr32461-2.c (revision 0)
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+typedef struct
+{
+ unsigned char exp[256];
+}
+expbap_t;
+
+void
+a52_bit_allocate (expbap_t * expbap)
+{
+ int i;
+ unsigned char *exp = expbap->exp;
+ int lowcomp;
+
+ do
+ {
+ if (exp[i + 1] == exp[i] - 2)
+ lowcomp = 384;
+ else if (lowcomp && (exp[i + 1] > exp[i]))
+ lowcomp -= 64;
+ i++;
+ }
+ while ((i < 3) || ((i < 7) && (exp[i] > exp[i - 1])));
+}
Index: gcc/testsuite/gcc.dg/tree-ssa/pr32461-1.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr32461-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr32461-1.c (revision 0)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+typedef struct
+{
+ unsigned exp[256];
+}
+expbap_t;
+
+void
+a52_bit_allocate (expbap_t * expbap)
+{
+ int i;
+ unsigned *exp = expbap->exp;
+ char *bap;
+
+ while (i < 3 || exp[i] > exp[i - 1]);
+
+ do {
+ if (exp[i + 1] == exp[i])
+ bap[i] = 0;
+ i++;
+ } while (i < 20);
+}