This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Aliasing of arrays
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Alexander Cherepanov <ch3root at openwall dot com>, "Joseph S. Myers" <joseph at codesourcery dot com>
- Cc: GCC Development <gcc at gcc dot gnu dot org>
- Date: Wed, 30 Nov 2016 14:42:17 +0100
- Subject: Re: Aliasing of arrays
- Authentication-results: sourceware.org; auth=none
- References: <7fd0ae56-3f31-ca85-9fe6-8c0d249a86d8@openwall.com>
On Wed, Nov 30, 2016 at 2:19 PM, Alexander Cherepanov
<ch3root@openwall.com> wrote:
> Hi!
>
> Pascal Cuoq communicated to me the following example:
>
> int ar1(int (*p)[3], int (*q)[3])
> {
> (*p)[0] = 1;
> (*q)[1] = 2;
> return (*p)[0];
> }
>
> gcc of versions 4.9.2 and 7.0.0 20161129 optimize it with -O2 on the premise
> that elements with different indices don't alias:
>
> 0000000000000000 <ar1>:
> 0: c7 47 0c 01 00 00 00 movl $0x1,0xc(%rdi)
> 7: b8 01 00 00 00 mov $0x1,%eax
> c: c7 46 10 02 00 00 00 movl $0x2,0x10(%rsi)
> 13: c3 retq
>
> That's fine. But then I expect that gcc will also assume that arrays of
> different known lengths don't alias, i.e. that gcc will optimize this
> example:
>
> int ar2(int (*p)[8], int (*q)[7]) {
> (*p)[3] = 1;
> (*q)[3] = 2;
> return (*p)[3];
> }
>
> But this is not optimized:
>
> 0000000000000020 <ar2>:
> 20: c7 47 0c 01 00 00 00 movl $0x1,0xc(%rdi)
> 27: c7 46 0c 02 00 00 00 movl $0x2,0xc(%rsi)
> 2e: 8b 47 0c mov 0xc(%rdi),%eax
>
> Is this behavior fully intentional, is the first example optimized too
> aggressively, is an optimization missed in the second example, or is the
> situation more complex?
I think it's a bug that we optimize ar1. We run into
static bool
indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
...
/* If both references are through the same type, they do not alias
if the accesses do not overlap. This does extra disambiguation
for mixed/pointer accesses but requires strict aliasing. */
if ((TREE_CODE (base1) != TARGET_MEM_REF
|| (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
&& (TREE_CODE (base2) != TARGET_MEM_REF
|| (!TMR_INDEX (base2) && !TMR_INDEX2 (base2)))
&& same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1
&& same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1
&& same_type_for_tbaa (TREE_TYPE (ptrtype1),
TREE_TYPE (ptrtype2)) == 1)
return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
but that probably shouldn't apply to array types. The idea is that
objects of the same type cannot overlap. Maybe Joseph can clarify whether
and array object of known size really constitutes an object in that sense.
For the ar2 case the types are not equal and thus we do not use that trick
(and all array types irrespective of size get the same alias set, so
TBAA doesn't
apply here).
Richard.
>
> --
> Alexander Cherepanov