Bug 43998 - inline assembler: can't set clobbering for input register
Summary: inline assembler: can't set clobbering for input register
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: inline-asm (show other bugs)
Version: 4.4.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-06 06:36 UTC by Коренберг Марк
Modified: 2016-06-25 00:31 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Коренберг Марк 2010-05-06 06:36:50 UTC
mmarkk@mmarkk-desktop:~/src/vmdetect$ gcc --version
gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1
----------------------------------------------
#include <sys/types.h> 
#include <stdio.h> 
int main (void)
{
  size_t ecx;
  asm ("cpuid": "=c" (ecx): "a" (0x1):"eax","ebx","edx");
  printf ("Suspected %s machine!\n", (ecx >> 31) ? "virtual" : "real");
  return 0;
}

mmarkk@mmarkk-desktop:~/src/vmdetect$ gcc 1main.c 
1main.c: In function ‘main’:
1main.c:7: error: can't find a register in class ‘AREG’ while reloading ‘asm’
1main.c:7: error: ‘asm’ operand has impossible constraints
------------------------------------------------
#include <sys/types.h> 
#include <stdio.h> 
int main (void)
{
  size_t ecx, dontneed;
  asm ("cpuid": "=c" (ecx),"=a"(dontneed): "a" (0x1):"ebx","edx");
  printf ("Suspected %s machine!\n", (ecx >> 31) ? "virtual" : "real");
  return 0;
}
works OK.

How to correctly say compiler about clobbering eax register ?
Comment 1 Uroš Bizjak 2010-05-06 07:11:09 UTC
You can use cpuid.h.

BTW: Please ask questions about using gcc in gcc-help@ or elsewhere.

Not a bug.
Comment 2 Jakub Jelinek 2010-05-06 08:06:43 UTC
To answer the exact question, yes, using a dummy variable as output (perhaps with "1" instead of "a" for the matching input) is the right fix.
Comment 3 Коренберг Марк 2010-05-06 11:00:42 UTC
Thanks alot, but I think it is bug in gcc inline assembler. I think I wrote correct asm() line.

I know about cpuid.h
I listed this instruction just as example.
Comment 4 Richard Biener 2010-05-06 11:31:16 UTC
You can't at the same time force something into aregs and clobber them.
Comment 5 Коренберг Марк 2010-05-06 11:41:45 UTC
Well, how to say that to compiler:

This instruction receives input in register eax, but after executing it, eax value will be corrupted. I don't need this new value, but compiler  should not think that eax is preserved.
Comment 6 H.J. Lu 2010-05-06 13:09:23 UTC
(In reply to comment #5)
> Well, how to say that to compiler:
> 
> This instruction receives input in register eax, but after executing it, eax
> value will be corrupted. I don't need this new value, but compiler  should not
> think that eax is preserved.
> 

Just make eax both input and output.
Comment 7 Коренберг Марк 2010-05-06 13:42:28 UTC
> Just make eax both input and output.
it's not optimal. gcc will try to preserve new eax value. So it will not use eax register in next instructions. If eax is really need, it will save it in esi, edi or so on - it's redundant.
Comment 8 Richard Biener 2010-05-06 13:55:59 UTC
(In reply to comment #7)
> > Just make eax both input and output.
> it's not optimal. gcc will try to preserve new eax value. So it will not use
> eax register in next instructions. If eax is really need, it will save it in
> esi, edi or so on - it's redundant.

Not if you make the output unused by not using it.
Comment 9 Коренберг Марк 2010-05-06 15:03:49 UTC
> Not if you make the output unused by not using it.
I do not understand why gcc distinguish between 'specifying register as output' and 'specifying as clobbering'.

I always considered, that 'clobber list' specify list of items which may be changed *AFTER* the end of instruction(s). So I do not understand why adding eax in clobber list will break compilation.

I found some posts where people create size_t dummy; and specify this variable as output. insted of just specifying this register in clobber-list.

Why not to fix bug I have reported? Maybe convert to feature?
Comment 10 Andrew Pinski 2010-05-14 02:44:56 UTC
Because the way the constraints are implemented inside GCC, an input constraint cannot overlap with a clobber.  As input constraint can stay in the same register across the inline-asm so it does not make sense to have it as a clobber.  Use an output register that says it clobbers that register.
Comment 11 Коренберг Марк 2010-05-14 06:31:06 UTC
Suppose this:

volatile int x;
asm("something"::"a" (1))
x=1;

the compiler may think that "something" do not modify eax. So next assignment may use eax ( mov eax, x ). So, "it does not make sense to have it as a clobber" is not correct. does not it ?
-----------------
And the second, "Because the way the constraints are implemented inside GCC, an input constraint cannot overlap with a clobber." - It definitely the bug.

Comment 12 Eric Botcazou 2010-05-14 07:10:49 UTC
> the compiler may think that "something" do not modify eax. So next assignment
> may use eax ( mov eax, x ). So, "it does not make sense to have it as a
> clobber" is not correct. does not it ?

Andrew was saying that it doesn't make sense to consider input operands as clobbered by an inline asm, generically.

> And the second, "Because the way the constraints are implemented inside GCC,
> an input constraint cannot overlap with a clobber." - It definitely the bug.

No, it isn't, it's clearly stated in the manual: "You may not write a clobber description in a way that overlaps with an input or output operand."
Comment 13 Ilya Lesokhin 2013-04-08 08:04:28 UTC
Andrew Pinski said:
>  Use an output register that says it clobbers that register.

This indeed works for normal inline assembler, but it doesn't work for asm goto which currently doesn't have outputs.

maybe the Bug should be reopened for newer versions of GCC?
Comment 14 Stas Sergeev 2016-06-25 00:29:48 UTC
(In reply to Eric Botcazou from comment #12)
> > the compiler may think that "something" do not modify eax. So next assignment
> > may use eax ( mov eax, x ). So, "it does not make sense to have it as a
> > clobber" is not correct. does not it ?
> 
> Andrew was saying that it doesn't make sense to consider input operands as
> clobbered by an inline asm, generically.
How about allowing an ampersand in the input list?
Just like early clobber in output list, in input list
it may mean "late clobber" - that is, clobbered after
the argument is taken.
Then you won't contradict with any doc and will avoid
any logical inconsistency.
This makes a lot of sense for things like "rep; movsl"
where you'd need 3 dummy values...
Comment 15 Stas Sergeev 2016-06-25 00:31:02 UTC
Btw, clang seems to allow same regs in input and clobber list.