On Wed, Nov 6, 2024 at 2:50 PM Jakub Jelinek <ja...@redhat.com> wrote: > > Hi! > > The following patch adds a "redzone" clobber (recognized just > on targets which choose to recognize it, right now just x86), > with which one can mark the rare case where inline asm pushes > something on the stack or uses call instruction without taking > red zone into account (i.e. addq $-128, %rsp; and addq $128, %rsp > around that).
Maybe we should always recognize "redzone", even for targets without it. This is the way we recognize "cc" even for targets without CC reg (e.g. alpha). This would simplify the definition and processing - if the hook returns NULL_RTX (the default), then it (obviously) won't be added to the clobber list. If someone adds "redzone" clobber to the target without redzone it won't hurt if it is simply ignored. > 2024-11-06 Jakub Jelinek <ja...@redhat.com> > > gcc/ > * target.def (redzone_clobber): New target hook. > * varasm.cc (decode_reg_name_and_count): Return -5 for > "redzone". > * cfgexpand.cc (expand_asm_stmt): Handle redzone clobber. > * config/i386/i386.h (struct machine_function): Add > asm_redzone_clobber_seen member. > * config/i386/i386.cc (ix86_compute_frame_layout): Don't > use red zone if cfun->machine->asm_redzone_clobber_seen. > (ix86_redzone_clobber): New function. > (TARGET_REDZONE_CLOBBER): Redefine. > * doc/extend.texi (Clobbers and Scratch Registers): Document > the "redzone" clobber. > * doc/tm.texi.in: Add @hook TARGET_REDZONE_CLOBBER. > * doc/tm.texi: Regenerate. > gcc/testsuite/ > * gcc.target/i386/asm-redzone-1.c: New test. > > --- gcc/target.def.jj 2024-10-25 10:00:29.525767041 +0200 > +++ gcc/target.def 2024-11-06 13:32:39.376320955 +0100 > @@ -3376,6 +3376,18 @@ to be used.", > bool, (machine_mode mode), > NULL) > > +DEFHOOK > +(redzone_clobber, > + "Define this to return some RTL for the @code{redzone} @code{asm} clobber\n\ > +if target has a red zone and wants to support the @code{redzone} clobber\n\ > +or return NULL if the clobber shouldn't be recognized or return\n\ > +@code{pc_rtx} if the clobber should be recognized but should not be added\n\ > +to the list of clobbers.\n\ > +\n\ > +The default is not to support the @code{redzone} clobber.", > + rtx, (), > + NULL) > + > /* Support for named address spaces. */ > #undef HOOK_PREFIX > #define HOOK_PREFIX "TARGET_ADDR_SPACE_" > --- gcc/varasm.cc.jj 2024-11-06 10:23:21.215728007 +0100 > +++ gcc/varasm.cc 2024-11-06 12:21:17.891908352 +0100 > @@ -967,9 +967,11 @@ set_user_assembler_name (tree decl, cons > > /* Decode an `asm' spec for a declaration as a register name. > Return the register number, or -1 if nothing specified, > - or -2 if the ASMSPEC is not `cc' or `memory' and is not recognized, > + or -2 if the ASMSPEC is not `cc' or `memory' or `redzone' and is not > + recognized, > or -3 if ASMSPEC is `cc' and is not recognized, > or -4 if ASMSPEC is `memory' and is not recognized. Comma at the end of this part of the sentence. > + or -5 if ASMSPEC is `redzone' and is not recognized. > Accept an exact spelling or a decimal number. > Prefixes such as % are optional. */ > > @@ -1036,6 +1038,9 @@ decode_reg_name_and_count (const char *a > } > #endif /* ADDITIONAL_REGISTER_NAMES */ > > + if (!strcmp (asmspec, "redzone")) > + return -5; > + > if (!strcmp (asmspec, "memory")) > return -4; > > --- gcc/cfgexpand.cc.jj 2024-11-05 08:55:41.610187084 +0100 > +++ gcc/cfgexpand.cc 2024-11-06 14:26:07.684918717 +0100 > @@ -3193,6 +3193,19 @@ expand_asm_stmt (gasm *stmt) > j = decode_reg_name_and_count (regname, &nregs); > if (j < 0) > { > + if (j == -5) > + { > + rtx x = NULL_RTX; > + if (targetm.redzone_clobber) > + x = targetm.redzone_clobber (); > + if (x == pc_rtx) > + /* Recognize it but don't add anything to > + clobber_rvec. */; > + else if (x) > + clobber_rvec.safe_push (x); > + else > + j = -2; > + } > if (j == -2) > { > /* ??? Diagnose during gimplification? */ > @@ -3208,8 +3221,9 @@ expand_asm_stmt (gasm *stmt) > else > { > /* Otherwise we should have -1 == empty string > - or -3 == cc, which is not a register. */ > - gcc_assert (j == -1 || j == -3); > + or -3 == cc, which is not a register or > + -5 == redzone, ditto. */ > + gcc_assert (j == -1 || j == -3 || j == -5); > } > } > else > --- gcc/config/i386/i386.h.jj 2024-11-05 08:55:41.663186325 +0100 > +++ gcc/config/i386/i386.h 2024-11-06 14:11:42.893154474 +0100 > @@ -2881,6 +2881,9 @@ struct GTY(()) machine_function { > /* True if red zone is used. */ > BOOL_BITFIELD red_zone_used : 1; > > + /* True if inline asm with redzone clobber has been seen. */ > + BOOL_BITFIELD asm_redzone_clobber_seen : 1; > + > /* The largest alignment, in bytes, of stack slot actually used. */ > unsigned int max_used_stack_alignment; > > --- gcc/config/i386/i386.cc.jj 2024-11-05 08:55:41.661186354 +0100 > +++ gcc/config/i386/i386.cc 2024-11-06 14:12:52.560168428 +0100 > @@ -7172,7 +7172,8 @@ ix86_compute_frame_layout (void) > && crtl->sp_is_unchanging > && crtl->is_leaf > && !ix86_pc_thunk_call_expanded > - && !ix86_current_function_calls_tls_descriptor) > + && !ix86_current_function_calls_tls_descriptor > + && !cfun->machine->asm_redzone_clobber_seen) Please put the new check just after crtl-> checks. Thanks, Uros.