public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Inline asm - unexpected optimization
@ 2011-08-24  9:10 Jeremy Hall
  2011-08-24 10:12 ` Georg-Johann Lay
  0 siblings, 1 reply; 7+ messages in thread
From: Jeremy Hall @ 2011-08-24  9:10 UTC (permalink / raw)
  To: gcc-help

Hi,
Looking at the assembler for this speculative code, I saw that without
asm volatile, the second call to rdrand was removed and the value
"low" used twice.
gcc 4.6.1 with any optimization turned on.  It looks to me like this
optimization will stop the code working.

My question is:  is this my ignorance of inline assembler (most
likely) or is it a bug in gcc which I should report?
I know its a new instruction.  The retry loop etc is removed to
simplify the test case.

#include <stdio.h>
typedef unsigned long long qword;
// #define asm __asm__ __volatile__

int
main( int argc, char *argv[] )
{
  qword result;

    /* for 32 bit mode call rdrand twice */
  unsigned int low, high;
  asm( "rdrand %0" : "=r" (low) );
  asm( "rdrand %0" : "=r" (high) );
  result = ((qword)high << 32U) | low;

  printf("64 bit random number: %llu\n", result );
}

// with asm volatile

#APP
# 17 "rand.c" 1
    rdrand edx  # low
# 0 "" 2
# 18 "rand.c" 1
    rdrand eax  # high
# 0 "" 2
#NO_APP
    mov DWORD PTR [esp+4], edx  #, low
    mov DWORD PTR [esp+8], eax  #, high
    mov DWORD PTR [esp], OFFSET FLAT:.LC0   #,
    call    printf  #

// without volatile

#APP
# 14 "rand.c" 1
    rdrand eax  # low
# 0 "" 2
#NO_APP
    mov ebp, esp    #,
    .cfi_def_cfa_register 5
    and esp, -16    #,
    sub esp, 16 #,
    mov DWORD PTR [esp+4], eax  #, low
    mov DWORD PTR [esp+8], eax  #, low
    mov DWORD PTR [esp], OFFSET FLAT:.LC0   #,
    call    printf  #

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

* Re: Inline asm - unexpected optimization
  2011-08-24  9:10 Inline asm - unexpected optimization Jeremy Hall
@ 2011-08-24 10:12 ` Georg-Johann Lay
  2011-08-24 12:01   ` Jeremy Hall
  0 siblings, 1 reply; 7+ messages in thread
From: Georg-Johann Lay @ 2011-08-24 10:12 UTC (permalink / raw)
  To: Jeremy Hall; +Cc: gcc-help

Jeremy Hall schrieb:
> Hi,
> Looking at the assembler for this speculative code, I saw that without
> asm volatile, the second call to rdrand was removed and the value
> "low" used twice.
> gcc 4.6.1 with any optimization turned on.  It looks to me like this
> optimization will stop the code working.
> 
> My question is:  is this my ignorance of inline assembler (most
> likely) or is it a bug in gcc which I should report?

It's not a bug in gcc.

The inlne asm has side effects you didn't report to gcc, so you need the 
volatile here.

> I know its a new instruction.  The retry loop etc is removed to
> simplify the test case.
> 
> #include <stdio.h>
> typedef unsigned long long qword;
> // #define asm __asm__ __volatile__
> 
> int
> main( int argc, char *argv[] )
> {
>   qword result;
> 
>     /* for 32 bit mode call rdrand twice */
>   unsigned int low, high;
>   asm( "rdrand %0" : "=r" (low) );
>   asm( "rdrand %0" : "=r" (high) );
>   result = ((qword)high << 32U) | low;
> 
>   printf("64 bit random number: %llu\n", result );
> }

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

* Re: Inline asm - unexpected optimization
  2011-08-24 10:12 ` Georg-Johann Lay
@ 2011-08-24 12:01   ` Jeremy Hall
  2011-08-24 13:21     ` Segher Boessenkool
                       ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Jeremy Hall @ 2011-08-24 12:01 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: gcc-help

On 24 August 2011 11:11, Georg-Johann Lay <avr@gjlay.de> wrote:
> It's not a bug in gcc.
>
> The inlne asm has side effects you didn't report to gcc, so you need the
> volatile here.
OK thanks.  I guess there is no way to report this kind of side
effect?  so you have to use volatile or call rdrand twice in the same
asm().
The only spanner in the works is that this problem does NOT occur with
the similar rdtsc instruction.  I wondered if rdtsc was flagged within
gcc in some way to say its output was volatile, and that perhaps this
had yet to be done with rdrand (as its a new instruction not available
for a few months until Ivy Bridge comes out).

>
>> I know its a new instruction.  The retry loop etc is removed to
>> simplify the test case.
>>
>> #include <stdio.h>
>> typedef unsigned long long qword;
>> // #define asm __asm__ __volatile__
>>
>> int
>> main( int argc, char *argv[] )
>> {
>>  qword result;
>>
>>    /* for 32 bit mode call rdrand twice */
>>  unsigned int low, high;
>>  asm( "rdrand %0" : "=r" (low) );
>>  asm( "rdrand %0" : "=r" (high) );
>>  result = ((qword)high << 32U) | low;
>>
>>  printf("64 bit random number: %llu\n", result );
>> }
>

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

* Re: Inline asm - unexpected optimization
  2011-08-24 12:01   ` Jeremy Hall
@ 2011-08-24 13:21     ` Segher Boessenkool
  2011-08-24 14:17     ` Georg-Johann Lay
  2011-08-24 14:28     ` Ian Lance Taylor
  2 siblings, 0 replies; 7+ messages in thread
