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]

Fix latent bug in TYPE_MAX_VALUE for sizetype


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]