Re: Re: [PATCH 3/4] [RISC-V] resolve confilct between zcmp multi push/pop and shrink-wrap-separate
On 2023-06-13 03:26 Jeff Law wrote: > > > >On 6/6/23 23:52, Fei Gao wrote: >> Disable zcmp multi push/pop if shrink-wrap-separate is active. >> >> So in -Os that prefers smaller code size, by default shrink-wrap-separate >> is disabled while zcmp multi push/pop is enabled. >> >> And in -O2 and others that prefers speed, by default shrink-wrap-separate >> is enabled while zcmp multi push/pop is disabled. To force enabling zcmp >> multi >> push/pop in this case, -fno-shrink-wrap-separate has to be explictly given. >> >> The following TC shows the issues in -O2 before this patch with both >> shrink-wrap-separate and zcmp multi push/pop active. >> 1. duplicated store of s regs. >> 2. cm.push pushes ra, s0-s11 in reverse order than what normal >> prologue does, causing stack corruption and failure to resotre s regs. >> >> TC: zcmp_shrink_wrap_separate.c included in this patch. >> >> output asm before this patch: >> calc_func: >> cm.push {ra, s0-s3}, -32 >> ... >> beq a5,zero,.L2 >> ... >> .L2: >> ... >> sw s1,20(sp) //issue here >> sw s3,12(sp) //issue here >> ... >> sw s2,16(sp) //issue here >> >> output asm after this patch: >> calc_func: >> addi sp,sp,-32 >> sw s0,24(sp) >> ... >> beq a5,zero,.L2 >> ... >> .L2: >> ... >> sw s1,20(sp) >> sw s3,12(sp) >> ... >> sw s2,16(sp) >> gcc/ChangeLog: >> >> * config/riscv/riscv.cc >> (riscv_avoid_shrink_wrapping_separate): wrap the condition check in >> riscv_avoid_shrink_wrapping_separate. >> (riscv_avoid_multi_push): avoid multi push if >>shrink_wrapping_separate >> is active. >> (riscv_get_separate_components): call >>riscv_avoid_shrink_wrapping_separate >> * shrink-wrap.cc (try_shrink_wrapping_separate): call >> use_shrink_wrapping_separate. >> (use_shrink_wrapping_separate):wrap the condition >> check in use_shrink_wrapping_separate >> * shrink-wrap.h (use_shrink_wrapping_separate): add to extern >> >> gcc/testsuite/ChangeLog: >> >> * gcc.target/riscv/zcmp_shrink_wrap_separate.c: New test. >> * gcc.target/riscv/zcmp_shrink_wrap_separate2.c: New test. >I know Kito asked for this to be broken up into target dependent vs >target independent changes, that's a good ask. > >Can't we utilize the get_separate_components hook to accomplish what >you're trying to do? ie, put the logic to avoid shrink wrapping for >this case within the existing risc-v hook? Thank Jeff and Kito for your comments. My first try was to avoid shrink wrapping if zcmp is enabled. But after discussion with Kito and Andrew Pinski, I realized it's better to disable zcmp push and pops if shrink wrapping is active. For detailed discussion, please check link below. thread: [PATCH 1/2] [RISC-V] disable shrink-wrap-separate if zcmp enabled. link: https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg307203.html I will go ahead with Kito's advice if you're fine with the current solution. Thanks. BR, Fei > >jeff
Re: [PATCH 3/4] [RISC-V] resolve confilct between zcmp multi push/pop and shrink-wrap-separate
On 6/6/23 23:52, Fei Gao wrote: Disable zcmp multi push/pop if shrink-wrap-separate is active. So in -Os that prefers smaller code size, by default shrink-wrap-separate is disabled while zcmp multi push/pop is enabled. And in -O2 and others that prefers speed, by default shrink-wrap-separate is enabled while zcmp multi push/pop is disabled. To force enabling zcmp multi push/pop in this case, -fno-shrink-wrap-separate has to be explictly given. The following TC shows the issues in -O2 before this patch with both shrink-wrap-separate and zcmp multi push/pop active. 1. duplicated store of s regs. 2. cm.push pushes ra, s0-s11 in reverse order than what normal prologue does, causing stack corruption and failure to resotre s regs. TC: zcmp_shrink_wrap_separate.c included in this patch. output asm before this patch: calc_func: cm.push {ra, s0-s3}, -32 ... beq a5,zero,.L2 ... .L2: ... sw s1,20(sp) //issue here sw s3,12(sp) //issue here ... sw s2,16(sp) //issue here output asm after this patch: calc_func: addisp,sp,-32 sw s0,24(sp) ... beq a5,zero,.L2 ... .L2: ... sw s1,20(sp) sw s3,12(sp) ... sw s2,16(sp) gcc/ChangeLog: * config/riscv/riscv.cc (riscv_avoid_shrink_wrapping_separate): wrap the condition check in riscv_avoid_shrink_wrapping_separate. (riscv_avoid_multi_push): avoid multi push if shrink_wrapping_separate is active. (riscv_get_separate_components): call riscv_avoid_shrink_wrapping_separate * shrink-wrap.cc (try_shrink_wrapping_separate): call use_shrink_wrapping_separate. (use_shrink_wrapping_separate):wrap the condition check in use_shrink_wrapping_separate * shrink-wrap.h (use_shrink_wrapping_separate): add to extern gcc/testsuite/ChangeLog: * gcc.target/riscv/zcmp_shrink_wrap_separate.c: New test. * gcc.target/riscv/zcmp_shrink_wrap_separate2.c: New test. I know Kito asked for this to be broken up into target dependent vs target independent changes, that's a good ask. Can't we utilize the get_separate_components hook to accomplish what you're trying to do? ie, put the logic to avoid shrink wrapping for this case within the existing risc-v hook? jeff
Re: [PATCH 3/4] [RISC-V] resolve confilct between zcmp multi push/pop and shrink-wrap-separate
I would suggest breaking this patch into two parts: RISC-V part and the rest part (shrink-wrap.h / shrink-wrap.cc). On Wed, Jun 7, 2023 at 1:55 PM Fei Gao wrote: > > Disable zcmp multi push/pop if shrink-wrap-separate is active. > > So in -Os that prefers smaller code size, by default shrink-wrap-separate > is disabled while zcmp multi push/pop is enabled. > > And in -O2 and others that prefers speed, by default shrink-wrap-separate > is enabled while zcmp multi push/pop is disabled. To force enabling zcmp multi > push/pop in this case, -fno-shrink-wrap-separate has to be explictly given. > > The following TC shows the issues in -O2 before this patch with both > shrink-wrap-separate and zcmp multi push/pop active. > 1. duplicated store of s regs. > 2. cm.push pushes ra, s0-s11 in reverse order than what normal >prologue does, causing stack corruption and failure to resotre s regs. > > TC: zcmp_shrink_wrap_separate.c included in this patch. > > output asm before this patch: > calc_func: > cm.push {ra, s0-s3}, -32 > ... > beq a5,zero,.L2 > ... > .L2: > ... > sw s1,20(sp) //issue here > sw s3,12(sp) //issue here > ... > sw s2,16(sp) //issue here > > output asm after this patch: > calc_func: > addisp,sp,-32 > sw s0,24(sp) > ... > beq a5,zero,.L2 > ... > .L2: > ... > sw s1,20(sp) > sw s3,12(sp) > ... > sw s2,16(sp) > gcc/ChangeLog: > > * config/riscv/riscv.cc > (riscv_avoid_shrink_wrapping_separate): wrap the condition check in > riscv_avoid_shrink_wrapping_separate. > (riscv_avoid_multi_push): avoid multi push if shrink_wrapping_separate > is active. > (riscv_get_separate_components): call > riscv_avoid_shrink_wrapping_separate > * shrink-wrap.cc (try_shrink_wrapping_separate): call > use_shrink_wrapping_separate. > (use_shrink_wrapping_separate):wrap the condition > check in use_shrink_wrapping_separate > * shrink-wrap.h (use_shrink_wrapping_separate): add to extern > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/zcmp_shrink_wrap_separate.c: New test. > * gcc.target/riscv/zcmp_shrink_wrap_separate2.c: New test. > > Signed-off-by: Fei Gao > Co-Authored-By: Zhangjin Liao > --- > gcc/config/riscv/riscv.cc | 19 +++- > gcc/shrink-wrap.cc| 25 +++-- > gcc/shrink-wrap.h | 1 + > .../riscv/zcmp_shrink_wrap_separate.c | 97 +++ > .../riscv/zcmp_shrink_wrap_separate2.c| 97 +++ > 5 files changed, 228 insertions(+), 11 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/riscv/zcmp_shrink_wrap_separate.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/zcmp_shrink_wrap_separate2.c > > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index f60c241a526..b505cdeca34 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -64,6 +64,7 @@ along with GCC; see the file COPYING3. If not see > #include "cfghooks.h" > #include "cfgloop.h" > #include "cfgrtl.h" > +#include "shrink-wrap.h" > #include "sel-sched.h" > #include "fold-const.h" > #include "gimple-iterator.h" > @@ -389,6 +390,7 @@ static const struct riscv_tune_param > optimize_size_tune_info = { >false, /* use_divmod_expansion */ > }; > > +static bool riscv_avoid_shrink_wrapping_separate (); > static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *); > static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *); > > @@ -4910,6 +4912,8 @@ riscv_avoid_multi_push(const struct riscv_frame_info > *frame) >|| cfun->machine->interrupt_handler_p >|| cfun->machine->varargs_size != 0 >|| crtl->args.pretend_args_size != 0 > + || (use_shrink_wrapping_separate () > + && !riscv_avoid_shrink_wrapping_separate ()) >|| (frame->mask & ~ MULTI_PUSH_GPR_MASK)) > return true; > > @@ -6077,6 +6081,17 @@ riscv_epilogue_uses (unsigned int regno) >return false; > } > > +static bool > +riscv_avoid_shrink_wrapping_separate () > +{ > + if (riscv_use_save_libcall (&cfun->machine->frame) > + || cfun->machine->interrupt_handler_p > + || !cfun->machine->frame.gp_sp_offset.is_constant ()) > +return true; > + > + return false; > +} > + > /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */ > > static sbitmap > @@ -6086,9 +6101,7 @@ riscv_get_separate_components (void) >sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER); >bitmap_clear (components); > > - if (riscv_use_save_libcall (&cfun->machine->frame) > - || cfun->machine->interrupt_handler_p > - || !cfun->machine->frame.gp_sp_offset.is_constant ()) > + if (ris