diff mbox series

Fix powerpc ICE with __builtin_vec_ld on an array (PR target/82112)

Message ID 20170907084030.GS2323@tucnak
State New
Headers show
Series Fix powerpc ICE with __builtin_vec_ld on an array (PR target/82112) | expand

Commit Message

Jakub Jelinek Sept. 7, 2017, 8:40 a.m. UTC
Hi!

The C and C++ FE handle resolve_overloaded_builtin differently, the C FE
calls it when e.g. array-to-pointer and function-to-pointer conversions
are already done on the arguments, while C++ FE does that only much later.
The c-common code e.g. for __sync/__atomic builtins deals with
that e.g. by:
  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      /* Force array-to-pointer decay for C++.  */
      gcc_assert (c_dialect_cxx());
      (*params)[0] = default_conversion ((*params)[0]);
      type = TREE_TYPE ((*params)[0]);
    }
while the rs6000 md hook uses default_conversion only in one spot (the
generic handling), but for vec_ld and vec_st does something on its own.
What is even worse is that for vec_ld, it does that too late, there is
a fold_convert in between for the case where the element type is
qualified, and that only works if the argument is pointer, not array
(in which case it ICEs).
So, the following patch moves the vec_ld conversion earlier and for both
vec_ld and vec_st uses what c-common as well as later
altivec_resolve_overloaded_builtin uses.

Bootstrapped/regtested on powerpc64-linux (regtest with {,-m32}), ok for
trunk?

2017-09-07  Jakub Jelinek  <jakub@redhat.com>

	PR target/82112
	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): For
	ALTIVEC_BUILTIN_VEC_LD if arg1 has array type call default_conversion
	on it early, rather than manual conversion late.  For
	ALTIVEC_BUILTIN_VEC_ST if arg2 has array type call default_conversion
	instead of performing manual conversion.

	* g++.dg/ext/altivec-18.C: New test.


	Jakub
diff mbox series

Patch

--- gcc/config/rs6000/rs6000-c.c.jj	2017-09-01 09:26:55.000000000 +0200
+++ gcc/config/rs6000/rs6000-c.c	2017-09-06 15:43:11.719590365 +0200
@@ -6478,7 +6478,14 @@  altivec_resolve_overloaded_builtin (loca
 
       /* Strip qualifiers like "const" from the pointer arg.  */
       tree arg1_type = TREE_TYPE (arg1);
-      if (!POINTER_TYPE_P (arg1_type) && TREE_CODE (arg1_type) != ARRAY_TYPE)
+      if (TREE_CODE (arg1_type) == ARRAY_TYPE)
+	{
+	  /* Force array-to-pointer decay for C++.  */
+	  gcc_assert (c_dialect_cxx ());
+	  arg1 = default_conversion (arg1);
+	  arg1_type = TREE_TYPE (arg1);
+	}
+      if (!POINTER_TYPE_P (arg1_type))
 	goto bad;
 
       tree inner_type = TREE_TYPE (arg1_type);
@@ -6498,15 +6505,6 @@  altivec_resolve_overloaded_builtin (loca
 	  if (!ptrofftype_p (TREE_TYPE (arg0)))
 	    arg0 = build1 (NOP_EXPR, sizetype, arg0);
 
-	  tree arg1_type = TREE_TYPE (arg1);
-	  if (TREE_CODE (arg1_type) == ARRAY_TYPE)
-	    {
-	      arg1_type = TYPE_POINTER_TO (TREE_TYPE (arg1_type));
-	      tree const0 = build_int_cstu (sizetype, 0);
-	      tree arg1_elt0 = build_array_ref (loc, arg1, const0);
-	      arg1 = build1 (ADDR_EXPR, arg1_type, arg1_elt0);
-	    }
-
 	  tree addr = fold_build2_loc (loc, POINTER_PLUS_EXPR, arg1_type,
 				       arg1, arg0);
 	  tree aligned = fold_build2_loc (loc, BIT_AND_EXPR, arg1_type, addr,
@@ -6563,10 +6561,10 @@  altivec_resolve_overloaded_builtin (loca
 	  tree arg2_type = TREE_TYPE (arg2);
 	  if (TREE_CODE (arg2_type) == ARRAY_TYPE)
 	    {
-	      arg2_type = TYPE_POINTER_TO (TREE_TYPE (arg2_type));
-	      tree const0 = build_int_cstu (sizetype, 0);
-	      tree arg2_elt0 = build_array_ref (loc, arg2, const0);
-	      arg2 = build1 (ADDR_EXPR, arg2_type, arg2_elt0);
+	      /* Force array-to-pointer decay for C++.  */
+	      gcc_assert (c_dialect_cxx ());
+	      arg2 = default_conversion (arg2);
+	      arg2_type = TREE_TYPE (arg2);
 	    }
 
 	  /* Find the built-in to make sure a compatible one exists; if not
--- gcc/testsuite/g++.dg/ext/altivec-18.C.jj	2017-09-06 15:45:00.673295858 +0200
+++ gcc/testsuite/g++.dg/ext/altivec-18.C	2017-09-06 15:45:36.274872713 +0200
@@ -0,0 +1,14 @@ 
+// PR target/82112
+// { dg-do compile { target powerpc*-*-* } }
+// { dg-require-effective-target powerpc_altivec_ok }
+// { dg-options "-save-temps -maltivec" }
+
+#include <altivec.h>
+
+__attribute__((aligned (16))) extern const unsigned char c[16];
+
+void
+foo (void)
+{
+  vec_ld (0, c);
+}