This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR23329
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 3 May 2009 21:52:55 +0200 (CEST)
- Subject: [PATCH] Fix PR23329
This fixes PR23329 - duplicate code in may_propagate_copy which
already checks for type compatibility which in turn checks alias
compatibility. It also makes useless_type_conversion_p_1
properly use get_deref_alias_set thus the TYPE_REF_CAN_ALIAS_ALL
check is redundant. Which in turn shows that the C FEs
compatibility of int[10] with int[] is bogus for the middle-end,
thus we have to retain conversions from T[] to T[n].
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
2009-05-03 Richard Guenther <rguenther@suse.de>
PR middle-end/23329
* tree-ssa.c (useless_type_conversion_p_1): Use get_deref_alias_set.
Do not lose casts from array types with unknown extent to array
types with known extent.
* tree-ssa-copy.c (may_propagate_copy): Remove hack checking for
alias set compatibility.
Index: gcc/tree-ssa-copy.c
===================================================================
*** gcc/tree-ssa-copy.c (revision 147065)
--- gcc/tree-ssa-copy.c (working copy)
*************** may_propagate_copy (tree dest, tree orig
*** 78,132 ****
if (!useless_type_conversion_p (type_d, type_o))
return false;
- /* FIXME. GIMPLE is allowing pointer assignments and comparisons of
- pointers that have different alias sets. This means that these
- pointers will have different memory tags associated to them.
-
- If we allow copy propagation in these cases, statements de-referencing
- the new pointer will now have a reference to a different memory tag
- with potentially incorrect SSA information.
-
- This was showing up in libjava/java/util/zip/ZipFile.java with code
- like:
-
- struct java.io.BufferedInputStream *T.660;
- struct java.io.BufferedInputStream *T.647;
- struct java.io.InputStream *is;
- struct java.io.InputStream *is.662;
- [ ... ]
- T.660 = T.647;
- is = T.660; <-- This ought to be type-casted
- is.662 = is;
-
- Also, f/name.c exposed a similar problem with a COND_EXPR predicate
- that was causing DOM to generate and equivalence with two pointers of
- alias-incompatible types:
-
- struct _ffename_space *n;
- struct _ffename *ns;
- [ ... ]
- if (n == ns)
- goto lab;
- ...
- lab:
- return n;
-
- I think that GIMPLE should emit the appropriate type-casts. For the
- time being, blocking copy-propagation in these cases is the safe thing
- to do. */
- if (TREE_CODE (dest) == SSA_NAME
- && TREE_CODE (orig) == SSA_NAME
- && POINTER_TYPE_P (type_d)
- && POINTER_TYPE_P (type_o))
- {
- if (get_alias_set (TREE_TYPE (type_d))
- != get_alias_set (TREE_TYPE (type_o)))
- return false;
- else if (DECL_NO_TBAA_P (SSA_NAME_VAR (dest))
- != DECL_NO_TBAA_P (SSA_NAME_VAR (orig)))
- return false;
- }
-
/* Propagating virtual operands is always ok. */
if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
{
--- 78,83 ----
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c (revision 147076)
--- gcc/tree-ssa.c (working copy)
*************** useless_type_conversion_p_1 (tree outer_
*** 961,972 ****
&& TYPE_VOLATILE (TREE_TYPE (outer_type)))
return false;
! /* Do not lose casts between pointers with different
! TYPE_REF_CAN_ALIAS_ALL setting or alias sets. */
! if ((TYPE_REF_CAN_ALIAS_ALL (inner_type)
! != TYPE_REF_CAN_ALIAS_ALL (outer_type))
! || (get_alias_set (TREE_TYPE (inner_type))
! != get_alias_set (TREE_TYPE (outer_type))))
return false;
/* We do not care for const qualification of the pointed-to types
--- 961,969 ----
&& TYPE_VOLATILE (TREE_TYPE (outer_type)))
return false;
! /* Do not lose casts between pointers that when dereferenced access
! memory with different alias sets. */
! if (get_deref_alias_set (inner_type) != get_deref_alias_set (outer_type))
return false;
/* We do not care for const qualification of the pointed-to types
*************** useless_type_conversion_p_1 (tree outer_
*** 1002,1007 ****
--- 999,1011 ----
if (TREE_CODE (inner_type) != TREE_CODE (outer_type))
return false;
+ /* Conversions from array types with unknown extent to
+ array types with known extent are not useless. */
+ if (TREE_CODE (inner_type) == ARRAY_TYPE
+ && !TYPE_DOMAIN (inner_type)
+ && TYPE_DOMAIN (outer_type))
+ return false;
+
/* ??? This seems to be necessary even for aggregates that don't
have TYPE_STRUCTURAL_EQUALITY_P set. */