On Tue, Nov 5, 2024 at 10:38 AM Richard Biener <richard.guent...@gmail.com> wrote:
> > > >> So I think we need to conclude whether or not the testcase is valid or > > > >> not first. > > > > > > > > This is what x86 linux kernel uses (arch/x86/include/asm/asm.h) as a > > > > scheduling barrier to prevent asm from being scheduled before stack > > > > frame is constructed: > > > Just because the kernel does it, doesn't make it right :-) > > > > True, it was not my intention to declare the usage in the kernel the > > correct one ;) . There is in fact PR [1] with a request for what is > > the correct construct to use to prevent scheduling in front of the > > frame pointer initialization (and other issues with changing SP) in > > case when assembly changes (not clobbers!) the stack pointer. > > > > [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117311 > > > > > ~~~~~~~~~~~~~~ > > > > > > > > OTOH, declaring and using %rsp as a global register variable doesn't > > > > error out, so one would expect that it would be used throughout the > > > > compiler as an alias to the internal stack pointer. The presented > > > > testcase exposes one place where this assumption doesn't hold. > > > But maybe it should error out or should be transformed internally to > > > reference the singleton rtx object. > > > > Adding a SP clobber to asm: > > > > void bar (void) > > { > > asm volatile ("#" : : : "rsp"); > > } > > > > results in: > > > > warning: listing the stack pointer register ‘rsp’ in a clobber list is > > deprecated [-Wdeprecated] > > note: the value of the stack pointer after an ‘asm’ statement must be > > the same as it was before the statement > > > > But what is the non-deprecated way to communicate the fact that SP > > changes, and possibly clobbers stack in the asm to the compiler? > > I don't think there's an existing way to tell the compiler that "arbitrary > stack > locations" are clobbered (SP doesn't really change). Only stack portions > allocated to variables are considered clobbered with a "memory" clobber. Perhaps I was not clear enough; the asm is not allowed, and will not clobber the frame that is allocated and used by the function. IOW, when the function allocates its frame, the asm will not touch it. When the frame is setup, we have this situation: ---- previous SP function frame ---- current SP <- we are here Here, the asm pushes some value to the stack, either directly using push/pop or indirectly using call insn. Considering the case without redzone, if the function frame is correctly set up, then the asm can push and pop values at will, assuming that at the end it sets the SP value to its original value. To prevent unwanted scheduling of the asm (where asm is moved before stack frame creation or after stack frame teardown), the linux kernel uses ASM_CALL_CONSTRAINT to depend asm on the RSP. Now, we would like to compile the (kernel) source with redzone support (-mred-zone). In this case we have to prevent redzone creation when the function uses asm that "hides" call insn (or push/pop). The function that uses asm with hidden call instruction is *not* leaf anymore, and if it is classified as such, the call or push/pop combo inside asm clobbers *redzone* of the leaf function. The compiler already detects when push/pop RTX is used in the instruction stream and cancels redzone creation (via crtl->sp_is_unchanging). However, the compiler currently doesn't detect when SP is used as output register in the asm (when ASM_CALL_CONSTRAINT is used), because it uses *pointer comparison* with stack_pointer_rtx instead of rtx_equal_p (reg, stack_pointer_rtx). Pointer comparison does not detect that "(reg/v:DI 7 sp [ current_stack_pointer ])" and "(reg/f:DI 7 sp)" RTXes actually both correspond to the same stack pointer register. The above pointer comparisons with stack_pointer_rtx are used throughout the compiler source, so if one is able to manually create RTX that corresponds to the same stack pointer register number, the compiler won't detect equality. This is a deficiency I would like to point out. Uros.