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