This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/30840] [4.3 Regression] ice for legal code with flags -O3 -fno-strict-aliasing
- From: "rguenth at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 19 Feb 2007 11:31:47 -0000
- Subject: [Bug tree-optimization/30840] [4.3 Regression] ice for legal code with flags -O3 -fno-strict-aliasing
- References: <bug-30840-9596@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #4 from rguenth at gcc dot gnu dot org 2007-02-19 11:31 -------
It seems to be a problem with ssa-edge simulation ordering. We have
# SMT.6_95 = VDEF <SMT.6_60>
# SMT.8_96 = VDEF <SMT.8_70>
this_22->firstfree = D.2527_46;
in particular, adding only the first output to simulate
/* Note that for propagation purposes, we are only interested in
visiting statements that load the exact same memory reference
stored here. Those statements will have the exact same list
of virtual uses, so it is enough to set the output of this
statement to be its first virtual definition. */
*output_p = first_vdef (stmt);
if (changed)
{
if (val.lattice_val == VARYING)
retval = SSA_PROP_VARYING;
will cause a missed propagation of the new lattice value to PHI results.
Another point is that get_value_loaded_by will return NULL for the two
VOPs where one has a CONSTANT and one a VARYING value and so we'll call
evaluate_stmt on the stmt which will return UNDEFINED which causes us to
go back from VARYING to UNDEFINED. Boom.
Sth. like the following fixes it (note 'VARYING' is unknown to
tree-ssa-propagate.c):
Index: tree-ssa-propagate.c
===================================================================
*** tree-ssa-propagate.c (revision 122127)
--- tree-ssa-propagate.c (working copy)
*************** get_value_loaded_by (tree stmt, prop_val
*** 835,850 ****
tree vuse;
prop_value_t *prev_val = NULL;
prop_value_t *val = NULL;
FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, i, SSA_OP_VIRTUAL_USES)
{
val = &values[SSA_NAME_VERSION (vuse)];
if (prev_val && prev_val->value != val->value)
! return NULL;
! prev_val = val;
}
! return val;
}
--- 841,860 ----
tree vuse;
prop_value_t *prev_val = NULL;
prop_value_t *val = NULL;
+ bool valid = true;
+ /* Make sure to set the result to varying if any of the operands is
+ varying. */
FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, i, SSA_OP_VIRTUAL_USES)
{
val = &values[SSA_NAME_VERSION (vuse)];
if (prev_val && prev_val->value != val->value)
! valid = false;
! if (!prev_val || prev_val->lattice_val < val->lattice_val)
! prev_val = val;
}
! return (valid || prev_val->lattice_val == 3) ? prev_val : NULL;
}
Index: tree-ssa-ccp.c
===================================================================
*** tree-ssa-ccp.c (revision 122127)
--- tree-ssa-ccp.c (working copy)
*************** visit_assignment (tree stmt, tree *outpu
*** 1208,1215 ****
prop_value_t *nval = get_value_loaded_by (stmt, const_val);
if (nval
! && nval->mem_ref
! && operand_equal_p (nval->mem_ref, rhs, 0))
val = *nval;
else
val = evaluate_stmt (stmt);
--- 1208,1216 ----
prop_value_t *nval = get_value_loaded_by (stmt, const_val);
if (nval
! && ((nval->mem_ref
! && operand_equal_p (nval->mem_ref, rhs, 0))
! || nval->lattice_val == VARYING))
val = *nval;
else
val = evaluate_stmt (stmt);
--
rguenth at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |dnovillo at redhat dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30840