[Bug target/82012] [8 Regression] libitm build fails for s390x-linux-gnu

rguenther at suse dot de gcc-bugzilla@gcc.gnu.org
Tue Aug 29 15:35:00 GMT 2017


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82012

--- Comment #6 from rguenther at suse dot de <rguenther at suse dot de> ---
On Tue, 29 Aug 2017, krebbel at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82012
> 
> --- Comment #5 from Andreas Krebbel <krebbel at gcc dot gnu.org> ---
> (In reply to rguenther@suse.de from comment #4)
> > Not sure.  The user might be deliberately expecting an error when
> > such function is called from wrong target context.  The function
> > might contain inline assembly which violates the callers ABI
> > (in this case it might contain hard-float code?).
> 
> In that case the backend would trigger an error. Because floating point
> registers or rather no instruction dealing with them would be enabled. It
> probably would not be a nice one though.
> 
> > Not sure what the libitm use of soft-float is about here.
> 
> We have to prevent call-saved FPRs from being used between the libitm
> transaction begin and the target dependent routine saving the registers.

I see.  For the particular code libitm could simply avoid the
always-inline C++ wrapper and directly call the atomic.

> > I'd say it is valid to inline any function not using FP into
> > a function that differs in "soft-float" state?  Similar to the
> > patch I did to the x86 backend allowing -mfpmath differences
> > in that case.
> 
> Whether a function does not use FPRs is not easy to figure out.  We would just
> go on  and let probably the register allocator complain about no FPRs being
> available.

IPA computes this for us, but only somewhat as it looks for FP expressions
only (hopefully taking all inline asm as containing FP expressions) but
not disallowing FP value loads/stores.  See i386.c:ix86_can_inline_p:

  else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath
           /* If the calle doesn't use FP expressions differences in
              ix86_fpmath can be ignored.  We are called from FEs
              for multi-versioning call optimization, so beware of
              ipa_fn_summaries not available.  */
           && (! ipa_fn_summaries
               || ipa_fn_summaries->get
               (cgraph_node::get (callee))->fp_expressions))

this means the RA would have to load/store to non-FPR registers
which is what soft-float should guarantee.  I think even FP expressions
should work, dispatching to soft-float routines?  So IPA should
compute a inline_asm flag (but even that would need to name FPRs
in the constraints explicitely to be a problem I guess).

> > Would probably fix this particular case.
> > 
> > Consider a flag enabling some vector features, -mfancy-vect, building
> > a TU with said flag and
> > 
> > inline void __attribute__((always_inline)) foo ()
> > {
> >   __builtin_fancy_vect_insn ();
> > }
> > 
> > void __attribute__((target("no-fancy-vect")))
> > {
> >   return foo ();
> > }
> > 
> > with the pre-patched default hook we'd happily inline foo () here
> > (it doesn't have a target attribute!).
> 
> If the extra functionality would be pulled in via builtin the backend
> expand_builtin function is supposed to complain about insufficient target
> flags. This only works if the inlining happened before builtin expansion
> though.
> 
> > Note at runtime such inlining should be always valid(?) (arm folks
> > make thumb vs. non-thumb as an example - not sure if the linker
> > needs to insert special dispatch code when transitioning, so it
> > might not be ok in that case!).  But as insn patterns are
> > usually guarded with some insn-enablement conditions we'd ICE.
> 
> I think the problem is how we make sure to detect if a feature disabled by the
> caller is being used in the callee. I think it should work for builtins (check
> flags in expand_builtin) and it often works for target flags which change the
> set of available registers (e.g. soft-float/hard-float on s390). 
> 
> In inline assemblies it works with soft-float as long as the register allocator
> is required to allocate an FPR.  So we get an error when calling foo2.  But
> unfortunately not for foo which only clobbers an FPR:
> 
> void __attribute__((always_inline))
> foo ()
> {
>   asm volatile ("lzdr %%f0" : : : "%f0");
> }
> 
> void __attribute__((always_inline))
> foo2 ()
> {
>   double a = 1.0;
>   asm volatile ("%0" : : "f" (a));
> }
> 
> void __attribute__((target("soft-float")))
> bar ()
> {
>   foo ();
> }
> 
> It should also work for most of the inline assemblies.  The assembler would
> complain about the special feature instruction not being available with the
> current set of options as long as the compile options are passed to the
> assembler. However, it would not help for instructions specified with .long or
> .insn in the asm snippet.
> 
> t3.c:
> 
> void __attribute__((always_inline))
> foo ()
> {
>   asm volatile ("vaf %v0,%v0,%v0"); // z13 instruction
> }
> 
> void __attribute__((target("arch=zEC12")))
> bar ()
> {
>   foo ();
> }
> 
> cc1plus -O3 t3.c -march=z13
> as t3.s
> t3.c: Assembler messages:
> t3.c:4: Error: Unrecognized opcode: `vaf'
> 
> This works because we pass the function specific options with gas pseudo
> commands to binutils:
> 
>         .machinemode zarch
>         .machine "zEC12"
> .globl _Z3barv
>         .type   _Z3barv, @function
> _Z3barv:
> .LFB1:
>         .cfi_startproc
> #APP
> # 4 "t3.c" 1
>         vaf %v0,%v0,%v0
> # 0 "" 2
> #NO_APP
>         br      %r14
> 
> 
> So for S/390 I currently would tend to always allow inlining regardless of the
> target attributes hoping that the majority of problems would be catched (with
> obscure error messages mostly).

ICEs you mean, or assembler errors.

On x86 we avoid the inlining to not run into obscure ICEs (but got hit
with inline failure errors with -flto due to the "bugs").

Ok, then do that (for always-inline functions I guess).

Richard.


More information about the Gcc-bugs mailing list