On Wed, Apr 30, 2014 at 1:03 PM, BELBACHIR Selim <selim.belbac...@fr.thalesgroup.com> wrote: > Hi, > > I encountered a problem on test 'gcc.c-torture/execute/loop-7.c' (gcc4.7.3) > on my private port during test case "-O2 -flto -fuse-linker-plugin > -fno-fat-lto-objects" > > Here is the tested code : > > void foo (unsigned int n)
Try making this function static, that might reproduce the issue without LTO (eventually add -fno-early-inlining). -fwhole-program without -flto should also reproduce it. > { > int i, j = -1; > > for (i = 0; i < 10 && j < 0; i++) > { > if ((1UL << i) == n) > j = i; > } > > if (j < 0) > abort (); > } > > main() > { > foo (64); > exit (0); > } > > > The LTO option merge the foo function into the main function. > > I'll try present my problem by simplifying the resulting assembler. > > <main>: > :L1 > [...] << content of the loop > compare 0, $R0 << test to know if the loop goes on or stop > ($R0 synthetize the whole loop end condition) > jump_delayed.ifNE L1 << conditional delayed jump : the loop end if > $R0 == 0 > nop #delayslot1 > sll $R1, 1, $R0 #delayslot2 << instruction which is part of the loop content > but placed into the 2nd delay slot of jump_delayed.ifNE instruction > compare -1, $R2 << test if (j < 0) > branch.ifeq abort << conditional branch to abort > branch exit << branch to exit which expect a 0 into > $R0 as first parameter > > The test fail, not because abort is called, but because exit is called with > $R0 containing 0x80 and not 0. > I think GCC expect $R0 to be equal to 0 when the loop end (so no need to set > explicitly $R0 to 0) > But in this case the 'sll' instruction placed into the delay slot of the > conditional delayed jump modify $R0 even if no jump is performed. > > Is it a bug due to LTO merging the 'foo' and 'main' function ? > > Or does GCC really thinks that the instructions placed into the delay slot of > conditional jump are executed only if the condition is true ? > > Or is it simply a GCC incompatibility between 'conditional jump' & 'delay > slots' ? the delay-slot code is fragile, you probably simply run into a bug. Richard. > > > Here are some parts of my backend relative to delay slot and conditional jump > (nothing formidable :) ): > > (define_delay (ior (eq_attr "type" "jump") (eq_attr "type" "cond_jump")) > [(and (eq_attr "delayable" "yes") (eq_attr "length" "1")) (nil) (nil) > (and (eq_attr "delayable" "yes") (eq_attr "length" "1")) (nil) (nil)]) > > (define_insn "jumpif" > [(set (pc) > (if_then_else (match_operator 0 "comparison_operator" > [(match_operand 2 "cc_register" "") (const_int 0)]) > (label_ref (match_operand 1 "" "")) > (pc)))] > "" > { [...] // use final_sequence to detect delay slot } > [set_attr "type" "cond_jump") > (set_attr "delayable" "no")] > > > Regards, > > Selim > > > > >