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]

Re: [patch] Fix pr23046


On Sun, Sep 18, 2005 at 09:12:24PM -0600, Roger Sayle wrote:
> On Sun, 18 Sep 2005, Richard Henderson wrote:
> > Roger's cop-out in the c++ front end is unfortunate, especially since
> > the middle-end does handle zero or sign extending values to fill the
> > mode -- it does exactly that for C.
> 
> I only wish this were true!

What's reduce_to_bit_field_precision then?  Certainly it is _intended_
to handle exactly this case.  Are you claiming that we're missing calls
to it, or what?

> In my mind, you over simplify the problem with your three options,
> (1), (2) and (3), but miss the key issue, which is that given a partial
> mode type with TYPE_MIN_VALUE and TYPE_MAX_VALUE what can the
> optimizers assume (at run-time) about a value from such a type held
> in a register/pseudo.

This is *exactly* option 3.  In what way was this not clear from my post?

> Ada may well be able to describe a type with
> bounds between 2 and 10, but where/who is responsible for ensuring
> variables of that type are always in the prescribed range and
> correctly sign or zero extended.

If the bounds are not exactly those representable in the precision,
then it's the job of the front end to enforce the bounds.  Or to
ignore the bounds and declare that the user must have ensured it,
and any failure on the user's part is a violation of language rules.

But in either case, the optimizers would be free to assume ANY value
is in fact within bounds of its type.

> In C++, if we generate no additional
> RTL for the assignment of an integer to an enumerated type, then as
> far as the optimizers are concerned variables can potentially hold
> any value in the specified mode.

Well, the C++ front end is (or was, before your change) assigning to
variables of TYPE_PRECISION N.  This is defined to be identical to
assigning to a bit field of width N.  Therefore the C++ front end has
in fact ensured that the value is in bounds for the enumeration by
virtue of the implicit truncation that occurs at the assignment.

Given that we use these reduced width types to implement bitfields
in C, this had better work exactly as described, or we have bugs not
just for enumerations.

> My role has purely been to fix/avoid the numerous bugs caused by the
> lack of a model (semantics) for partial-mode integral types.

BUT WE DO HAVE SEMANTICS!

We've had semantics for them since the very instant partial mode
integral types were introduced.  There may have been parts of the
compiler that needed to be updated to handle the brand new construct,
and those should have been classified as bugs.  But claiming that
there are no semantics because of these bugs is counterproductive.

> Despite
> repeated claims to the contrary, the middle-end currently doesn't handle
> these bitfield types well (as demonstrated by the numerous PRs), so the
> less than ideal "cop-out" has been to avoid generating them in the
> front-ends.

You certainly didn't remove all of them.  They still exist in the C
front end.  Though only in intermediate code generated by the front
end not as abusable as a type exposed to the user, as with C++ enum.

> It should be easy enough to demonstrate these problems by
> reverting the "cop-out" patch to the C++ front-end, to re-expose the
> latent bugs, such as PR16372.

Fine, I'll do that.  And then fix all the bugs.  This discussion
is circularly insane.

> Perhaps to make some progress on this issue, you could comment
> on where in the RTL expanders the assignment of a 3-bit unsigned
> field to a 3-bit signed field, we (should) generate the necessary
> manual sign extension using XORs and subtractions, if we believe
> that the stored representations should always be suitably extended?

For purposes of explanation:

  typedef "3-bit unsigned int" u3;
  typedef "3-bit signed int" s3;
  u3 u;
  s3 s;

You seem to be asking about

  s = u;

This is in fact illegal.  One must write

  s = (s3)u;

For this, on return from expand_expr on the NOP_EXPR that is the
rhs of this statement, we'll call reduce_to_bit_field_precision
to mask and sign-extend the value to 3 bits.

One can argue that there are in fact holes with this scheme, e.g.

  (A) memset (&u, -1, sizeof (u));
  (B) __asm__ ("mov $-1, %0" : "=r"(u));

i.e. any assignment to these variables not under direct control of
the compiler, such that the value of U in its full mode after the
statement is not confined to the bounds of its partial mode type.

There are several possibilities for correcting these.

  (A) Pass DECL_RTL in memory through reduce_to_bit_field_precision.
  (B) For non-addressable variables, use intermediate variables of
      a full-mode type and expose the assignment in the IL.


r~


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