This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] Fix CCP bug exposed by 099.go
- From: law at redhat dot com
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 16 Sep 2003 17:46:24 -0600
- Subject: [tree-ssa] Fix CCP bug exposed by 099.go
- Reply-to: law at redhat dot com
This fixes a CCP bug exposed by 099.go. There's two underlying issues.
First, if a statement had virtual definitions and the first time we
simulated the statement we got either an UNDEFINED or CONSTANT result,
then we would fail to re-simulate the statement if its operands
changed. vdefs really don't tell us anything useful about the
result of the statement and the existence of vdefs shouldn't inhibit
re-simulation of an instruction.
Second, if we passed an undefined value as an argument to a function
call, then we considered the function call itself to produce an undefined
value. That is wrong. Just because we pass in an undefined value doesn't
mean the function actually uses the value. Function calls are immediately
assumed to produce VARYING results.
This makes 099.go from spec95 work again. Whee.
* tree-ssa-ccp.c (visit_stmt): Do not set DONT_SIMULATE_AGAIN
just because a statement as virtual definitions.
(likely_value): A CALL_EXPR is assumed to return a VARYING
result, regardless of its operands.
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.89
diff -c -3 -p -r1.1.2.89 tree-ssa-ccp.c
*** tree-ssa-ccp.c 16 Sep 2003 03:08:08 -0000 1.1.2.89
--- tree-ssa-ccp.c 16 Sep 2003 23:43:44 -0000
*************** visit_stmt (tree stmt)
*** 580,586 ****
ops = vdef_ops (stmt);
if (ops)
{
- DONT_SIMULATE_AGAIN (stmt) = 1;
for (i = 0; i < VARRAY_ACTIVE_SIZE (ops); i++)
def_to_varying (VDEF_RESULT (VARRAY_TREE (ops, i)));
}
--- 580,585 ----
*************** likely_value (tree stmt)
*** 1251,1256 ****
--- 1250,1266 ----
won't fold to a constant value. */
ann = stmt_ann (stmt);
if (ann->makes_aliased_loads || ann->has_volatile_ops)
+ return VARYING;
+
+ /* A CALL_EXPR is assumed to be varying. This may be overly conservative,
+ in the presence of const and pure calls. */
+ if (TREE_CODE (stmt) == CALL_EXPR
+ || (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
+ || (TREE_CODE (stmt) == RETURN_EXPR
+ && TREE_OPERAND (stmt, 0)
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (TREE_OPERAND (stmt, 0), 1)) == CALL_EXPR))
return VARYING;
get_stmt_operands (stmt);