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

            Bug ID: 80558
           Summary: VRP not handling x & -2 well
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

The VRP handling of BIT_AND_EXPR when one of the operands is a INTEGER_CST mask
with all 1 bits starting from MSB followed by only 0 bits is not good enough.
Consider:
void link_error (void);

void
foo (int x)
{
  if (x >= 5 && x <= 19)
    {
      x &= -2;
      if (x < 4 || x > 18)
        link_error ();
    }
}
With assertions we have:
  x_10 = ASSERT_EXPR <x_6(D), (unsigned int) x_6(D) + 4294967291 <= 14>;
  x_8 = x_10 & -2;
and properly compute:
x_10: [5, 19]  EQUIVALENCES: { x_6(D) } (1 elements)
but for x_8 we generate an unnecessarily wide range:
x_8: [0, 19]
while
x_8: [4, 18]
is the right result.  Shall we special case BIT_AND_EXPR with one of the
operands a singleton range equal to wi::shifted_mask (start, precision - start,
false, precision) for some value of start (i.e. one where its negation is a
power of 2)?  If the other range is VR_RANGE, I think we can just mask the min
and max, maybe something similar even for anti range?

Reply via email to