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] |
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] |