On 7/28/21 4:39 PM, Andrew MacLeod wrote:
So Im seeing what appears to me to be inconsistent behaviour.

in pr96094.c we see:

int
foo (int x)
{
   if (x >= 2U)
     return 34;
   return 34 / x;
}

x has a range of [0,1] and since / 0  in undefined, the expectation is that we fold this to "return 34" and vrp1 does this:

  <bb 3> [local count: 767403281]:
   x_6 = ASSERT_EXPR <x_3(D), (unsigned int) x_3(D) <= 1>;
   _4 = 34 / x_6;

   <bb 4> [local count: 1073741824]:
   # _2 = PHI <34(2), _4(3)>

Transformed to

  <bb 3> [local count: 767403281]:
   _4 = 34;

   <bb 4> [local count: 1073741824]:
   # _2 = PHI <34(2), _4(3)>


but if we go to tree-ssa/pr61839_2.c, we see:

   volatile unsigned b = 1U;
   int c = 1;
   c = (a + 972195718) % (b ? 2 : 0);
   if (c == 1)
     ;
   else
     __builtin_abort ();

/* Dont optimize 972195717 / 0 in function foo.  */
/* { dg-final { scan-tree-dump-times "972195717 / " 1  "evrp" } } */


So why is it OK to optimize out the divide in the first case, but not in the second??

IIRC, the code triggering the removal of the first division by zero is the following in match.pd:

/* X / bool_range_Y is X.  */
 (simplify
  (div @0 SSA_NAME@1)
  (if (INTEGRAL_TYPE_P (type) && ssa_name_has_boolean_range (@1))
   @0))

Aldy

Reply via email to