This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/36861] [4.5/4.6 Regression] boost's compressed avl confuses GCC


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36861

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID

--- Comment #37 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-01-18 15:19:05 UTC ---
Ok, with -O1 -fno-tree-loop-im as basic flags -fno-tree-dse makes the
difference for the segfault when we remove

 static void
boost::intrusive::avltree_algorithms<NodeTraits>::rebalance_after_i
nsertion(boost::intrusive::avltree_algorithms<NodeTraits>::node_ptr,
boost::intr
usive::avltree_algorithms<NodeTraits>::node_ptr) [with NodeTraits =
boost::intru
sive::avltree_node_traits<boost::interprocess::offset_ptr<void>, false>,
boost::
intrusive::avltree_algorithms<NodeTraits>::node_ptr =
boost::interprocess::offse
t_ptr<boost::intrusive::avltree_node<boost::interprocess::offset_ptr<void> > >] 
(struct node_ptr & restrict header, struct node_ptr & restrict x)
 {
   long int D.64530;
@@ -8290,7 +7992,6 @@
   p.19_2156 = (long int) D.64522_2154;
   D.64529_2157 = (long int) D.64513_2150;
   D.64530_2158 = p.19_2156 - D.64529_2157;
-  MEM[(struct offset_ptr *)D.64515_2149].m_offset = D.64530_2158;
   if (D.64530_2158 == 1)
     goto <bb 746>;
   else

this pointer is believed to point to

D.64515_2149, points-to NULL, points-to vars: { D.57715 CAST_RESTRICT.445 }
(includes restrict tags)

computed from

<bb 742>:
  n_2143 = (struct node_ptr & restrict) &D.57715;
  p_2144 = (struct node_ptr & restrict) &D.57716;
  D.64517_2145 = D.57715.m_offset;
  D.64516_2147 = (long unsigned int) D.64517_2145;
  D.64515_2148 = n_2143 + D.64516_2147;

<bb 743>:
  # D.64515_2149 = PHI <0B(739), D.64515_2148(742)>

which confirms the points-to calculation.

But the compressed AVL tree thinks it can represent a pointer to
a global object by using the address of a local variable and
the difference between the address of the global and the local.
Which it of course cannot according to the C++ standard.
D.57715.m_offset is set by

<bb 740>:
  p.19_2139 = (long int) D.64504_2137;
  D.64508_2140 = (long int) &D.57715;
  D.64509_2141 = p.19_2139 - D.64508_2140;
  D.57715.m_offset = D.64509_2141;
  if (D.64509_2141 == 1)
    goto <bb 741>;
  else
    goto <bb 742>;

and we have

<bb 737>:
boost::interprocess::offset_ptr<boost::intrusive::avltree_node<boost::interprocess::offset_ptr<void>
> >::offset_ptr (&D.57716, &root);
  D.64502_2134 = MEM[(const struct offset_ptr *)header_2(D)].m_offset;
  if (D.64502_2134 != 1)
    goto <bb 738>;
  else
    goto <bb 739>;

<bb 738>:
  D.64503_2136 = (long unsigned int) D.64502_2134;
  D.64504_2137 = header_2(D) + D.64503_2136;

where header_2(D) is a parameter, struct node_ptr & restrict header.  So
Boost AVL expects us to compute whatever header points-to as points-to
set of D.64515_2149 with no backing from the standard that we are required
to do that.

If we were able to "optimize" the code back to base the address on
header it would of course work (by luck).

For

extern void abort (void);
struct X { unsigned long offset; };
void foo (char *p)
{
  struct X a;
  char tmp, *q;
  a.offset = p - &tmp;
  if (a.offset == 1)
    abort ();
  q = &tmp + a.offset;
  *q = 0;
}

already early DCE kills the store (the above is what compressed AVL does).

Thus, this testcase is invalid.  Resulting performance is irrelevant.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]