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) { 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' ? 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