This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] for PR17474
- From: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 19 Sep 2004 23:51:25 +0200
- Subject: [patch] for PR17474
Hello,
when strength reduction in ivopts was rewriting memory accesses of
form
(*base_1)->field = ...
It took a duplicate of the ssa name that was base of the reference as
the base of the new INDIRECT_REF reference (so that the aliasing info is
preserved). The problem is that this pointer has wrong type, i.e.
struct something * instead typeof (field) *, which somehow persuaded dom
to fold this reference back to structure field access, however with a
wrong offset (this might be a bug in maybe_fold_offset_to_component_ref,
I am not really sure).
This patch makes the base variable be of the right type, thus fixing
the misscompilation.
Bootstrapped & regtested on i686.
Zdenek
PR tree-optimization/17474
* tree-flow.h (create_subfield_ptr_name): Declare.
* tree-ssa-loop-ivopts.c (rewrite_address_base): Use
create_subfield_ptr_name.
* tree-ssanames.c (create_subfield_ptr_name): New function.
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 2.46
diff -c -3 -p -r2.46 tree-flow.h
*** tree-flow.h 16 Sep 2004 21:29:38 -0000 2.46
--- tree-flow.h 19 Sep 2004 21:40:03 -0000
*************** extern void rewrite_ssa_into_ssa (void);
*** 594,599 ****
--- 594,600 ----
void compute_global_livein (bitmap, bitmap);
tree duplicate_ssa_name (tree, tree);
+ tree create_subfield_ptr_name (tree, tree);
/* In tree-ssa-ccp.c */
bool fold_stmt (tree *);
Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v
retrieving revision 2.11
diff -c -3 -p -r2.11 tree-ssa-loop-ivopts.c
*** tree-ssa-loop-ivopts.c 17 Sep 2004 21:54:42 -0000 2.11
--- tree-ssa-loop-ivopts.c 19 Sep 2004 21:40:05 -0000
*************** unshare_and_remove_ssa_names (tree ref)
*** 3826,3868 ****
static void
rewrite_address_base (block_stmt_iterator *bsi, tree *op, tree with)
{
! tree var = get_base_address (*op), new_var, new_name, copy, name;
! tree orig;
! if (!var || TREE_CODE (with) != SSA_NAME)
goto do_rewrite;
! if (TREE_CODE (var) == INDIRECT_REF)
! var = TREE_OPERAND (var, 0);
! if (TREE_CODE (var) == SSA_NAME)
! {
! name = var;
! var = SSA_NAME_VAR (var);
! }
! else if (DECL_P (var))
! name = NULL_TREE;
! else
goto do_rewrite;
-
- if (var_ann (var)->type_mem_tag)
- var = var_ann (var)->type_mem_tag;
! /* We need to add a memory tag for the variable. But we do not want
! to add it to the temporary used for the computations, since this leads
! to problems in redundancy elimination when there are common parts
! in two computations referring to the different arrays. So we copy
! the variable to a new temporary. */
! copy = build2 (MODIFY_EXPR, void_type_node, NULL_TREE, with);
! if (name)
! new_name = duplicate_ssa_name (name, copy);
! else
! {
! new_var = create_tmp_var (TREE_TYPE (with), "ruatmp");
! add_referenced_tmp_var (new_var);
! var_ann (new_var)->type_mem_tag = var;
! new_name = make_ssa_name (new_var, copy);
! }
! TREE_OPERAND (copy, 0) = new_name;
bsi_insert_before (bsi, copy, BSI_SAME_STMT);
with = new_name;
--- 3855,3873 ----
static void
rewrite_address_base (block_stmt_iterator *bsi, tree *op, tree with)
{
! tree new_name, copy, orig;
! if (TREE_CODE (with) != SSA_NAME)
goto do_rewrite;
! /* Copy the address to the new temporary variable with the aliasing
! information copied from the memory reference. */
! new_name = create_subfield_ptr_name (*op, NULL_TREE);
! if (!new_name)
goto do_rewrite;
! copy = build2 (MODIFY_EXPR, void_type_node, new_name, with);
! SSA_NAME_DEF_STMT (new_name) = copy;
bsi_insert_before (bsi, copy, BSI_SAME_STMT);
with = new_name;
Index: tree-ssanames.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssanames.c,v
retrieving revision 2.14
diff -c -3 -p -r2.14 tree-ssanames.c
*** tree-ssanames.c 18 Sep 2004 07:31:30 -0000 2.14
--- tree-ssanames.c 19 Sep 2004 21:40:05 -0000
*************** duplicate_ssa_name (tree name, tree stmt
*** 294,299 ****
--- 294,346 ----
return new_name;
}
+ /* Create and return a ssa name defined by statement STMT. The aliasing
+ information of new ssa name is set up using the fact that it will
+ be used to address memory location FIELD. */
+
+ tree
+ create_subfield_ptr_name (tree field, tree stmt)
+ {
+ tree new_name, new_var, old_name, old_var, type_mem_tag, type;
+
+ old_var = get_base_address (field);
+
+ if (!old_var)
+ return NULL_TREE;
+ if (TREE_CODE (old_var) == INDIRECT_REF)
+ old_var = TREE_OPERAND (old_var, 0);
+ if (TREE_CODE (old_var) == SSA_NAME)
+ {
+ old_name = old_var;
+ old_var = SSA_NAME_VAR (old_var);
+ }
+ else if (DECL_P (old_var))
+ old_name = NULL_TREE;
+ else
+ return NULL_TREE;
+
+ type_mem_tag = var_ann (old_var)->type_mem_tag;
+ if (!type_mem_tag)
+ type_mem_tag = old_var;
+
+ type = build_pointer_type (TREE_TYPE (field));
+ new_var = create_tmp_var (type, "cspntmp");
+ add_referenced_tmp_var (new_var);
+ var_ann (new_var)->type_mem_tag = type_mem_tag;
+
+ if (old_name)
+ {
+ /* We use duplicate_ssa_name to copy the aliasing information
+ from old_name. A bit hacky. */
+ new_name = duplicate_ssa_name (old_name, stmt);
+ SSA_NAME_VAR (new_name) = new_var;
+ TREE_TYPE (new_name) = type;
+ }
+ else
+ new_name = make_ssa_name (new_var, stmt);
+
+ return new_name;
+ }
/* Release all the SSA_NAMEs created by STMT. */