]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/33627 (ICE in verify_stmts compiling abiword)
authorRichard Guenther <rguenther@suse.de>
Thu, 4 Oct 2007 09:37:04 +0000 (09:37 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 4 Oct 2007 09:37:04 +0000 (09:37 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr33627.C [new file with mode: 0644]
gcc/tree-gimple.c
gcc/tree-gimple.h
gcc/tree-ssa-forwprop.c
gcc/tree-ssa-ifcombine.c

index 1b4731d95a044b0b4fbaffd0371e61e39425f867..c6d6a848ea50231f29832e6495f03ba9f88075f5 100644 (file)
@@ -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, 
index dc740322949c962ddceabf2a07cce7f9dd5bc0c8..cd6596ef763aa9e86f7fc0d62de5c6aca3cce618 100644 (file)
@@ -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 (file)
index 0000000..a14e345
--- /dev/null
@@ -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);
+  }
+}
index 8e976e201fef594a5ede683c6a4c57c8f058afab..7b29812294e362ae1e8dd1951e916e58891dcea2 100644 (file)
@@ -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;
+}
index 09182d725cf1b32333b717c153508fd6fc2b6ff9..2493b6b24198a52585268129db3a3addc3ee9698 100644 (file)
@@ -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);
index 60e6ffa9e62512e1442ecb05325bcd245f4b03bd..3b72b6c44af8b40296e8ef691b504ff9a59508dc 100644 (file)
@@ -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
index f52585ca20e8d89ec06df272d40f736722b2dba5..eef6f22d2a29fd0fc2f7bddea6f3bae8f95266f6 100644 (file)
@@ -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);