> maybe check that return_copy_pat is a SET instead? You mean something like this? I tried this but I am not sure single_set is good enough here, because it should be "narrow" than GET_RTX_LENGTH.
+ && single_set (return_copy) Pan -----Original Message----- From: Richard Biener <richard.guent...@gmail.com> Sent: Monday, August 7, 2023 9:14 PM To: Li, Pan2 <pan2...@intel.com> Cc: gcc-patches@gcc.gnu.org; juzhe.zh...@rivai.ai; kito.ch...@sifive.com; Wang, Yanzhang <yanzhang.w...@intel.com>; jeffreya...@gmail.com Subject: Re: [PATCH v1] Mode-Switching: Fix SET_SRC ICE when only one operand On Mon, Aug 7, 2023 at 2:30 PM Pan Li via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > From: Pan Li <pan2...@intel.com> > > In same cases, like gcc/testsuite/gcc.dg/pr78148.c in RISC-V, there will > be only 1 operand when SET_SRC in create_pre_exit. For example as below. > > (insn 13 9 14 2 (clobber (reg/i:TI 10 a0)) > "gcc/testsuite/gcc.dg/pr78148.c":24:1 -1 > (expr_list:REG_UNUSED (reg/i:TI 10 a0) > (nil))) > > Unfortunately, SET_SRC requires at least 2 operands and then Segment > Fault here. This patch would like to fix this ICE by adding operand > length check before SET_SRC. > > Signed-off-by: Pan Li <pan2...@intel.com> > > gcc/ChangeLog: > > * mode-switching.cc (create_pre_exit): Add operand length check. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/mode-switch-ice-1.c: New test. > --- > gcc/mode-switching.cc | 2 ++ > .../gcc.target/riscv/mode-switch-ice-1.c | 22 +++++++++++++++++++ > 2 files changed, 24 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/riscv/mode-switch-ice-1.c > > diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc > index 64ae2bc29c3..cbf03c02159 100644 > --- a/gcc/mode-switching.cc > +++ b/gcc/mode-switching.cc > @@ -411,6 +411,8 @@ create_pre_exit (int n_entities, int *entity_map, const > int *num_modes) > conflict with address reloads. */ > if (copy_start >= ret_start > && copy_start + copy_num <= ret_end > + && GET_RTX_LENGTH (GET_CODE (return_copy_pat)) >= > 2 > + /* SET_SRC requires at least 2 operands. */ maybe check that return_copy_pat is a SET instead? > && OBJECT_P (SET_SRC (return_copy_pat))) > forced_late_switch = true; > break; > diff --git a/gcc/testsuite/gcc.target/riscv/mode-switch-ice-1.c > b/gcc/testsuite/gcc.target/riscv/mode-switch-ice-1.c > new file mode 100644 > index 00000000000..1b34a471904 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/mode-switch-ice-1.c > @@ -0,0 +1,22 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +struct A { char e, f; }; > + > +struct B > +{ > + int g; > + struct A h[4]; > +}; > + > +extern void bar (int, int); > + > +struct B foo (void) > +{ > + bar (2, 1); > +} > + > +void baz () > +{ > + foo (); > +} > -- > 2.34.1 >