Message ID | 20241010152452.1205387-1-victor.donascimento@arm.com |
---|---|
State | New |
Headers | show |
Series | middle-end: [PR middle-end/116926] Allow widening optabs for vec-mode -> scalar-mode | expand |
On Thu, Oct 10, 2024 at 5:25 PM Victor Do Nascimento <victor.donascimento@arm.com> wrote: > > The recent refactoring of the dot_prod optab to convert-type exposed a > limitation in how `find_widening_optab_handler_and_mode' is currently > implemented, owing to the fact that, while the function expects the > > GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode) > > condition to hold, the c6x backend implements a dot product from V2HI > to SI, which triggers an ICE. > > Consequently, this patch adds some logic to allow widening optabs > which accumulate vector elements to a single scalar. > > Regression tested on x86_64 and aarch64 with no new regressions. > Fixes failing unit tests on c6x, as validated for the tic6x-unknown-elf > target. > > Ok for master? > > gcc/ChangeLog: > > PR middle-end/116926 > * optabs-query.cc (find_widening_optab_handler_and_mode): Add > handling of vector -> scalar optab handling. > --- > gcc/optabs-query.cc | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > > diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc > index c3134d6a2ce..8a9092ffec7 100644 > --- a/gcc/optabs-query.cc > +++ b/gcc/optabs-query.cc > @@ -485,6 +485,19 @@ find_widening_optab_handler_and_mode (optab op, machine_mode to_mode, > if (GET_MODE_CLASS (limit_mode) == MODE_PARTIAL_INT) > limit_mode = GET_MODE_WIDER_MODE (limit_mode).require (); > } > + else if (GET_MODE_CLASS (from_mode) != GET_MODE_CLASS (to_mode)) > + { > + gcc_checking_assert (VECTOR_MODE_P (from_mode) > + && !VECTOR_MODE_P (to_mode) > + && GET_MODE_INNER (from_mode) < to_mode); > + enum insn_code handler = convert_optab_handler (op, to_mode, from_mode); > + if (handler != CODE_FOR_nothing) > + { > + if (found_mode) > + *found_mode = from_mode; > + return handler; > + } else if (is_a <scalar_int_mode> (to_mode)) { gcc_checking_assert (VECTOR_MODE_P (from_mode) && GET_MODE_INNER (from_mode) < to_mode); limit_mode = from_mode; } else ... would also work? Thanks, Richard. > + } > else > gcc_checking_assert (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode) > && from_mode < to_mode); > -- > 2.34.1 >
On 10/11/24 08:28, Richard Biener wrote: > On Thu, Oct 10, 2024 at 5:25 PM Victor Do Nascimento > <victor.donascimento@arm.com> wrote: >> >> The recent refactoring of the dot_prod optab to convert-type exposed a >> limitation in how `find_widening_optab_handler_and_mode' is currently >> implemented, owing to the fact that, while the function expects the >> >> GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode) >> >> condition to hold, the c6x backend implements a dot product from V2HI >> to SI, which triggers an ICE. >> >> Consequently, this patch adds some logic to allow widening optabs >> which accumulate vector elements to a single scalar. >> >> Regression tested on x86_64 and aarch64 with no new regressions. >> Fixes failing unit tests on c6x, as validated for the tic6x-unknown-elf >> target. >> >> Ok for master? >> >> gcc/ChangeLog: >> >> PR middle-end/116926 >> * optabs-query.cc (find_widening_optab_handler_and_mode): Add >> handling of vector -> scalar optab handling. >> --- >> gcc/optabs-query.cc | 13 +++++++++++++ >> 1 file changed, 13 insertions(+) >> >> diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc >> index c3134d6a2ce..8a9092ffec7 100644 >> --- a/gcc/optabs-query.cc >> +++ b/gcc/optabs-query.cc >> @@ -485,6 +485,19 @@ find_widening_optab_handler_and_mode (optab op, machine_mode to_mode, >> if (GET_MODE_CLASS (limit_mode) == MODE_PARTIAL_INT) >> limit_mode = GET_MODE_WIDER_MODE (limit_mode).require (); >> } >> + else if (GET_MODE_CLASS (from_mode) != GET_MODE_CLASS (to_mode)) >> + { >> + gcc_checking_assert (VECTOR_MODE_P (from_mode) >> + && !VECTOR_MODE_P (to_mode) >> + && GET_MODE_INNER (from_mode) < to_mode); >> + enum insn_code handler = convert_optab_handler (op, to_mode, from_mode); >> + if (handler != CODE_FOR_nothing) >> + { >> + if (found_mode) >> + *found_mode = from_mode; >> + return handler; >> + } > > else if (is_a <scalar_int_mode> (to_mode)) > { > gcc_checking_assert (VECTOR_MODE_P (from_mode) > && GET_MODE_INNER > (from_mode) < to_mode); > limit_mode = from_mode; > } > else > ... > > would also work? You're absolutely right, much better. Patch resubmitted. Many thanks, Victor. > Thanks, > Richard. > >> + } >> else >> gcc_checking_assert (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode) >> && from_mode < to_mode); >> -- >> 2.34.1 >>
diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc index c3134d6a2ce..8a9092ffec7 100644 --- a/gcc/optabs-query.cc +++ b/gcc/optabs-query.cc @@ -485,6 +485,19 @@ find_widening_optab_handler_and_mode (optab op, machine_mode to_mode, if (GET_MODE_CLASS (limit_mode) == MODE_PARTIAL_INT) limit_mode = GET_MODE_WIDER_MODE (limit_mode).require (); } + else if (GET_MODE_CLASS (from_mode) != GET_MODE_CLASS (to_mode)) + { + gcc_checking_assert (VECTOR_MODE_P (from_mode) + && !VECTOR_MODE_P (to_mode) + && GET_MODE_INNER (from_mode) < to_mode); + enum insn_code handler = convert_optab_handler (op, to_mode, from_mode); + if (handler != CODE_FOR_nothing) + { + if (found_mode) + *found_mode = from_mode; + return handler; + } + } else gcc_checking_assert (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode) && from_mode < to_mode);