Bug 11103 - [3.3/3.4 regression] asm-specifier conflicts with asm clobber list
Summary: [3.3/3.4 regression] asm-specifier conflicts with asm clobber list
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: inline-asm (show other bugs)
Version: 3.3
: P2 normal
Target Milestone: 3.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-06-05 18:58 UTC by mdb
Modified: 2004-01-17 04:22 UTC (History)
5 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: xscale-elf
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2003-06-08 05:51:47


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description mdb 2003-06-05 18:58:17 UTC
Using the gcc 3.2.2 xscale-elf-gcc compiler had no problems with the test case.

Using the gcc 3.3 xscale-elf-gcc compiler will produce the following
messages:

blkpg-test.c: In function `blk_ioctl':
blkpg-test.c:13: error: asm-specifier for variable `myr1' conflicts with asm
clobber list

The basic problem is that the gcc code generator does NOT like the user
forcing the use of registers r0 and r1 for the inline assembler.

The workaround would appear to be to elide the asm("r1") and the two
asm("r0") extensions and let gcc choose the register for the code...
which really only works correctly if that is what the __put_user_1
function will accept.

In the real world, this problem is found by building the file
linux-2.4.19/drivers/block/blkpg.c which results in the error

blkpg.c: In function `blk_ioctl':
blkpg.c:285: warning: comparison between signed and unsigned
blkpg.c:252: error: asm-specifier for variable `__r1' conflicts with asm clobber
list


Release:
gcc 3.3

Target:
xscale-elf

Environment:
Redhat 7.3 GNU/Linux: uname -a says:
Linux mdb-lnx 2.4.20-13.7 #1 Mon May 12 13:13:52 EDT 2003 i686 unknown

How-To-Repeat:
cat <<EOF > blkpg-test.c
/*
 * -------------- blkpg-test.c ---------------
 * xscale-elf-gcc -c blkpg-test.c
 */

int __put_user_1 (void *, unsigned int);
int
blk_ioctl (unsigned long long *arg)
{
    const register unsigned long long myr1 asm("r1") = 0;
    const register unsigned long long *ptr asm("r0") = arg;
    register int res asm("r0");
    __asm__ __volatile__ ("bl   __put_user_1"
                          : "=&r" (res)
                          : "0" (ptr), "r" (myr1)
                          : "r2", "lr");
    return(res);
}
EOF
xscale-elf-gcc -c blkpg-test.c
Comment 1 Dara Hazeghi 2003-06-08 05:51:47 UTC
Confirmed with gcc 3.3 and mainline (20030608). I think this belongs in the inline-asm category 
though. Richard, would you mind commenting on whether the code in question is legal? Thanks,

Dara
Comment 2 dank 2003-06-08 09:39:36 UTC
I get a similar error,
error: asm-specifier for variable `_a1' conflicts with asm clobber list
compiling glibc-2.3.2 with gcc-3.3 for arm-linux.
In the real world, you should be able to reproduce this like so:

wget http://www.kegel.com/crossgcc/crosstool-0.6.tar.gz
tar -xzvf crosstool-0.6.tar.gz
cd crosstool-0.6
eval `cat arm.dat` `cat gcc3.3-glibc2.3.2.dat` sh all.sh

Here's the problem boiled down as small as I can easily get it
(this is the output of 
$ cd build/arm-unknown-linux-gnu/gcc-3.3-glibc-2.3.2/glibc-2.3.2/signal
$ arm-unknown-linux-gnu-gcc -E ../linuxthreads/sysdeps/pthread/sigaction.c
cut down by hand and reformatted with indent):

-- snip --

cat > bug.c <<_EOF_
extern int *__errno_location (void) __attribute__ ((__const__));
struct kernel_sigaction {
    //__sighandler_t k_sa_handler;
    unsigned long sa_flags;
    void (*sa_restorer) (void);
    //sigset_t sa_mask;
};

int __libc_sigaction(sig, act, oact)
int sig;
const struct sigaction *act;
struct sigaction *oact;
{
    int result;
    struct kernel_sigaction kact, koact;

    result = ( {
            unsigned int _sys_result = ( {
                    unsigned int _sys_result; {
                        register int _a1 asm("a1");
                        register int _a4 asm("a4") = (int)(64 / 8);
                        register int _a3 asm("a3") = (int)(oact ? (&koact) :
((void *)0));
                        register int _a2 asm("a2") = (int)(act ? (&kact) :
((void *)0));
                        _a1 = (int) (sig);
              asm volatile ("swi    %1  @ syscall " "rt_sigaction": "=r" (_a1):
"i"(((0x900000 + 174))), "r"(_a1), "r"(_a2), "r"(_a3), "r"(_a4):"a1",
                            "memory");
                        _sys_result = _a1;
                    } (int) _sys_result;
                });
            if (__builtin_expect(((unsigned int) (_sys_result) >= 0xfffff001u),
0)) {
        ((*__errno_location()) = ((-(_sys_result))));
                _sys_result = (unsigned int) -1;} (int) _sys_result;});

    return result;
}
_EOF_
arm-unknown-linux-gnu-gcc bug.c

-- snip --
Comment 3 Dara Hazeghi 2003-06-11 15:38:19 UTC
As Richard noted (http://gcc.gnu.org/ml/gcc-bugs/2003-06/msg01134.html), the behavior of 
the compiler seems to be correct, and so the bug appears to be in the code here. I am marking this 
bug as invalid, but if for some reason this turns out to be incorrect, we can reopen this.
Comment 4 dank 2003-06-11 15:53:13 UTC
Ah, so I should open this as a glibc bug, then?  OK, I'll try that.
Comment 5 dank 2003-06-15 14:47:47 UTC
Supposedly fixed in glibc cvs; see
http://bugs.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=glibc&pr=5051