Commit dc575233 by Richard Guenther Committed by Richard Biener

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
parent 65567efa
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,
2007-10-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/33627
* g++.dg/torture/pr33627.C: New testcase.
2007-10-04 Tobias Schlter <tobi@gcc.gnu.org>
PR fortran/33626
/* { 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);
}
}
......@@ -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;
}
......@@ -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);
......
......@@ -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
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment