Howdy.

I'm looking at the ABS_EXPR code in extract_range_from_unary_expr() and have noticed that by the time we get here:

      /* If a VR_ANTI_RANGEs contains zero, then we have
         ~[-INF, min(MIN, MAX)].  */
      if (vr0.type == VR_ANTI_RANGE)

...we have already handled VR_VARYING, VR_UNDEFINED, and symbolics. Which means, we only have VR_RANGE of constants to deal with. Furthermore, we have previously split a VR_ANTI_RANGE into its constituents and handled them piecemeal:

  /* Now canonicalize anti-ranges to ranges when they are not symbolic
     and express op ~[]  as (op []') U (op []'').  */
  if (vr0.type == VR_ANTI_RANGE
      && ranges_from_anti_range (&vr0, &vrtem0, &vrtem1))

Am I missing something, or is this entire block dead code?

      /* If a VR_ANTI_RANGEs contains zero, then we have
         ~[-INF, min(MIN, MAX)].  */
      if (vr0.type == VR_ANTI_RANGE)
        {
          if (range_includes_zero_p (vr0.min, vr0.max) == 1)
            {
              /* Take the lower of the two values.  */
              if (cmp != 1)
                max = min;

              /* Create ~[-INF, min (abs(MIN), abs(MAX))]
                 or ~[-INF + 1, min (abs(MIN), abs(MAX))] when
                 flag_wrapv is set and the original anti-range doesn't include
                 TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE.  */
              if (TYPE_OVERFLOW_WRAPS (type))
                {
                  tree type_min_value = TYPE_MIN_VALUE (type);

                  min = (vr0.min != type_min_value
                         ? int_const_binop (PLUS_EXPR, type_min_value,
                                            build_int_cst (TREE_TYPE 
(type_min_value), 1))
                         : type_min_value);
                }
              else
                min = TYPE_MIN_VALUE (type);
            }
          else
            {
              /* All else has failed, so create the range [0, INF], even for
                 flag_wrapv since TYPE_MIN_VALUE is in the original
                 anti-range.  */
              vr0.type = VR_RANGE;
              min = build_int_cst (type, 0);
              max = TYPE_MAX_VALUE (type);
            }
        }

I tried putting a gcc_unreachable() there, and it never gets triggered in either a bootstrap or a full test run. I also tried exercising programmatically extract_range_from_unary_expr() for the entire domain of a signed char and unsigned char, with and without flag_wrapv (ranges and anti-ranges), and I can't get the above code to trigger.

Thanks.
Aldy

Reply via email to