diff options
author | Richard Guenther <rguenther@suse.de> | 2007-10-04 09:37:04 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2007-10-04 09:37:04 +0000 |
commit | dc5752338ba869ec407f1d97b0d47793be431239 (patch) | |
tree | e796856d793e5691b916e4fbbedc157a8e3dce8b /gcc | |
parent | 65567efaa82178fcfe63bee2c81f06a541cd72a4 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr33627.C | 57 | ||||
-rw-r--r-- | gcc/tree-gimple.c | 44 | ||||
-rw-r--r-- | gcc/tree-gimple.h | 1 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 42 | ||||
-rw-r--r-- | gcc/tree-ssa-ifcombine.c | 3 |
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); |