This is the mail archive of the gcc-bugs@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]

[Bug target/46915] New: Wrong code is generated for conditional branch followed by zero length asm


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46915

           Summary: Wrong code is generated for conditional branch
                    followed by zero length asm
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: danglin@gcc.gnu.org
              Host: hppa*-*-*
            Target: hppa*-*-*
             Build: hppa*-*-*


Created attachment 22728
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=22728
Preprocessed source

With gcc 4.4 and current head, we generate incorrect code for the function
add_to_swap at -O2:

int add_to_swap(struct page *page)
{
 swp_entry_t entry;
 int err;

 do { (void)(!PageLocked(page)); } while (0);
 do { (void)(!PageUptodate(page)); } while (0);

 entry = get_swap_page();
 ...

PageUptodate is:

static inline __attribute__((always_inline)) int PageUptodate(struct page
*page)
{
 int ret = test_bit(PG_uptodate, &(page)->flags);
# 297 "include/linux/page-flags.h"
 if (ret)
  __asm__ __volatile__("":::"memory");

 return ret;
}

The generated RTL is:

(jump_insn 13 10 14 (set (pc)
        (if_then_else (eq (zero_extract:SI (reg:SI 28 %r28 [orig:100 D.22506 ]
[
100])
                    (const_int 1 [0x1])
                    (const_int 28 [0x1c]))
                (const_int 0 [0]))
            (label_ref 16)
            (pc))) include/linux/page-flags.h:297 29 {*pa.md:1610}
     (expr_list:REG_BR_PRED (const_int 5 [0x5])
        (expr_list:REG_DEAD (reg:SI 28 %r28 [orig:100 D.22506 ] [100])
            (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
                (nil))))
 -> 16)

(note 14 13 15 [bb 3] NOTE_INSN_BASIC_BLOCK)

(insn:TI 15 14 16 (parallel [
            (asm_operands/v ("") ("") 0 []
                 []
                 [] mm/swap_state.c:185)
            (clobber (mem:BLK (scratch) [0 A8]))
        ]) include/linux/page-flags.h:298 -1
    (nil))

(code_label 16 15 17 15 "" [1 uses])

(note 17 16 19 [bb 4] NOTE_INSN_BASIC_BLOCK)

(note 19 17 107 NOTE_INSN_DELETED)

(insn 107 19 122 (sequence [
            (call_insn:TI 18 19 4 (parallel [
                        (set (reg:SI 28 %r28)
                            (call (mem:SI (symbol_ref/v:SI ("@get_swap_page")
[f
lags 0x41]  <function_decl 0x40ae6280 get_swap_page>) [0 S4 A32])
...

This results in the following assembler:

globl add_to_swap
        .type   add_to_swap, @function
add_to_swap:
        .PROC
        .CALLINFO FRAME=64,CALLS,SAVE_RP,ENTRY_GR=5
        .ENTRY
        stw %r2,-20(%r30)
        stwm %r5,64(%r30)
        stw %r3,-56(%r30)
        copy %r26,%r3
        stw %r4,-60(%r30)
        ldw 0(%r26),%r28
        ldw 0(%r26),%r28
        bb,>=,n %r28,28,.L15
.L15:
        bl get_swap_page,%r2
        ldi 0,%r4

As can be seen, the bb instruction branches to its delay slot.  This
is not handled by the hardware.

The asm confuses the branch code generation.


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