diff mbox series

[committed] Fix OpenMP declare simd handling with externals (PR middle-end/89246)

Message ID 20190209090305.GJ2135@tucnak
State New
Headers show
Series [committed] Fix OpenMP declare simd handling with externals (PR middle-end/89246) | expand

Commit Message

Jakub Jelinek Feb. 9, 2019, 9:03 a.m. UTC
Hi!

As the following testcase shows, if we only check DECL_ARGUMENTS
even on external decls, where the !node->definition declarations
usually have NULL DECL_ARGUMENTS, we don't actually check the arguments
at all, so if there is any non-suitable argument type, we actually don't
warn for it, but what's worse, we clone it and allow it to be used in
vectorization code, which in some rare cases as in the following testcase
actually is possible.

The following patch grabs the arguments similarly how
  if (node->definition)
    args = ipa_get_vector_of_formal_parms (node->decl);
  else
    args = simd_clone_vector_of_formal_parm_types (node->decl);
grabs those.  Bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk.

aarch64 will need similar changes.

2019-02-09  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/89246
	* config/i386/i386.c (ix86_simd_clone_compute_vecsize_and_simdlen):
	If !node->definition and TYPE_ARG_TYPES is non-NULL, use
	TYPE_ARG_TYPES instead of DECL_ARGUMENTS.

	* gcc.dg/gomp/pr89246-1.c: New test.
	* gcc.dg/gomp/pr89246-2.c: New test.


	Jakub
diff mbox series

Patch

--- gcc/config/i386/i386.c.jj	2019-02-07 17:33:38.374676821 +0100
+++ gcc/config/i386/i386.c	2019-02-08 16:40:33.645381631 +0100
@@ -50447,28 +50447,34 @@  ix86_simd_clone_compute_vecsize_and_simd
 
   tree t;
   int i;
+  tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl));
+  bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE);
 
-  for (t = DECL_ARGUMENTS (node->decl), i = 0; t; t = DECL_CHAIN (t), i++)
-    switch (TYPE_MODE (TREE_TYPE (t)))
-      {
-      case E_QImode:
-      case E_HImode:
-      case E_SImode:
-      case E_DImode:
-      case E_SFmode:
-      case E_DFmode:
-      /* case E_SCmode: */
-      /* case E_DCmode: */
-	if (!AGGREGATE_TYPE_P (TREE_TYPE (t)))
-	  break;
-	/* FALLTHRU */
-      default:
-	if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
-	  break;
-	warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
-		    "unsupported argument type %qT for simd", TREE_TYPE (t));
-	return 0;
-      }
+  for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0;
+       t && t != void_list_node; t = TREE_CHAIN (t), i++)
+    {
+      tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t);
+      switch (TYPE_MODE (arg_type))
+	{
+	case E_QImode:
+	case E_HImode:
+	case E_SImode:
+	case E_DImode:
+	case E_SFmode:
+	case E_DFmode:
+	/* case E_SCmode: */
+	/* case E_DCmode: */
+	  if (!AGGREGATE_TYPE_P (arg_type))
+	    break;
+	  /* FALLTHRU */
+	default:
+	  if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
+	    break;
+	  warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+		      "unsupported argument type %qT for simd", arg_type);
+	  return 0;
+	}
+    }
 
   if (!TREE_PUBLIC (node->decl))
     {
--- gcc/testsuite/gcc.dg/gomp/pr89246-1.c.jj	2019-02-08 16:44:33.362428659 +0100
+++ gcc/testsuite/gcc.dg/gomp/pr89246-1.c	2019-02-08 16:46:01.195979218 +0100
@@ -0,0 +1,19 @@ 
+/* PR middle-end/89246 */
+/* { dg-do link { target { int128 && vect_simd_clones } } } */
+/* { dg-options "-O2 -fopenmp-simd -w" } */
+/* { dg-additional-sources "pr89246-2.c" } */
+
+#pragma omp declare simd
+int foo (__int128 x)
+{
+  return x;
+}
+
+#pragma omp declare simd
+extern int bar (int x);
+
+int
+main ()
+{
+  return foo (0) + bar (0);
+}
--- gcc/testsuite/gcc.dg/gomp/pr89246-2.c.jj	2019-02-08 16:44:39.287330957 +0100
+++ gcc/testsuite/gcc.dg/gomp/pr89246-2.c	2019-02-08 16:02:16.425237007 +0100
@@ -0,0 +1,13 @@ 
+/* PR middle-end/89246 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O0 -fno-openmp -fno-openmp-simd" } */
+
+#pragma omp declare simd
+extern int foo (__int128 x);
+
+#pragma omp declare simd
+int
+bar (int x)
+{
+  return x + foo (0);
+}