public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* Incorrect code from EGCS-1.1 on PowerPC
@ 1998-08-18  6:21 Gary Thomas
  1998-08-18 14:59 ` Franz Sirl
  1998-08-20  0:07 ` Jeffrey A Law
  0 siblings, 2 replies; 8+ messages in thread
From: Gary Thomas @ 1998-08-18  6:21 UTC (permalink / raw)
  To: egcs-bugs

[-- Attachment #1: Type: text/plain, Size: 721 bytes --]

The attached code snippet (from the Linux kernel) generates incorrect
code when compiled on Linux/PPC with "-O2" options.

The problem stems from inlined functions and a pointer (skb) being
dereferenced (skb->sb) before it is tested for NULL as a result of 
the loop being reorganized.

------------------------------------------------------------------------
Gary Thomas                              |
email: gdt@linuxppc.org                  | "Fine wine is a necessity of
   ... opinions expressed here are mine  |        life for me"
       and no one else would claim them! |
                                         |      Thomas Jefferson
------------------------------------------------------------------------



[-- Attachment #2: bad_ppc.c --]
[-- Type: text/x-c, Size: 1204 bytes --]

struct sk_buff {
  struct sk_buff	* next;			 
  struct sk_buff	* prev;			 
  struct sk_buff_head * list;		 
  struct sock		* sk;
};

struct sk_buff_head {
  struct sk_buff	* next;
  struct sk_buff	* prev;
  int			qlen;		 

};

struct sock {
  struct sock 	* receive_queue;
};

extern struct sk_buff *		skb_dequeue(struct sk_buff_head *list);

 
extern __inline__ struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
{
	struct sk_buff *next, *prev, *result;
	prev = (struct sk_buff *) list;
	next = prev->next;
	result = ((void *) 0) ;
	if (next != prev) {
		result = next;
		next = next->next;
		list->qlen--;
		next->prev = prev;
		prev->next = next;
		result->next = ((void *) 0) ;
		result->prev = ((void *) 0) ;
		result->list = ((void *) 0) ;
	}
	return result;
}

extern __inline__ struct sk_buff *skb_dequeue(struct sk_buff_head *list)
{
	long flags;
	struct sk_buff *result;
	__save_flags(&( flags )) ;
	cli();
	result = __skb_dequeue(list);
	__restore_flags( flags ) ;
	return result;
}
 
static void tcp_close_pending (struct sock *sk)
{
	struct sk_buff *skb;
	while ((skb = skb_dequeue(&sk->receive_queue)) != ((void *) 0) )
	{
		tcp_close(skb->sk, 0);
		kfree_skb(skb, 1 );
	}
	return;
}

[-- Attachment #3: bad_ppc.s --]
[-- Type: text/x-asm, Size: 867 bytes --]

	.file	"xx1.c"
gcc2_compiled.:
	.section	".text"
	.align 2
	.type	 tcp_close_pending,@function
tcp_close_pending:
	mr 12,1
	la 1,-48(1)
	stw 12,0(1)
	mflr 0
	stw 29,36(1)
	stw 30,40(1)
	stw 31,44(1)
	stw 0,52(1)
	mr 30,3
	addi 29,1,8
	b .L7
.L9:
	crxor 6,6,6
	bl tcp_close
	li 4,1
	mr 3,31
	crxor 6,6,6
	bl kfree_skb
.L7:
	mr 3,29
	crxor 6,6,6
	bl __save_flags
	li 31,0
	bl cli
	lwz 11,0(30)
	lwz 3,8(1)
	cmpw 0,11,30
	li 0,0
	bc 12,2,.L10
	lwz 9,8(30)
	mr 31,11
	lwz 11,0(31)
	addi 9,9,-1
	stw 9,8(30)
	stw 30,4(11)
	stw 11,0(30)
	stw 0,8(31)
	stw 0,0(31)
	stw 0,4(31)
.L10:
	crxor 6,6,6
	bl __restore_flags
	cmpwi 0,31,0
	li 4,0
	lwz 3,12(31)
	bc 4,2,.L9
	lwz 0,52(1)
	mtlr 0
	lwz 29,36(1)
	lwz 30,40(1)
	lwz 31,44(1)
	la 1,48(1)
	blr
.Lfe1:
	.size	 tcp_close_pending,.Lfe1-tcp_close_pending
	.ident	"GCC: (GNU) egcs-2.91.53 19980803 (gcc2 ss-980609 experimental)"

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~1998-08-21  6:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-08-18  6:21 Incorrect code from EGCS-1.1 on PowerPC Gary Thomas
1998-08-18 14:59 ` Franz Sirl
1998-08-19  0:17   ` Gary Thomas
1998-08-19  2:44     ` Franz Sirl
1998-08-19 13:29     ` Franz Sirl
1998-08-20  0:07 ` Jeffrey A Law
1998-08-20  2:41   ` Gary Thomas
1998-08-21  6:05   ` Gary Thomas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).