On Mon, 14 Apr 2014, Richard Biener wrote: > While digging in PR60819 (and thinking whether the original testcase > is valid) we figured that a clearly valid testcase is miscompiled > as well. That's because of the C/C++ frontends implementation of > vector indexing by decaying the vector to a element pointer. The > helper for that fails to apply the may-alias properties of the > vector type to the build scalar pointer type. > > The following patch fixes that. > > Bootstrapped and tested x86_64-unknown-linux-gnu, I'm re-testing > with some other changes. > > Ok for trunk and branches after 4.9.0 is out?
Based on IRC communication the following patch fixes also the original testcase #include <mmintrin.h> int f (__m64 const __A, int const __N) { return ((__v4hi)__A)[__N]; } where the user clearly writes a value-cast of __A and indexes the resulting vector. That we do this by accessing a memory representation of the casted object is an implementation detail, and thus we have to be careful in that implementation that the generated access properly honors TBAA rules. Which the patch below does. Bootstrap/regtest pending on x86_64-unknown-linux-gnu, ok for trunk and branches (after 4.9.0)? Thanks, Richard. 2014-04-14 Richard Biener <rguent...@suse.de> Marc Glisse <marc.gli...@inria.fr> PR c/60819 c-family/ * c-common.c (convert_vector_to_pointer_for_subscript): Properly apply may-alias properties of the vector type to the scalar pointer type. * gcc.target/i386/vec-may_alias.c: New testcase. Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c (revision 209359) +++ gcc/c-family/c-common.c (working copy) @@ -11784,8 +11784,21 @@ convert_vector_to_pointer_for_subscript c_common_mark_addressable_vec (*vecp); type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type)); - type = build_pointer_type (type); type1 = build_pointer_type (TREE_TYPE (*vecp)); + bool ref_all = TYPE_REF_CAN_ALIAS_ALL (type1); + if (!ref_all + && !DECL_P (*vecp)) + { + /* If the original vector isn't declared may_alias and it + isn't a bare vector look if the subscripting would + alias the vector we subscript, and if not, force ref-all. */ + alias_set_type vecset = get_alias_set (*vecp); + alias_set_type sset = get_alias_set (type); + if (!alias_sets_must_conflict_p (sset, vecset) + && !alias_set_subset_of (sset, vecset)) + ref_all = true; + } + type = build_pointer_type_for_mode (type, ptr_mode, ref_all); *vecp = build1 (ADDR_EXPR, type1, *vecp); *vecp = convert (type, *vecp); } Index: gcc/testsuite/gcc.target/i386/vec-may_alias.c =================================================================== --- gcc/testsuite/gcc.target/i386/vec-may_alias.c (revision 0) +++ gcc/testsuite/gcc.target/i386/vec-may_alias.c (working copy) @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -w -Wno-abi" } */ + +typedef int v2si __attribute__ ((vector_size (8))); +typedef short v4hi __attribute__ ((vector_size (8))); +typedef short v4hia __attribute__ ((vector_size (8), may_alias)); + +__attribute__ ((noinline, noclone)) +int f (v2si A, int N) +{ return ((v4hia)A)[N]; } + +__attribute__ ((noinline, noclone)) +int g (v2si A, int N) +{ return ((v4hi)A)[N]; } + +int main() +{ + v2si x = { 0, 0 }, y = { 1, 1 }; + if (f (x, 0) || f (x, 1) || f (x, 2) || f (x, 3)) + __builtin_abort (); + if (g (y, 0) != 1 || g (y, 1) || g (y, 2) != 1 || g (y, 3)) + __builtin_abort (); + return 0; +} +