]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[rs6000] PR70010, avoid no-vsx function to be inlined to vsx function
authorPeter Bergner <bergner@linux.ibm.com>
Mon, 28 Oct 2019 09:46:15 +0000 (09:46 +0000)
committerJiufu Guo <guojiufu@gcc.gnu.org>
Mon, 28 Oct 2019 09:46:15 +0000 (09:46 +0000)
In PR70010, a function is marked with target(no-vsx) to disable VSX code
generation.  To avoid VSX code generation, this function should not be
inlined into VSX function.  To fix the bug, in the current logic when
checking whether the caller's ISA flags supports the callee's ISA flags, we
just need to add a test that enforces that the caller's ISA flags match
exactly the callee's flags, for those flags that were explicitly set in the
callee.  If caller without target attribute then using options from command
line.

Jiufu
BR

gcc/
2019-10-16  Peter Bergner <bergner@linux.ibm.com>
    Jiufu Guo  <guojiufu@linux.ibm.com>

PR target/70010
* config/rs6000/rs6000.c (rs6000_can_inline_p): Prohibit inlining if
the callee explicitly disables some isa_flags the caller is using.

gcc.testsuite/
2019-10-16  Peter Bergner <bergner@linux.ibm.com>
    Jiufu Guo  <guojiufu@linux.ibm.com>

PR target/70010
* gcc.target/powerpc/pr70010.c: New test.
* gcc.target/powerpc/pr70010-1.c: New test.
* gcc.target/powerpc/pr70010-2.c: New test.
* gcc.target/powerpc/pr70010-3.c: New test.
* gcc.target/powerpc/pr70010-4.c: New test.

Co-Authored-By: Jiufu Guo <guojiufu@linux.ibm.com>
From-SVN: r277506

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr70010-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr70010-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr70010-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr70010-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr70010.c [new file with mode: 0644]

index 6e41b1f651be7020ccda6e228cb19e3b157454b6..5541277466723409a07fe2e36e3d3266dcbf1b47 100644 (file)
@@ -1,3 +1,10 @@
+2019-10-28  Peter Bergner <bergner@linux.ibm.com>
+           Jiufu Guo  <guojiufu@linux.ibm.com>
+
+       PR target/70010
+       * config/rs6000/rs6000.c (rs6000_can_inline_p): Prohibit inlining if
+       the callee explicitly disables some isa_flags the caller is using.
+
 2019-10-27  Iain Sandoe  <iain@sandoe.co.uk>
 
        Backport from mainline
index aa292a1c8bd3bef57003d3d6e3a2d1070586a9ea..6523dd2dabc90faffbd231e0f17d298437104a3b 100644 (file)
@@ -37866,25 +37866,31 @@ rs6000_can_inline_p (tree caller, tree callee)
   tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
   tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
 
-  /* If callee has no option attributes, then it is ok to inline.  */
+  /* If the callee has no option attributes, then it is ok to inline.  */
   if (!callee_tree)
     ret = true;
 
-  /* If caller has no option attributes, but callee does then it is not ok to
-     inline.  */
-  else if (!caller_tree)
-    ret = false;
-
   else
     {
-      struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
+      HOST_WIDE_INT caller_isa;
       struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+      HOST_WIDE_INT callee_isa = callee_opts->x_rs6000_isa_flags;
+      HOST_WIDE_INT explicit_isa = callee_opts->x_rs6000_isa_flags_explicit;
 
-      /* Callee's options should a subset of the caller's, i.e. a vsx function
-        can inline an altivec function but a non-vsx function can't inline a
-        vsx function.  */
-      if ((caller_opts->x_rs6000_isa_flags & callee_opts->x_rs6000_isa_flags)
-         == callee_opts->x_rs6000_isa_flags)
+      /* If the caller has option attributes, then use them.
+        Otherwise, use the command line options.  */
+      if (caller_tree)
+       caller_isa = TREE_TARGET_OPTION (caller_tree)->x_rs6000_isa_flags;
+      else
+       caller_isa = rs6000_isa_flags;
+
+      /* The callee's options must be a subset of the caller's options, i.e.
+        a vsx function may inline an altivec function, but a no-vsx function
+        must not inline a vsx function.  However, for those options that the
+        callee has explicitly enabled or disabled, then we must enforce that
+        the callee's and caller's options match exactly; see PR70010.  */
+      if (((caller_isa & callee_isa) == callee_isa)
+         && (caller_isa & explicit_isa) == (callee_isa & explicit_isa))
        ret = true;
     }
 
