[PATCH] Fix variant of PR60819

Richard Biener rguenther@suse.de
Mon Apr 14 09:43:00 GMT 2014


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  <rguenther@suse.de>
	Marc Glisse  <marc.glisse@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;
+}
+



More information about the Gcc-patches mailing list