This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR43402: miscompile of libicu
- From: Michael Matz <matz at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Guenther <rguenther at suse dot de>
- Date: Wed, 17 Mar 2010 18:02:12 +0100 (CET)
- Subject: Fix PR43402: miscompile of libicu
Hi,
the fix for pr43186 made cfgcleanup look through single-argument PHI
nodes. That's fine except that during cfgcleanup we might have some SSA
names registered for update (we run update_ssa only after cfgcleanup). We
can't look through such SSA names.
This fixes the miscompile and still make pr43186 pass. Regstrapping on
x86_64 in progress, okay for trunk?
Ciao,
Michael.
--
PR tree-optimization/43402
* tree-cfgcleanup.c (cleanup_control_expr_graph): Don't follow
PHI chains of ssa names registered for update.
testsuite/
* gcc.dg/pr43402.c: New testcase.
Index: tree-cfgcleanup.c
===================================================================
--- tree-cfgcleanup.c (revision 157458)
+++ tree-cfgcleanup.c (working copy)
@@ -103,20 +103,28 @@ cleanup_control_expr_graph (basic_block
/* For conditions try harder and lookup single-argument
PHI nodes. Only do so from the same basic-block though
as other basic-blocks may be dead already. */
- if (TREE_CODE (lhs) == SSA_NAME)
+ if (TREE_CODE (lhs) == SSA_NAME
+ && !name_registered_for_update_p (lhs))
{
gimple def_stmt = SSA_NAME_DEF_STMT (lhs);
if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (def_stmt) == 1
- && gimple_bb (def_stmt) == gimple_bb (stmt))
+ && gimple_bb (def_stmt) == gimple_bb (stmt)
+ && (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
+ || !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
+ 0))))
lhs = PHI_ARG_DEF (def_stmt, 0);
}
- if (TREE_CODE (rhs) == SSA_NAME)
+ if (TREE_CODE (rhs) == SSA_NAME
+ && !name_registered_for_update_p (rhs))
{
gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (def_stmt) == 1
- && gimple_bb (def_stmt) == gimple_bb (stmt))
+ && gimple_bb (def_stmt) == gimple_bb (stmt)
+ && (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
+ || !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
+ 0))))
rhs = PHI_ARG_DEF (def_stmt, 0);
}
val = fold_binary_loc (loc, gimple_cond_code (stmt),
Index: testsuite/gcc.dg/pr43402.c
===================================================================
--- testsuite/gcc.dg/pr43402.c (revision 0)
+++ testsuite/gcc.dg/pr43402.c (revision 0)
@@ -0,0 +1,58 @@
+/* { dg-do run } */
+/* { dg-options "-O1 -fno-inline" } */
+extern void abort (void);
+
+static int something;
+
+static int * converterData[2]={
+ &something, &something,
+};
+
+static struct {
+ const char *name;
+ int type;
+} const cnvNameType[] = {
+ { "bocu1", 1 },
+ { "utf7", 1 },
+ { "utf8", 1 }
+};
+
+
+const int * getAlgorithmicTypeFromName(const char *realName);
+const int *
+getAlgorithmicTypeFromName(const char *realName)
+{
+ unsigned mid, start, limit;
+ unsigned lastMid;
+ int result;
+ start = 0;
+ limit = sizeof(cnvNameType)/sizeof(cnvNameType[0]);
+ mid = limit;
+ lastMid = 0xffffffff;
+
+ for (;;) {
+ mid = (start + limit) / 2;
+ if (lastMid == mid) { /* Have we moved? */
+ break; /* We haven't moved, and it wasn't found. */
+ }
+ lastMid = mid;
+ result = __builtin_strcmp(realName, cnvNameType[mid].name);
+
+ if (result < 0) {
+ limit = mid;
+ } else if (result > 0) {
+ start = mid;
+ } else {
+ return converterData[cnvNameType[mid].type];
+ }
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ if (!getAlgorithmicTypeFromName ("utf8"))
+ abort ();
+ return 0;
+}