This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: possible problem with C implied intermediate variable sizerequirements -> rtl mapping ?
- From: Paul Koning <pkoning at equallogic dot com>
- To: schlie at comcast dot net
- Cc: gcc at gcc dot gnu dot org
- Date: Thu, 21 Oct 2004 20:06:43 -0400
- Subject: Re: possible problem with C implied intermediate variable sizerequirements -> rtl mapping ?
- References: <BD9DB2AD.7518%schlie@comcast.net>
> (Summary: GCC's C's front-end doesn't seem to be placing requirements
> on it's back-end to generate intermediate temporaries which may be
> required to be wider than it's operands, to comply with C's semantics;
> which is particularly a problem on smaller than int sized machines.)
> ...
> For example, if a hypothetical target machine were defined as having
> the following operand mode size mappings:
>
> QI :: signed char
> HI :: signed int
Not all that hypothetical... that looks a lot like a pdp11...
> ...
> Given the C code fragment (assuming it's not optimized away):
>
> volatile signed char x, y ;
>
> x = y + y ;
> x = y + y + y ;
>
> Assuming x == r0:qi, y == r1:qi, and if a temporary allocation is
> hypothetically required then temp == r2:MODE, then expecting the
> following to be logically generated satisfying C's semantics:
>
> x = y + y generating an rtl equivalent expression like:
>
> (set (reg:QI 0)
> (plus:QI (reg:QI 1)
> (reg:QI 1)))
>
> Which satisfies C as it's target only requires QI precision, yielding:
>
> r0:qi = plus r1:qi r1:qi ; which is fine, and then
>
>
> x = y + y + y generating an rtl equivalent with an widened intermediate:
>
> (set (reg:QI 0)
> (plus:QI (reg:QI 1)
> (plus:HI (reg:QI 1)
> (reg:QI 1))))
>
> Ideally yielding, and satisfying C's semantics for intermediate operations:
>
> r2:hi = plus r1:qi r1:qi ; where r2:hi is an widened intermediate temporary
> r0:qi = plus r1:qi r2:hi ; as required to guarantee intermediate precision.
>
> Which it doesn't seem to do as required to satisfy C's semantics that
> operations are performed to maintain at least the logical precision of the
> greater of an int or it's largest ranking operand, it appears to generate:
>
> (set (reg:QI 0)
> (plus:QI (reg:QI 1)
> (plus:QI (reg:QI 1)
> (reg:QI 1))))
>
> Incorrectly yielding:
>
> r2:qi = plus r1:qi r1:qi ; where r2:qi = char loosing the required
> r0:qi = plus r2:qi r1:qi ; intermediate precision specified by C ?
But that has the same semantics, because of modulo arithmetic. Since
you can't tell the difference (other than that execution may be
faster) it's allowed. Right?
The same would hold with some other operations -- though not for
comparisons, nor for division.
For example, if you only see QI operations in
if ((y + y) != '\0') { ... }
that would seem to be a different matter.
paul