This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/46915] New: Wrong code is generated for conditional branch followed by zero length asm
- From: "danglin at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sun, 12 Dec 2010 22:48:03 +0000
- Subject: [Bug target/46915] New: Wrong code is generated for conditional branch followed by zero length asm
- Auto-submitted: auto-generated
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.