https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86619
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |alias, missed-optimization
Status|UNCONFIRMED |NEW
Last reconfirmed| |2018-07-23
CC| |rguenth at gcc dot gnu.org
Ever confirmed|0 |1
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
type-based alias analysis doesn't distinguish between int[2] and int[3]. The
issue with operator[] is that the FE produces
;; Function T& ar<T, size>::operator[](size_t) [with T = int; long unsigned int
size = 2; size_t = long unsigned int] (null)
;; enabled by -tree-original
return <retval> = (int &) &((struct ar *) this)->ar[offset];
and
<<cleanup_point <<< Unknown tree: expr_stmt
(void) (*ar<int, 3>::operator[] ((struct ar *) a, 0) = 1) >>>>>;
<<cleanup_point <<< Unknown tree: expr_stmt
(void) (*ar<int, 2>::operator[] ((struct ar *) b, 0) = 2) >>>>>;
<<cleanup_point return <retval> = *ar<int, 3>::operator[] ((struct ar *) a,
0)>>;
which after inlining is
int & _6;
int & _9;
<bb 2> :
_6 = &a_5(D)->ar[0];
*_6 = 1;
_9 = &b_8(D)->ar[0];
*_9 = 2;
_11 = &a_5(D)->ar[0];
_12 = *_11;
return _12;
compared to
f1 (struct ar & a, struct ar & b)
{
int _6;
<bb 2> :
a_2(D)->ar[0] = 1;
b_4(D)->ar[0] = 2;
_6 = a_2(D)->ar[0];
return _6;
here TBAA only sees int & accesses which do conflict and points-to analysis
is TBAA agnostic and cannot disambiguate a_5(D) and b_8(D). For f1
TBAA sees structure accesses and can disambiguate.
C++ abstraction makes it harder to optimize here. You get two accesses
of effective type int vs. one of ar<int, 2> and one of ar<int, 3>.
Way in the past points-to had some bits of TBAA, eventually we can
re-introduce bits here but the TBAA bits did not play well with
the points-to solver and created wrong-code.
Note there isn't really a way to tell the middle-end that a pointed
to object is of a specific dynamic type. Eventually we can play
leeway and make REFERENCE_TYPE parameters behave that way.