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