[Bug fortran/57297] FAIL: gfortran.dg/select_type_4.f90 -O2 execution test
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu May 16 10:14:00 GMT 2013
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57297
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2013-05-16
CC| |jamborm at gcc dot gnu.org
Ever confirmed|0 |1
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
This
MEM[(struct __class_poly_list_Node_type_p *)&node] = node_17;
MEM[(struct __class_poly_list_Node_type_p *)&node + 4B] =
&__vtab_poly_list_Node_type;
MEM[(struct node_type *)integer_node_4].next = VIEW_CONVERT_EXPR<struct
__class_poly_list_Node_type_p>(MEM[(struct __class_poly_list_Node_type
&)&node]);
certainly looks suspicious - we store to node with alias type
(struct __class_poly_list_Node_type_p *) and load from the same location
with alias type (struct __class_poly_list_Node_type &).
Now, the frontend generated code doesn't have the above as it appears only
via some inlining:
append_node (struct list_type & restrict list, struct
__class_poly_list_Node_type & new_node)
{
...
_9 = list_4(D)->tail._data;
_9->next = VIEW_CONVERT_EXPR<struct
__class_poly_list_Node_type_p>(*new_node_6(D));
and
_19 = __builtin_malloc (16);
node._data = _19;
...
_26 = node._data;
__builtin_memset (_26, 0, 16);
node._vptr = &__vtab_poly_list_Node_type;
_29 = node._vptr;
_30 = _29->_size;
_31 = (unsigned long) _30;
_32 = node._vptr;
_33 = _32->_def_init;
_34 = node._data;
__builtin_memcpy (_34, _33, _31);
append_node (&list, &node);
It is early SRA that re-materializes in that way before the aggregate
copy:
MEM[(struct __class_poly_list_Node_type_p *)&node] = node$_data_28;
MEM[(struct __class_poly_list_Node_type_p *)&node + 8B] = node$_vptr_20;
list.head = VIEW_CONVERT_EXPR<struct
__class_poly_list_Node_type_p>(MEM[(struct __class_poly_list_Node_type
&)&node]);
Access trees for node (UID: 1941):
access { base = (1941)'node', offset = 0, size = 128, expr = node, type =
struct __class_poly_list_Node_type_p, grp_read = 1, grp_write = 1,
grp_assignment_read = 1, grp_assignment_write = 1, grp_scalar_read = 0,
grp_scalar_write = 0, grp_total_scalarization = 1, grp_hint = 1, grp_covered =
1, grp_unscalarizable_region = 0, grp_unscalarized_data = 0, grp_partial_lhs =
0, grp_to_be_replaced = 0, grp_to_be_debug_replaced = 0, grp_maybe_modified =
0, grp_not_necessarilly_dereferenced = 0
* access { base = (1941)'node', offset = 0, size = 64, expr = node._data, type
= struct node_type *, grp_read = 1, grp_write = 1, grp_assignment_read = 1,
grp_assignment_write = 1, grp_scalar_read = 1, grp_scalar_write = 1,
grp_total_scalarization = 1, grp_hint = 1, grp_covered = 1,
grp_unscalarizable_region = 0, grp_unscalarized_data = 0, grp_partial_lhs = 0,
grp_to_be_replaced = 1, grp_to_be_debug_replaced = 0, grp_maybe_modified = 0,
grp_not_necessarilly_dereferenced = 0
* access { base = (1941)'node', offset = 64, size = 64, expr = node._vptr, type
= struct __vtype_poly_list_Node_type * {ref-all}, grp_read = 1, grp_write = 1,
grp_assignment_read = 1, grp_assignment_write = 1, grp_scalar_read = 1,
grp_scalar_write = 1, grp_total_scalarization = 1, grp_hint = 1, grp_covered =
1, grp_unscalarizable_region = 0, grp_unscalarized_data = 0, grp_partial_lhs =
0, grp_to_be_replaced = 1, grp_to_be_debug_replaced = 0, grp_maybe_modified =
0, grp_not_necessarilly_dereferenced = 0
that replacement is not 100% correct. Coming from
Therefore, I specially handle a fourth case, happening when there is a
specific type cast or it is impossible to locate a scalarized subaccess on
the other side of the expression. If that happens, I simply "refresh" the
RHS by storing in it is scalarized components leave the original statement
there to do the copying and then load the scalar replacements of the LHS.
This is what the first branch does. */
if (modify_this_stmt
|| gimple_has_volatile_ops (*stmt)
|| contains_vce_or_bfcref_p (rhs)
|| contains_vce_or_bfcref_p (lhs))
{
with
list.head = VIEW_CONVERT_EXPR<struct __class_poly_list_Node_type_p>(MEM[(struct
__class_poly_list_Node_type &)&node]);
build_ref_for_offset ends up creating a MEM_REF with different alias pointer
type than "the original" (note that there may be multiple originals and
AFAIK we don't make any attempt to "merge" them conservatively).
Re-materializing the original variable will always be hard. I believe that
Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c (revision 198420)
+++ gcc/tree-sra.c (working copy)
@@ -3158,7 +3158,7 @@ sra_modify_assign (gimple *stmt, gimple_
if (modify_this_stmt
|| gimple_has_volatile_ops (*stmt)
- || contains_vce_or_bfcref_p (rhs)
+ || contains_bitfld_comp_ref_p (rhs)
|| contains_vce_or_bfcref_p (lhs))
{
if (access_has_children_p (racc))
should work.
But note that the frontend already geneated wrong-code with the above
assignment
list.head = VIEW_CONVERT_EXPR<struct __class_poly_list_Node_type_p>(MEM[(struct
__class_poly_list_Node_type &)&node]);
which comes from
_9->next = VIEW_CONVERT_EXPR<struct
__class_poly_list_Node_type_p>(*new_node_6(D));
as this is reading from 'node' with a different alias set than was stored
to (via the simple component-refs). But SRA is likely required to expose
this situation to the scheduler.
Confirmed as a frontend issue.
I can see a difference with the proposed Frontend patch but the alias
sets are unchanged.
More information about the Gcc-bugs
mailing list