This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug optimization/14782] New: [3.3/3.4/hppa64-linux] gcc inlines code incorrectly at -O2
- From: "tausq at debian dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 30 Mar 2004 07:39:11 -0000
- Subject: [Bug optimization/14782] New: [3.3/3.4/hppa64-linux] gcc inlines code incorrectly at -O2
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
The attached code when compiled with gcc-3.3 or 3.4 at -O2 generates a "ldd -23
(%r3),%r19" sequence which is wrong. Compiling with -O1 or -O2 -fno-gcse works
around the problem. The offending asm seems to be generated from the if-
statement in loop_unregister_transfer(). Removing the up/down calls make the
problem go away. This test case was derived from the linux kernel,
drivers/block/loop.c.
thanks, randolph
-------- 8< cut here 8< -------------
#define __PA_LDCW_ALIGNMENT 16
#define __ldcw_align(a) ({ \
unsigned long __ret = (unsigned long) a; \
__ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \
(volatile unsigned int *) __ret; \
})
#define __ldcw(a) ({ \
unsigned __ret; \
__asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \
__ret; \
})
typedef struct {
volatile unsigned int lock[4];
} spinlock_t;
struct semaphore
{
spinlock_t sentry;
int count;
};
struct loop_device
{
struct loop_func_table *lo_encryption;
struct semaphore lo_ctl_mutex;
};
static int max_loop = 8;
static struct loop_device *loop_dev;
void __down (struct semaphore *sem);
void __up (struct semaphore *sem);
static inline void _raw_spin_lock (spinlock_t * x)
{
volatile unsigned int *a = __ldcw_align(&x->lock[0]);
while (__ldcw(a) == 0)
while (*a == 0);
}
static inline void _raw_spin_unlock (spinlock_t * x)
{
volatile unsigned int *a = __ldcw_align(&x->lock[0]);
*a = 1;
}
inline void down (struct semaphore *sem)
{
_raw_spin_lock (&sem->sentry);
if (sem->count > 0) { sem->count--; }
else { __down (sem); }
_raw_spin_unlock (&sem->sentry);
}
inline void up (struct semaphore *sem)
{
_raw_spin_lock (&sem->sentry);
if (sem->count < 0) { __up (sem); }
else { sem->count++; }
_raw_spin_unlock (&sem->sentry);
}
int
loop_unregister_transfer (int number)
{
struct loop_device *lo = &loop_dev[0];
for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++)
{
down (&lo->lo_ctl_mutex);
if (lo->lo_encryption == 0)
loop_release_xfer (lo);
up (&lo->lo_ctl_mutex);
}
return 0;
}
-------- 8< cut here 8< -------------
--
Summary: [3.3/3.4/hppa64-linux] gcc inlines code incorrectly at -
O2
Product: gcc
Version: 3.4.0
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: tausq at debian dot org
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: hppa-linux
GCC host triplet: hppa-linux
GCC target triplet: hppa64-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14782