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] |
Yet another latent bug exposed by the upcoming VRP improvements.... When VRP discovers that an SSA_NAME has a nonnegative range it will build a range [0, TYPE_MAX_VALUE (type)]. We can then use that range to eliminate/simplify conditionals. It is imperative that TYPE_MAX_VALUE actually reflect the true maximum value for the type. For example, if TYPE_MAX_VALUE is missing high order bits, the we can (and will) generate incorrect code. Now let's look at fold-const.c::force_fit_type /* Size types *are* sign extended. */ sign_extended_type = (!TYPE_UNSIGNED (TREE_TYPE (t)) || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE && TYPE_IS_SIZETYPE (TREE_TYPE (t)))); We then use sign_extend_type to determine if we should extend the sign bit from whatever precision the type has into the unused bits in our tree representation. So note very carefully that while sizetype might specify an unsigned type, it will be *sign* extended into the unused bits within our tree representation. So, if we're converting an integer -1 (0xffffffffffffffff) into a normal unsigned 32bit type we'd get 0xffffffff. However if we're converting it into a 32bit unsigned sizetype we would get 0xffffffffffffffff. So imagine we have sizetype y; int x; x = (int) y; if (x == -1) The forward propagation code will (correctly) realize that the type conversion is pointless and that the code can be rewritten as sizetype y; int x; x = (int y); /* Likely dead, to be removed by DCE */ if (y == -1) Note that we will have converted -1 from an integer into a sizetype and verified that it's underlying bit representation is unchanged as part of this transformation. Now because y is an unsigned type, we know it must have a nonnegative value. Thus we can build a range for it. Specifically it has the range [0, TYPE_MAX_VALUE (sizetype)]. Our bug is that TYPE_MAX_VALUE (sizetype) has not undergone the same sign extension that other values of sizetype have done. So the range we've built is really [ 0, 0xffffffff ] So we're comparing RANGE of Y Internal representation of -1 [ 0, 0xffffffff] NE 0xffffffffffffffff Which evaluates to true, which is clearly wrong. If TYPE_MAX_VALUE was correctly extended we would have been comparing [ 0, 0xffffffffffffffff] NE 0xffffffffffffffff Which is compile-time unknown, which is correct. [ This shows up inside libjava and causes massive java testsuite failures with the pending VRP improvements. ] This patch fixes TYPE_MAX_VALUE (sizetype) for those targets where sizetype is an unsigned type. I've verified this bootstraps and passes regression testing both standalone and with the pending VRP improvements which exposed the bug on i686-pc-linux-gnu. There is the possibility that this fixes PR26304. I have not looked at it in any significant way yet.
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] |