Bug 21699 - asm and cast-to-reference -> bad code
asm and cast-to-reference -> bad code
Status: RESOLVED DUPLICATE of bug 21920
Product: gcc
Classification: Unclassified
Component: c++
3.4.3
: P2 normal
: ---
Assigned To: Not yet assigned to anyone
:
: 21700 (view as bug list)
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2005-05-21 15:47 UTC by Emmanuel Thomé
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host: i386-redhat-linux
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
asm code at -O2 (1.30 KB, text/plain)
2005-05-21 16:09 UTC, Emmanuel Thomé
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Emmanuel Thomé 2005-05-21 15:47:59 UTC
The code below is an attempt at having the macro add_ssaaaa from GNU
MP accepted by G++. I am casting the outputs of the asm statement to
unsigned int& (in GMP, USItype is unsigned int + attrib SI, which are the
same on i386).

First, I'd like to be told if this is not a reasonable thing to do. I
think it is, but I'm not too sure.

The problem is that g++ 3.4.x produces wrong code at -O2 level for this.
The asm produced has no trace of the two tests at the end (it must,
really). No warning is issued.

The problem vanishes if I cast to unsigned long& instead, or if I remove the 
cast.

4.0 does not have the problem.

See also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2803

---------------------------------------------------------------------------
const unsigned long f_p = 4194301;
extern unsigned long mpinv_mod_r;

unsigned long redc(unsigned long zhi, unsigned long zlo)
{
        unsigned long t, u, m, __w1, __xm0, __xm1;
        m = zlo * mpinv_mod_r;
        __xm0 = m;
        __xm1 = f_p;
        __asm__("mull %3": "=a"(u), "=d"(__w1):"%0"(__xm0),
                "rm"(__xm1));
        t = __w1 - (-(__xm0 >> 31) & __xm1) - (-(__xm1 >> 31) & __xm0);
        __asm__("addl %5,%1\n\tadcl %3,%0"
                        : "=r" ((unsigned int&) t), "=&r" ((unsigned int&) u)
                        :"0"(t), "g"(zhi), "%1"(u), "g"(zlo));
        if ((int) t < 0)
                t += f_p;
        if (t >= f_p)
                t -= f_p;
        return t;
}
---------------------------------------------------------------------------

E.
Comment 1 Emmanuel Thomé 2005-05-21 16:05:38 UTC
*** Bug 21700 has been marked as a duplicate of this bug. ***
Comment 2 Emmanuel Thomé 2005-05-21 16:09:04 UTC
Created attachment 8946 [details]
asm code at -O2


see how the result of the second adc goes straight as a return value.
Comment 3 Andrew Pinski 2005-05-21 16:21:50 UTC
You are violating C++ aliasing rules.
You are accessing a long variable as an int.
Comment 4 Emmanuel Thomé 2005-05-21 16:42:56 UTC
(In reply to comment #3)
> You are violating C++ aliasing rules.
> You are accessing a long variable as an int.
> 

ok. I'll try to have gmp fixed then.

shouldn't -Wstrict-aliasing issue a warning in such a situation ?

E.
Comment 5 Andrew Pinski 2005-06-05 09:20:25 UTC
Reopening to ...
Comment 6 Andrew Pinski 2005-06-05 09:20:50 UTC
Mark as a dup of bug 21920.

*** This bug has been marked as a duplicate of 21920 ***