+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 Schlüter <tobi@gcc.gnu.org>
PR fortran/33626
--- /dev/null
+/* { 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);
+ }
+}
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;
+}
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);
/* 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
/* 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);