index cb2d912291d9c41ad4dae348756f8be38eaaa700..d3d1d6c189e7ec0acd4ac173f2b7d0aa8fde6863 100644 (file)
@@ -1,3 +1,13 @@
+2019-10-28  Peter Bergner <bergner@linux.ibm.com>
+           Jiufu Guo  <guojiufu@linux.ibm.com>
+
+       PR target/70010
+       * gcc.target/powerpc/pr70010.c: New test.
+       * gcc.target/powerpc/pr70010-1.c: New test.
+       * gcc.target/powerpc/pr70010-2.c: New test.
+       * gcc.target/powerpc/pr70010-3.c: New test.
+       * gcc.target/powerpc/pr70010-4.c: New test.
+
 2019-10-28  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.target/powerpc/pr70010-1.c b/gcc/testsuite/gcc.target/powerpc/pr70010-1.c
new file mode 100644 (file)
index 0000000..78870db
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -flto -mvsx" } */
+
+vector int c, a, b;
+
+static inline void __attribute__ ((__always_inline__, target ("no-vsx")))
+foo () /* { dg-error "inlining failed in call to .* target specific option mismatch" } */
+{
+  c = a + b;
+}
+
+int
+main ()
+{
+  foo (); /* { dg-message "called from here" } */
+  c = a + b;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr70010-2.c b/gcc/testsuite/gcc.target/powerpc/pr70010-2.c
new file mode 100644 (file)
index 0000000..4c09b21
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -flto -mno-vsx" } */
+
+vector int c, a, b;
+
+static inline void __attribute__ ((__always_inline__, target ("no-vsx")))
+foo ()
+{
+  c = a + b;
+}
+
+int
+main ()
+{
+  foo ();
+  c = a + b;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr70010-3.c b/gcc/testsuite/gcc.target/powerpc/pr70010-3.c
new file mode 100644 (file)
index 0000000..bca3187
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-vsx" } */
+
+vector int c, a, b;
+
+static inline void __attribute__ ((__always_inline__, target ("no-vsx")))
+foo ()
+{
+  c = a + b;
+}
+
+int
+main ()
+{
+  foo ();
+  c = a + b;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr70010-4.c b/gcc/testsuite/gcc.target/powerpc/pr70010-4.c
new file mode 100644 (file)
index 0000000..c575cff
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mvsx" } */
+
+vector int c, a, b;
+
+static inline void __attribute__ ((__always_inline__, target ("no-vsx")))
+foo () /* { dg-error "inlining failed in call to .* target specific option mismatch" } */
+{
+  c = a + b;
+}
+
+int
+main ()
+{
+  foo (); /* { dg-message "called from here" } */
+  c = a + b;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr70010.c b/gcc/testsuite/gcc.target/powerpc/pr70010.c
new file mode 100644 (file)
index 0000000..257ac29
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -finline-functions" } */
+/* { dg-final { scan-assembler {\mbl vadd_no_vsx\M} } } */
+
+typedef int vec_t __attribute__((vector_size(16)));
+
+static vec_t
+__attribute__((__target__("no-vsx")))
+vadd_no_vsx (vec_t a, vec_t b)
+{
+  return a + b;
+}
+
+vec_t
+__attribute__((__target__("vsx")))
+call_vadd_no_vsx (vec_t x, vec_t y, vec_t z)
+{
+  return vadd_no_vsx (x, y) - z;
+}