This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: LTO + conditional jump + delay slot


On Wed, Apr 30, 2014 at 1:03 PM, BELBACHIR Selim
<selim.belbachir@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
>
>
>
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]