https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82012
--- Comment #5 from Andreas Krebbel <krebbel at gcc dot gnu.org> --- (In reply to rguent...@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'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. > 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).