Peter Bergner <berg...@linux.ibm.com> writes: > Segher Boessenkool <seg...@kernel.crashing.org> writes: >> So what should we do about this? There are arguments for *both* >> behaviours, and apparently with LTO we do not know which flags are >> explicit? > > Actually, from my testing, it seems the rs6000_isa_flags_explicit > flags are set correctly in LTO! > > > > On 10/15/19 7:45 AM, Jiufu Guo wrote: >> The difference between 'with LTO' and 'without LTO' is: >> Wit LTO, if a function does not have target attribute in source code, >> then using option attribute from command line(e.g. -mcpu=xxx) as >> isa_flags; and if features (e.g. -mno-vsx, -mvsx) are specified on >> command line, isa_flags_explicit is also set. >> If a function has target attribute in source code explicitly, >> then isa_flags_explicit is set to reflect feature is specified >> explicitly besides explicit features from command line; and isa_flags is >> set as the effective features. >> >> Without LTO, if a function does not have target attribute in source code, >> then it's isa_flags_explicit and isa_flags are as NULL (target_options >> == NULL). >> If a function has target attribute in source code, it is same as 'with >> LTO'. > > After reading this a few times and compiling a few unit tests cases in > gdb/cc1/lto1, I agree with your explanation above and with your addition > to my patch. However, how about a slight modification to your change > with some updated comments? Updated patch below. Great update. > > This also incorporates Segher and Andreas's changes to my test case. > I have not looked at your extra test cases, so I have not added them > to this patch, but I like the idea of adding test cases that exercise > this code in LTO context. > > I am going on vacation tomorrow, so Jiufu, can you take over ownership > of this combined patch, along with your extra test cases? I have not > bootstrapped or regtested this, so that still needs doing. If you're > busy, I can pick this up when I return to work on Monday. Sure, I will add test cases and do bootstrap/regtest.
Jiufu BR > > Peter > > > gcc/ > 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/ > PR target/70010 > * gcc.target/powerpc/pr70010.c: New test. > > Index: gcc/config/rs6000/rs6000.c > =================================================================== > --- gcc/config/rs6000/rs6000.c (revision 276975) > +++ gcc/config/rs6000/rs6000.c (working copy) > @@ -23964,25 +23964,31 @@ rs6000_can_inline_p (tree caller, tree c > 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; > + > + /* 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; > > - /* 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) > + /* 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 non-vsx function > + must not inline a vsx function. However, for those options that the > + callee has explicitly set, 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: gcc/testsuite/gcc.target/powerpc/pr70010.c > =================================================================== > --- gcc/testsuite/gcc.target/powerpc/pr70010.c (nonexistent) > +++ gcc/testsuite/gcc.target/powerpc/pr70010.c (working copy) > @@ -0,0 +1,20 @@ > +/* { dg-do compile } */ > +/* { dg-require-effective-target powerpc_vsx_ok } */ > +/* { 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; > +}