* [PATCH] Fix PR33627, invalid COND_EXPR_COND with ifcombine
@ 2007-10-04 9:34 Richard Guenther
0 siblings, 0 replies; only message in thread
From: Richard Guenther @ 2007-10-04 9:34 UTC (permalink / raw)
To: gcc-patches
This fixes ifcombine to canonicalize folded conditions appropriately
for COND_EXPR_COND (it somehow sucks that fold and verify_stmts don't
agree what is canonical here). Fortunately we went through this before
and so I split out a common function to do the work.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to mainline.
Richard.
2007-10-02 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.
Index: gcc/tree-gimple.h
===================================================================
*** gcc/tree-gimple.h (revision 128957)
--- gcc/tree-gimple.h (working copy)
*************** extern enum gimplify_status gimplify_va_
*** 133,138 ****
--- 133,139 ----
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);
Index: gcc/tree-gimple.c
===================================================================
*** gcc/tree-gimple.c (revision 128957)
--- gcc/tree-gimple.c (working copy)
*************** recalculate_side_effects (tree t)
*** 521,523 ****
--- 521,567 ----
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;
+ }
Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c (revision 128957)
--- gcc/tree-ssa-forwprop.c (working copy)
*************** combine_cond_expr_cond (enum tree_code c
*** 326,371 ****
/* 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));
! }
/* Bail out if we required an invariant but didn't get one. */
! if (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;
}
/* Propagate from the ssa name definition statements of COND_EXPR
--- 326,341 ----
/* Require that we got a boolean type out if we put one in. */
gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
! /* 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 (!t
! || (invariant_only
! && !is_gimple_min_invariant (t)))
return NULL_TREE;
! return t;
}
/* Propagate from the ssa name definition statements of COND_EXPR
Index: gcc/tree-ssa-ifcombine.c
===================================================================
*** gcc/tree-ssa-ifcombine.c (revision 128957)
--- gcc/tree-ssa-ifcombine.c (working copy)
*************** ifcombine_iforif (basic_block inner_cond
*** 483,488 ****
--- 483,491 ----
/* 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);
Index: gcc/testsuite/g++.dg/torture/pr33627.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr33627.C (revision 0)
--- gcc/testsuite/g++.dg/torture/pr33627.C (revision 0)
***************
*** 0 ****
--- 1,55 ----
+ 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);
+ }
+ }
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-10-04 9:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-04 9:34 [PATCH] Fix PR33627, invalid COND_EXPR_COND with ifcombine Richard Guenther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).