From 1624d351f14049bfe08bc2c86c63a9cccfb43ab8 Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Wed, 16 Oct 2019 13:35:41 +0000 Subject: [PATCH] In PR70010, a function is marked with target(no-vsx) to disable VSX code generation. 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. gcc/ 2019-10-16 Peter Bergner Jiufu Guo 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 Jiufu Guo 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 From-SVN: r277065 --- gcc/ChangeLog | 7 +++++ gcc/config/rs6000/rs6000.c | 30 ++++++++++++-------- gcc/testsuite/ChangeLog | 10 +++++++ gcc/testsuite/gcc.target/powerpc/pr70010-1.c | 17 +++++++++++ gcc/testsuite/gcc.target/powerpc/pr70010-2.c | 17 +++++++++++ gcc/testsuite/gcc.target/powerpc/pr70010-3.c | 17 +++++++++++ gcc/testsuite/gcc.target/powerpc/pr70010-4.c | 17 +++++++++++ gcc/testsuite/gcc.target/powerpc/pr70010.c | 19 +++++++++++++ 8 files changed, 122 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr70010-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr70010-2.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr70010-3.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr70010-4.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr70010.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1a03ac2dc05..da7bf1fddbf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-10-16 Peter Bergner + Jiufu Guo + + 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-16 Richard Sandiford * function-abi.cc (expr_callee_abi): Assert for POINTER_TYPE_P. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d1434a9f743..a129137da94 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -23964,25 +23964,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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b2b92deb134..93ca734f8a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2019-10-16 Peter Bergner + Jiufu Guo + + 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-16 Feng Xue PR ipa/91088 diff --git a/gcc/testsuite/gcc.target/powerpc/pr70010-1.c b/gcc/testsuite/gcc.target/powerpc/pr70010-1.c new file mode 100644 index 00000000000..78870dbd886 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr70010-1.c @@ -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 index 00000000000..4c09b216689 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr70010-2.c @@ -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 index 00000000000..bca31875632 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr70010-3.c @@ -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 index 00000000000..c575cff1b52 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr70010-4.c @@ -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 index 00000000000..257ac297a8a --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr70010.c @@ -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; +} -- 2.43.5