This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Improve VRP's ability to deal with type conversions



When the VRP code encounters a cast, it typically drops the result of 
the cast to VR_VARYING, even if it could trivially represent the value
in the result type (particularly singleton ranges).

This in turn prevents the VRP code from propagating ranges are far as
it could, and in the case of a singleton range prevents propagation of
the singleton range to all its uses.

This happens relatively often within GCC's internal checking code --
consider this fragment (simplified from actual checking code):

  if ((enum tree_code) t->common.code) != COND_EXPR)
    tree_check_failed (...)
  if (i >= tree_code_length[(int)(enum tree_code) t->common.code)
    tree_operand_check_failed (...)



Which looks something like this in gimple (t->common.code is a common
subexpression):

 if (xxx != COND_EXPR)
   tree_check_failed (...)

 yyy = (int) xxx;
 lentmp = tree_code_length[yyy];
 if (i >= lentmp)
   tree_operand_check_failed (...)



When we hit the statement yyy = (int) xxx; we know that xxx  will have
the value COND_EXPR (which is a known integer value).  However, we will
not record a range for yyy because of the cast, even though yyy can
trivially hold the value of COND_EXPR.

Failure to record the singleton range for yyy results in not propagating
the value into the ARRAY_REF.

These would be caught by DOM, but it seems rather silly to not handle
this case in VRP.  Particularly when you look at larger contexts where
these fragments appear together (think about looking at each operand in
a multi-operand _EXPR node).  The tree_code_length[yyy] becomes a common
subexpression, and the range check on the operand number can either be
simplified or in some cases eliminated in the later fragments.  And, yes
DOM is able to detect and optimize all this crud.....

Anyway, this patch allows VRP to discover ranges for some NOP_EXPR and
CONVERT_EXPR expressions.   The interesting cases to consider are:

Widening, both types have same signedness:
  Trivial case since the widened type can trivially represent all the
  values of the original type.

Widening unsigned to signed:
  Also trivial since the widened type can trivially represent all the
  values of the original type.

Widening signed to unsigned:
  We have to be careful here when presented with a range which has
  both positive and negative values such as [-1..1], 8 bit type.  This
  range has precisely three values, -1, 0, 1.  When we convert the range
  to the new type we get [0xffffffff .. 1], 32 bit type).  This is not
  a valid range and it will be rejected.

  Note that converting something like [-128 .. -1], 8 bit type to a
  32bit unsigned results in [0xffffff80 .. 0xffffffff], which is a
  valid range and correctly represents the possible set of values.
  However, I'm pretty sure we don't record this range -- ie, the
  code is probably a little over-conservative.

Same bitsize, same signedness:
  Trivial case.  New type can trivially represent all the values of
  the original type.

Same bitsize, unsigned to signed:
  The worry here, is of course overflow when converting to the signed
  type.  The code to compare the original min/max values to the
  converted min/max values will reject these as the original min/max
  values will not compare equal to the converted min/max values.

Same bitsize, signed to unsigned
  Similar to the unsigned to signed case and will be rejected by
  the code to compare the original min/max values to the converted
  min/max values.

Narrowing, with or without a signedness change
  Like the cases of same bitsize, the problem here is when the
  min/max values in the range can not be represented in the 
  converted type.  When this occurs the code to compare the
  original min/max values to the converted min/max values will
  reject the range.


Bootstrapped and regression tested on i686-pc-linux-gnu, I've also
added a minimized testcase to the testsuite.












Attachment: PPP
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]