HAO CHEN GUI <guih...@linux.ibm.com> writes: > Hi, > This patch checks available optabs for scalar modes used in by > pieces operations. It fixes the regression cases caused by previous > patch. Now both scalar and vector modes are examined by the same > approach. > > Bootstrapped and tested on x86 and powerpc64-linux BE and LE with no > regressions. Is this OK for trunk? > > Thanks > Gui Haochen > > > ChangeLog > Expand: Checking available optabs for scalar modes in by pieces operations > > The former patch (f08ca5903c7) examines the scalar modes by target > hook scalar_mode_supported_p. It causes some i386 regression cases > as XImode and OImode are not enabled in i386 target function. This > patch examines the scalar mode by checking if the corresponding optabs > are available for the mode. > > gcc/ > PR target/111449 > * expr.cc (qi_vector_mode_supported_p): Rename to... > (by_pieces_mode_supported_p): ...this, and extends it to do > the checking for both scalar and vector mode. > (widest_fixed_size_mode_for_size): Call > by_pieces_mode_supported_p to examine the mode. > (op_by_pieces_d::smallest_fixed_size_mode_for_size): Likewise.
OK, thanks. Richard > patch.diff > diff --git a/gcc/expr.cc b/gcc/expr.cc > index 7aac575eff8..2af9fcbed18 100644 > --- a/gcc/expr.cc > +++ b/gcc/expr.cc > @@ -1000,18 +1000,21 @@ can_use_qi_vectors (by_pieces_operation op) > /* Return true if optabs exists for the mode and certain by pieces > operations. */ > static bool > -qi_vector_mode_supported_p (fixed_size_mode mode, by_pieces_operation op) > +by_pieces_mode_supported_p (fixed_size_mode mode, by_pieces_operation op) > { > + if (optab_handler (mov_optab, mode) == CODE_FOR_nothing) > + return false; > + > if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES) > - && optab_handler (vec_duplicate_optab, mode) != CODE_FOR_nothing) > - return true; > + && VECTOR_MODE_P (mode) > + && optab_handler (vec_duplicate_optab, mode) == CODE_FOR_nothing) > + return false; > > if (op == COMPARE_BY_PIECES > - && optab_handler (mov_optab, mode) != CODE_FOR_nothing > - && can_compare_p (EQ, mode, ccp_jump)) > - return true; > + && !can_compare_p (EQ, mode, ccp_jump)) > + return false; > > - return false; > + return true; > } > > /* Return the widest mode that can be used to perform part of an > @@ -1035,7 +1038,7 @@ widest_fixed_size_mode_for_size (unsigned int size, > by_pieces_operation op) > { > if (GET_MODE_SIZE (candidate) >= size) > break; > - if (qi_vector_mode_supported_p (candidate, op)) > + if (by_pieces_mode_supported_p (candidate, op)) > result = candidate; > } > > @@ -1049,7 +1052,7 @@ widest_fixed_size_mode_for_size (unsigned int size, > by_pieces_operation op) > { > mode = tmode.require (); > if (GET_MODE_SIZE (mode) < size > - && targetm.scalar_mode_supported_p (mode)) > + && by_pieces_mode_supported_p (mode, op)) > result = mode; > } > > @@ -1454,7 +1457,7 @@ op_by_pieces_d::smallest_fixed_size_mode_for_size > (unsigned int size) > break; > > if (GET_MODE_SIZE (candidate) >= size > - && qi_vector_mode_supported_p (candidate, m_op)) > + && by_pieces_mode_supported_p (candidate, m_op)) > return candidate; > } > }