+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.
+
2019-10-16 Richard Sandiford <richard.sandiford@arm.com>
* function-abi.cc (expr_callee_abi): Assert for POINTER_TYPE_P.
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;
}
+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.
+
2019-10-16 Feng Xue <fxue@os.amperecomputing.com>
PR ipa/91088
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}