From: Segher Boessenkool @ 2011-08-24 13:21 UTC (permalink / raw)
  To: Jeremy Hall; +Cc: Georg-Johann Lay, gcc-help

>> The inlne asm has side effects you didn't report to gcc, so you  
>> need the
>> volatile here.
> OK thanks.  I guess there is no way to report this kind of side
> effect?  so you have to use volatile

That's exactly what volatile means: "this asm has some unspecified
side effect".


Segher

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

* Re: Inline asm - unexpected optimization
  2011-08-24 12:01   ` Jeremy Hall
  2011-08-24 13:21     ` Segher Boessenkool
@ 2011-08-24 14:17     ` Georg-Johann Lay
  2011-08-24 14:28     ` Ian Lance Taylor
  2 siblings, 0 replies; 7+ messages in thread
From: Georg-Johann Lay @ 2011-08-24 14:17 UTC (permalink / raw)
  To: Jeremy Hall; +Cc: gcc-help

Jeremy Hall wrote:
> On 24 August 2011 11:11, Georg-Johann Lay wrote:
>> It's not a bug in gcc.
>>
>> The inlne asm has side effects you didn't report to gcc, so you need the
>> volatile here.
> OK thanks.  I guess there is no way to report this kind of side
> effect?  so you have to use volatile or call rdrand twice in the same
> asm().

Putting rdrand twice in the same asm won't help because when you then use
that asm twice or more to get several 64-bit numbers you might face a
similar problem.

> The only spanner in the works is that this problem does NOT occur with
> the similar rdtsc instruction.  I wondered if rdtsc was flagged within

If the same sequence behaves different with just an other string dropped
in instead of "rdrand" that would be very strange and astonishing.

GCC does not scan the inline assembler string except for %-operands to
replace and maybe new lines to estimate the number of instructions.

Johann

> gcc in some way to say its output was volatile, and that perhaps this
> had yet to be done with rdrand (as its a new instruction not available
> for a few months until Ivy Bridge comes out).
> 
>>> I know its a new instruction.  The retry loop etc is removed to
>>> simplify the test case.
>>>
>>> #include <stdio.h>
>>> typedef unsigned long long qword;
>>> // #define asm __asm__ __volatile__
>>>
>>> int
>>> main( int argc, char *argv[] )
>>> {
>>>  qword result;
>>>
>>>    /* for 32 bit mode call rdrand twice */
>>>  unsigned int low, high;
>>>  asm( "rdrand %0" : "=r" (low) );
>>>  asm( "rdrand %0" : "=r" (high) );
>>>  result = ((qword)high << 32U) | low;
>>>
>>>  printf("64 bit random number: %llu\n", result );
>>> }

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

* Re: Inline asm - unexpected optimization
  2011-08-24 12:01   ` Jeremy Hall
  2011-08-24 13:21     ` Segher Boessenkool
  2011-08-24 14:17     ` Georg-Johann Lay
@ 2011-08-24 14:28     ` Ian Lance Taylor
  2011-08-24 14:43       ` Jeremy Hall
  2 siblings, 1 reply; 7+ messages in thread
From: Ian Lance Taylor @ 2011-08-24 14:28 UTC (permalink / raw)
  To: Jeremy Hall; +Cc: Georg-Johann Lay, gcc-help

Jeremy Hall <gcc.hall@gmail.com> writes:

> The only spanner in the works is that this problem does NOT occur with
> the similar rdtsc instruction.  I wondered if rdtsc was flagged within
> gcc in some way to say its output was volatile, and that perhaps this
> had yet to be done with rdrand (as its a new instruction not available
> for a few months until Ivy Bridge comes out).

gcc doesn't know anything special about rdtsc.  We would have to see the
code to understand the difference.

For your example, the second rdrand instruction is removed by the
common-subexpression-elimination pass.  By default gcc assumes that an
asm instruction reads nothing other than its inputs and changes only its
outputs.  By that reasoning, your second rdrand instruction will produce
exactly the same result as your first one, so there is no need for it,
so gcc eliminates it.  The volatile qualifier tells gcc that the asm
instruction does something which is not explicitly expressed in the
inputs and outputs.

Ian

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

* Re: Inline asm - unexpected optimization
  2011-08-24 14:28     ` Ian Lance Taylor
@ 2011-08-24 14:43       ` Jeremy Hall
  0 siblings, 0 replies; 7+ messages in thread
From: Jeremy Hall @ 2011-08-24 14:43 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Georg-Johann Lay, gcc-help

> gcc doesn't know anything special about rdtsc.  We would have to see the
> code to understand the difference.
My bad here, sorry.  My experiment was incorrect. I rechecked it and
rdtsc is indeed treated the same way as rdrand.

> For your example, the second rdrand instruction is removed by the
> common-subexpression-elimination pass.  By default gcc assumes that an
> asm instruction reads nothing other than its inputs and changes only its
> outputs.  By that reasoning, your second rdrand instruction will produce
> exactly the same result as your first one, so there is no need for it,
> so gcc eliminates it.  The volatile qualifier tells gcc that the asm
> instruction does something which is not explicitly expressed in the
> inputs and outputs.
Thank you Ian, Georg and Segher for the helpful explanations - its clear now.

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

end of thread, other threads:[~2011-08-24 14:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-24  9:10 Inline asm - unexpected optimization Jeremy Hall
2011-08-24 10:12 ` Georg-Johann Lay
2011-08-24 12:01   ` Jeremy Hall
2011-08-24 13:21     ` Segher Boessenkool
2011-08-24 14:17     ` Georg-Johann Lay
2011-08-24 14:28     ` Ian Lance Taylor
2011-08-24 14:43       ` Jeremy Hall

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).