Note: This is a beta release of Red Hat Bugzilla 5.0. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Also email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback here.

Bug 163810

Summary: register bool var in inline asm gets assigned a non-existent register
Product: [Fedora] Fedora Reporter: Benjamin S. Scarlet <scarlet>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 4   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-07-21 12:46:06 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Benjamin S. Scarlet 2005-07-21 11:51:21 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.8) Gecko/20050524 Fedora/1.0.4-4 Firefox/1.0.4

Description of problem:
passing a variable of the c++ type bool to an inline asm, it's possible to get the compiler to generate the register names "%dil" or "%sil", which the assembler rejects (I think correctly) as bad register names.

This looks to me like somewhere some person or code has tried to generate a name for the low 8 bits of %esi or %edi, as one might correctly generate %al as a name for the low 8 bits of %eax.



Version-Release number of selected component (if applicable):
gcc-4.0.0-8

How reproducible:
Always

Steps to Reproduce:
1. make a file foo.cpp containing:
bool foo(int *x0, int *x1) {
    register bool b;
    asm volatile(
        "\tsete %[b]"
        : [b] "=r"(b),"+r"(*x1), "+m"(*x0)
        : 
        : "cc", "memory", "eax"
        );
    return b;
}

void bar() {
    int x0 = 0;
    int x1 = 0;
    foo(&x0,&x1);
}
2. compile it with g++ -S -O -c foo.cpp -o -

  

Actual Results:  I got (amid the rest of the assembly):

#APP
		sete %sil
#NO_APP

Expected Results:  #APP
		sete %bl
#NO_APP

(or some other valid register). Even if my inline asm is completely nonsensical, I don't expect gcc to generate invalid register names.

Additional info:

I haven't gotten this to happen with vanilla gcc-4.0.0 or if the variable type e is changed to "char", but I don't know if that's because it can't happen, or only if a different register is getting chosen of which it is legal to take the low 8-bits.

Comment 1 Jakub Jelinek 2005-07-21 11:55:34 UTC
Your testcase is bogus.  For 8-bit values you need to use q constraint rather
than r, which tells GCC to choose one of the registers that have 8-bit parts
in hardware in -m32 (on x86-64 with -m64 q is the same as r, as all registers
have 8-bit lower parts).

Comment 2 Benjamin S. Scarlet 2005-07-21 12:03:51 UTC
Thanks! (And thanks for the blindingly fast response).

One might argue that since gcc automatically interpreted the type of the
variable to figure out an "l" suffix, it does have enough information to figure
out that part of the constraint itself.

Thanks again though.

Comment 3 Jakub Jelinek 2005-07-21 12:46:06 UTC
asm is a general low level mechanism.  What you are suggesting would be to
clutter it with tons of various architecture specific tweaks.  That's not really
the way to go.