On Wed, 2015-10-28 at 13:42 +0100, Richard Biener wrote:
> On Wed, Oct 28, 2015 at 12:23 AM, Steve Ellcey <sell...@imgtec.com> wrote:
> >
> > I have a question about the _Fract types and their conversion routines.
> > If I compile this program:
> >
> > extern void abort (void);
> > int main ()
> > {
> >   signed char a = -1;
> >   _Sat unsigned _Fract b = a;
> >   if (b != 0.0ur)
> >     abort();
> >   return 0;
> > }
> >
> > with -O0 and on a MIPS32 system where char is 1 byte and unsigned (int)
> > is 4 bytes I see a call to '__satfractqiuhq' for the conversion.
> >
> > Now I think the 'qi' part of the name is for the 'from type' of the
> > conversion, a 1 byte signed type (signed char), and the 'uhq' part is
> > for the 'to' part of the conversion.  But 'uhq' would be a 2 byte
> > unsigned fract, and the unsigned fract type on MIPS should be 4 bytes
> > (unsigned int is 4 bytes).  So shouldn't GCC have generated a call to
> > __satfractqiusq instead?  Or am I confused?
> 
> did it eventually narrow the comparison?  Just check some of the tree/RTL 
> dumps.
> 
> > Steve Ellcey
> > sell...@imgtec.com

Hm, it looks like it optimized this in expand.  In the last tree dump it
still looks like:

        b_2 = (_Sat unsigned _Fract) a_1;

But in the expand phase it becomes:

(call_insn/u 13 12 14 2 (parallel [
            (set (reg:UHQ 2 $2)
                (call (mem:SI (symbol_ref:SI ("__satfractqiuhq") [flags 0x41]) 
[0  S4 A32])
                    (const_int 16 [0x10])))
            (clobber (reg:SI 31 $31))
        ])

I think this is a legitimate optimization (though I am compiling at -O0
so I wonder if it should really be doing this).  The problem I am
looking at is that I want to remove 'TARGET_PROMOTE_PROTOTYPES' because
it causing us to promote/sign extend types in the caller and the callee.
The MIPS ABI requires it be done in the caller so it should not need to
be done in the callee as well

See https://gcc.gnu.org/ml/gcc/2015-10/msg00149.html

When I ran the testsuite, I got one regression: 
gcc.dg/fixed-point/convert-sat.c.

When looking at that failure I thought the problem might be that I was calling
__satfractqiuhq instead of __satfractqiusq, but that does not seem to be the
issue.  The call to __satfractqiuhq is correct, and the difference that I see
when I don't define TARGET_PROMOTE_PROTOTYPES is that the result of 
__satfractqiuhq
is not truncated/sign-extended to UHQ mode inside of __satfractqiuhq.
I am looking to see if I need to do something with TARGET_PROMOTE_FUNCTION_MODE
to handle _Fract types differently than what 
default_promote_function_mode_always_promote
does.

I tried updating PROMOTE_MODE to handle _Fract modes (by promoting UHQ to USQ 
or SQ) but
that caused more failures than before.  It seems to be only the return of 
partial word
_Fract types that is causing me a problem.

Steve Ellcey
sell...@imgtec.com

Reply via email to