Committed as r14-5001. Thanks Gui Haochen
在 2023/10/27 17:29, Richard Sandiford 写道: > 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; >> } >> }