Hi Michael,

On Tue, Oct 14, 2014 at 04:24:13PM +0200, Michael Matz wrote:
> Hi,
> 
> On Tue, 14 Oct 2014, Jamie Iles wrote:
> 
> >     int foo(void)
> >     {
> >             if (getreturn() != 0)
> >                     return -1;
> >     
> >             return 0;
> >     }
> 
> So if getreturn() returns zero it can simply reuse that return value ...
> 
> > but at -O1 I get
> > 
> >   10:       fb ff ff 40     call    0 <foo>
> >                     10: R_OLDLAND_PC24      getreturn-0x4
> >   14:       01 00 00 3c     mov     $r1, 0x0
> >   18:       01 01 00 0a     sub     $r1, $r1, $r0
> >   1c:       00 01 00 2a     or      $r0, $r1, $r0
> >   20:       00 f0 01 38     asr     $r0, $r0, 0x1f
> 
> ... and if I'm interpreting the mnemonics correctly that is what seems to 
> happen here.  If $r0 is zero, then:
> 
>      mov     $r1, 0x0              $r1 = 0
>      sub     $r1, $r1, $r0         $r1 = 0 - 0 = 0
>      or      $r0, $r1, $r0         $r0 = 0 | 0 = 0
>      asr     $r0, $r0, 0x1f        $r0 = 0 >> 31 = 0
> 
> Voila, zero is correctly returned.  Any non-zero value will be transformed 
> into -1 (if positive the high bit will be set due to subtraction, if 
> negative the high bit will be set due to the 'or', and the shift 
> replicates the high bit into the lower ones, yielding -1).

Thanks, this definitely put me in the right direction, I'd been staring 
at it for too long!  It turns out that the problem was that I'd 
previously been testing with one_cmplsi2 defined which *was* wrong and I 
thought I'd reduced it to this.  It turns out that the actual problem 
was that I had one_cmplsi2 defined with

        (define_insn "one_cmplsi2"
          [(set (match_operand:SI 0 "register_operand" "=r")
                  (neg:SI (match_operand:SI 1 "register_operand" "r")))]
          ""
          "xor    %0, %1, -1")

and had operand 1 as neg:SI rather than not:SI.  Fixing that gives me 
the correct code at all optimization levels.

Thanks again for looking at this, much appreciated!

Jamie

Reply via email to