On Wed, Jun 13, 2018 at 09:58:49AM +0200, Jakub Jelinek wrote:
> I'm actually worried about the fold-const.c change and don't understand, why
> it has been done at all in the context of this PR.
> 
>         case SAVE_EXPR:
>           if (flags & OEP_LEXICOGRAPHIC)
>             return OP_SAME (0);
>           return 0;
> 
> means it does something different from the state before the patch:
>       default:
>         return 0;
> only if OEP_LEXICOGRAPHIC is set, which AFAIK is only in the
> -Wduplicated-branches warning code, so why it is needed for
> -Wstringop-truncation warning is unclear to me.  More importantly,
> especially -fsanitize=undefined has a tendency of creating trees
> which contain two or more uses of the same SAVE_EXPR at each level, and very
> deep nesting levels of such SAVE_EXPRs, so if we handle it without checking
> for duplicates, it results in exponential compile time complexity.
> So, if we really want to handle SAVE_EXPR here, we'd need to create some
> cache where we'd remember if in the same toplevel operand_equal_p call we've
> already compared two particular SAVE_EXPRs and what was the result.

Random testcase for -Wduplicated-branches -fsanitize=shift:
int
foo (int x, int y)
{
  if (x)
    y = y << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 
<< 1 >> 1
          << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 
<< 1 >> 1
          << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 
<< 1 >> 1
          << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 
<< 1 >> 1;
  else
    y = y << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 
<< 1 >> 1
          << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 
<< 1 >> 1
          << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 
<< 1 >> 1
          << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 << 1 >> 1 
<< 1 >> 1;
  return y;
}

Though it seems we have that problem already in inchash::add_expr.  In that
case perhaps we could have a pointer to a hashmap in inchash::hash objects,
clear it in the ctors and destroy/clear in inchash::hash::end (), though we
have the add_commutative that has two separate hash objects.

        Jakub

Reply via email to