aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2007-10-04 09:37:04 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2007-10-04 09:37:04 +0000
commitdc5752338ba869ec407f1d97b0d47793be431239 (patch)
treee796856d793e5691b916e4fbbedc157a8e3dce8b /gcc
parent65567efaa82178fcfe63bee2c81f06a541cd72a4 (diff)
downloadgcc-dc5752338ba869ec407f1d97b0d47793be431239.zip
gcc-dc5752338ba869ec407f1d97b0d47793be431239.tar.gz
gcc-dc5752338ba869ec407f1d97b0d47793be431239.tar.bz2
re PR tree-optimization/33627 (ICE in verify_stmts compiling abiword)
2007-10-04 Richard Guenther <rguenther@suse.de> PR tree-optimization/33627 * tree-gimple.h (canonicalize_cond_expr_cond): Declare. * tree-gimple.c (canonicalize_cond_expr_cond): New function, split out from ... * tree-ssa-forwprop.c (combine_cond_expr_cond): ... here. * tree-ssa-ifcombine.c (ifcombine_iforif): Use it. * g++.dg/torture/pr33627.C: New testcase. From-SVN: r129004
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr33627.C57
-rw-r--r--gcc/tree-gimple.c44
-rw-r--r--gcc/tree-gimple.h1
-rw-r--r--gcc/tree-ssa-forwprop.c42
-rw-r--r--gcc/tree-ssa-ifcombine.c3
7 files changed, 125 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1b4731d..c6d6a84 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2007-10-04 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/33627
+ * tree-gimple.h (canonicalize_cond_expr_cond): Declare.
+ * tree-gimple.c (canonicalize_cond_expr_cond): New function,
+ split out from ...
+ * tree-ssa-forwprop.c (combine_cond_expr_cond): ... here.
+ * tree-ssa-ifcombine.c (ifcombine_iforif): Use it.
+
2007-10-04 Anatoly Sokolov <aesok@post.ru>
* config/avr/avr.c (commands_in_file, commands_in_prologues,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dc74032..cd6596e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-10-04 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/33627
+ * g++.dg/torture/pr33627.C: New testcase.
+
2007-10-04 Tobias Schlüter <tobi@gcc.gnu.org>
PR fortran/33626
diff --git a/gcc/testsuite/g++.dg/torture/pr33627.C b/gcc/testsuite/g++.dg/torture/pr33627.C
new file mode 100644
index 0000000..a14e345
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr33627.C
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+
+typedef unsigned int UT_uint32;
+typedef UT_uint32 PT_DocPosition;
+typedef UT_uint32 PT_BlockOffset;
+typedef enum _PTStruxType { PTX_Block } PTStruxType;
+typedef UT_uint32 PL_ListenerId;
+typedef const void * PL_StruxFmtHandle;
+class PX_ChangeRecord;
+class pf_Frag {
+ public:
+ typedef enum _PFType { PFT_Object } PFType;
+ inline PFType getType(void) const { }
+ inline pf_Frag * getNext(void) const { }
+ PT_DocPosition getPos(void) const { }
+};
+class pf_Fragments {
+ public:
+ pf_Frag * getFirst() const;
+};
+class pt_PieceTable {
+ bool getStruxOfTypeFromPosition(PL_ListenerId listenerId, PT_DocPosition docPos, PTStruxType pts, PL_StruxFmtHandle * psfh) const;
+ bool _tellAndMaybeAddListener(PL_ListenerId listenerId, bool bAdd);
+ pf_Fragments m_fragments;
+};
+class pf_Frag_Object : public pf_Frag
+{
+ public:
+ virtual bool createSpecialChangeRecord(PX_ChangeRecord ** ppcr, PT_DocPosition dpos, PT_BlockOffset blockOffset) const;
+};
+bool pt_PieceTable::_tellAndMaybeAddListener(PL_ListenerId listenerId, bool bAdd)
+{
+ PL_StruxFmtHandle sfh = 0;
+ PT_DocPosition sum = 0;
+ UT_uint32 blockOffset = 0;
+ for (pf_Frag * pf = m_fragments.getFirst(); (pf); pf=pf->getNext())
+ {
+ pf_Frag_Object * pfo = static_cast<pf_Frag_Object *> (pf);
+ PX_ChangeRecord * pcr = __null;
+ bool bStatus1 = false;
+ if(sfh != __null) {
+ bStatus1 = pfo->createSpecialChangeRecord(&pcr,sum,blockOffset);
+ if (!(bStatus1))
+ return (false);
+ }
+ else
+ {
+ PT_DocPosition pos = pf->getPos();
+ getStruxOfTypeFromPosition(listenerId,pos,PTX_Block,&sfh);
+ bStatus1 = pfo->createSpecialChangeRecord(&pcr,pos,blockOffset);
+ if (!(bStatus1))
+ return (false);
+ }
+ if (!(bStatus1))
+ return (false);
+ }
+}
diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c
index 8e976e2..7b29812 100644
--- a/gcc/tree-gimple.c
+++ b/gcc/tree-gimple.c
@@ -521,3 +521,47 @@ recalculate_side_effects (tree t)
gcc_unreachable ();
}
}
+
+/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns
+ a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
+ we failed to create one. */
+
+tree
+canonicalize_cond_expr_cond (tree t)
+{
+ /* For (bool)x use x != 0. */
+ if (TREE_CODE (t) == NOP_EXPR
+ && TREE_TYPE (t) == boolean_type_node)
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (NE_EXPR, TREE_TYPE (t),
+ top0, build_int_cst (TREE_TYPE (top0), 0));
+ }
+ /* For !x use x == 0. */
+ else if (TREE_CODE (t) == TRUTH_NOT_EXPR)
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (EQ_EXPR, TREE_TYPE (t),
+ top0, build_int_cst (TREE_TYPE (top0), 0));
+ }
+ /* For cmp ? 1 : 0 use cmp. */
+ else if (TREE_CODE (t) == COND_EXPR
+ && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
+ && integer_onep (TREE_OPERAND (t, 1))
+ && integer_zerop (TREE_OPERAND (t, 2)))
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (TREE_CODE (top0), TREE_TYPE (t),
+ TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
+ }
+
+ /* A valid conditional for a COND_EXPR is either a gimple value
+ or a comparison with two gimple value operands. */
+ if (is_gimple_val (t)
+ || (COMPARISON_CLASS_P (t)
+ && is_gimple_val (TREE_OPERAND (t, 0))
+ && is_gimple_val (TREE_OPERAND (t, 1))))
+ return t;
+
+ return NULL_TREE;
+}
diff --git a/gcc/tree-gimple.h b/gcc/tree-gimple.h
index 09182d7..2493b6b 100644
--- a/gcc/tree-gimple.h
+++ b/gcc/tree-gimple.h
@@ -133,6 +133,7 @@ extern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
struct gimplify_omp_ctx;
extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
extern tree gimple_boolify (tree);
+extern tree canonicalize_cond_expr_cond (tree);
/* In omp-low.c. */
extern void diagnose_omp_structured_block_errors (tree);
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 60e6ffa..3b72b6c 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -326,46 +326,16 @@ combine_cond_expr_cond (enum tree_code code, tree type,
/* Require that we got a boolean type out if we put one in. */
gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
- /* For (bool)x use x != 0. */
- if (TREE_CODE (t) == NOP_EXPR
- && TREE_TYPE (t) == boolean_type_node)
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (NE_EXPR, type,
- top0, build_int_cst (TREE_TYPE (top0), 0));
- }
- /* For !x use x == 0. */
- else if (TREE_CODE (t) == TRUTH_NOT_EXPR)
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (EQ_EXPR, type,
- top0, build_int_cst (TREE_TYPE (top0), 0));
- }
- /* For cmp ? 1 : 0 use cmp. */
- else if (TREE_CODE (t) == COND_EXPR
- && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
- && integer_onep (TREE_OPERAND (t, 1))
- && integer_zerop (TREE_OPERAND (t, 2)))
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (TREE_CODE (top0), type,
- TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
- }
+ /* Canonicalize the combined condition for use in a COND_EXPR. */
+ t = canonicalize_cond_expr_cond (t);
/* Bail out if we required an invariant but didn't get one. */
- if (invariant_only
- && !is_gimple_min_invariant (t))
+ if (!t
+ || (invariant_only
+ && !is_gimple_min_invariant (t)))
return NULL_TREE;
- /* A valid conditional for a COND_EXPR is either a gimple value
- or a comparison with two gimple value operands. */
- if (is_gimple_val (t)
- || (COMPARISON_CLASS_P (t)
- && is_gimple_val (TREE_OPERAND (t, 0))
- && is_gimple_val (TREE_OPERAND (t, 1))))
- return t;
-
- return NULL_TREE;
+ return t;
}
/* Propagate from the ssa name definition statements of COND_EXPR
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index f52585c..eef6f22 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -483,6 +483,9 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
/* Do it. */
t = fold_build2 (code, boolean_type_node,
TREE_OPERAND (ccond2, 0), TREE_OPERAND (ccond2, 1));
+ t = canonicalize_cond_expr_cond (t);
+ if (!t)
+ return false;
COND_EXPR_COND (inner_cond) = t;
update_stmt (inner_cond);