On Wed, Apr 30, 2014 at 1:03 PM, BELBACHIR Selim
<[email protected]> 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
>
>
>
>
>