https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94779

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amacleod at redhat dot com

--- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, for start I think we should do:
1) query->range_of_expr (m_index_range, m_index_expr, swtch)
   where query is address of gimple_ranger passed down from the caller
   to figure out range of the index expression; case labels without CASE_HIGH
for
   which m_index_range.contains_p (CASE_LOW (case)) is false can be ignored
   for the optimization (well, handled the way it is better for the
optimization)
   For CASE_HIGH labels, similarly query if the range overlaps the index range.
   Note, I don't remember exactly in which way the types of the index
expression
   and of the case labels can differ, I believe all case labels have to have
the
   same type, so probably for the computation of the range if it has different
   type from the case label ones, it needs to call something that would emulate
   the effect of conversion to that type (or vice versa?)
   CCing Andrew for the range stuff
2) similarly, cases that refer to blocks which have EDGE_COUNT (bb->succs) == 0
   && gimple_seq_unreachable_p (bb_seq (bb)) should be treated again like cases
   one shouldn't need to care about
3) to handle the #c0 testcase in C (C++ already adds __builtin_unreachable),
   handle also the case where case refers to block which has EDGE_COUNT
(bb->succs) and ends in GIMPLE_RETURN without expression in a function that
   returns integral or pointer value (for simplicity) and has no statements
   other than debug stmts or clobber stmts before it.  Note, this case can't be
   treated completely like a UB case, there is no UB in C unless the caller
   checks the return value, but it could be handled conditionally, as long as
   the code we emit for that doesn't invoke UB in the function, we really don't 
   care about the value we return to the caller.  So e.g. if we are considering
   a linear function and other case labels return that linear value and some
   return unspecified value, just use the linear function to cover those too.
4) to be able to optimize the int f1(unsigned x) { if (x >= 3)
__builtin_unreachable();
   switch (x) { case 0: return 1; case 1: return 2; case 2: return 3; } }
   testcase, we should for consideration virtually undo the evrp optimization
   which removed the case 0: and replaced it with default: - here the handled
   cases (that should include the really handled ones and ones that and the
   UB ones (if the case is outside of range or __builtin_unreachable) cover
   everything but one case, assume the default label is that for that single
   case rather than handling anything else; similarly, if the whole range
   is covered, ignore the default label

Reply via email to