Discussion:
"cc" clobber
David Wohlferd
2016-01-26 23:12:09 UTC
Permalink
It is well known that on i386, the "cc" clobber is always set for
extended asm, whether it is specified or not. I was wondering how much
difference it might make if the generated code actually followed what
the user specified (expectation: not much). But implementing this
turned up a different question.

I started by just commenting out the code in ix86_md_asm_adjust that
unconditionally clobbered the flags. I figured this would allow the
'normal' "cc" handling to occur. But apparently there is no 'normal'
"cc" handling.

So I went back to ix86_md_asm_adjust and tried to handle the "cc" if it
was specified in the clobbers argument. But apparently "cc" doesn't get
added to that clobbers list.

Hmm.

Tracing back to see how the "memory" clobber (which does get added to
the clobber list) is handled brings me to expand_asm_stmt() in
cfgexpand.c. Following the example set by the memory clobber, it looks
like I want something like this:

else if (j == -3)
{
#if defined(__i386__) || defined(__x86_64__)
rtx x = gen_rtx_REG (CCmode, FLAGS_REG);
clobber_rvec.safe_push (x);

x = gen_rtx_REG (CCFPmode, FPSR_REG);
clobber_rvec.safe_push (x);
#endif
}

Now I can check for this in the clobbers to ix86_md_asm_adjust and
SET_HARD_REG_BIT as appropriate. Tada.

It's working, but can that be right? Why do I need to do this for
i386? How do other platforms handle "cc"?

Other than not rejecting it as an invalid clobber, I can't find any code
that seems to recognize "cc." Has "cc" become just an unenforced
comment on all platforms? Or did I just miss it?

dw
Bernd Schmidt
2016-01-27 00:31:18 UTC
Permalink
Post by David Wohlferd
I started by just commenting out the code in ix86_md_asm_adjust that
unconditionally clobbered the flags. I figured this would allow the
'normal' "cc" handling to occur. But apparently there is no 'normal'
"cc" handling.
I have a dim memory that there's a difference between the "cc" and "CC"
spellings. You might want to check that.


Bernd
David Wohlferd
2016-02-01 09:51:44 UTC
Permalink
Post by Bernd Schmidt
Post by David Wohlferd
I started by just commenting out the code in ix86_md_asm_adjust that
unconditionally clobbered the flags. I figured this would allow the
'normal' "cc" handling to occur. But apparently there is no 'normal'
"cc" handling.
I have a dim memory that there's a difference between the "cc" and
"CC" spellings. You might want to check that.
I checked, but my scan of the current code isn't turning up anything for
"CC" related to clobbers either.

While presumably "cc" did something at one time, apparently now it's
just an unenforced comment (on extended asm). Not a problem, just a bit
of a surprise.

dw
Ulrich Weigand
2016-02-01 14:58:56 UTC
Permalink
Post by David Wohlferd
Post by Bernd Schmidt
Post by David Wohlferd
I started by just commenting out the code in ix86_md_asm_adjust that
unconditionally clobbered the flags. I figured this would allow the
'normal' "cc" handling to occur. But apparently there is no 'normal'
"cc" handling.
I have a dim memory that there's a difference between the "cc" and
"CC" spellings. You might want to check that.
I checked, but my scan of the current code isn't turning up anything for
"CC" related to clobbers either.
While presumably "cc" did something at one time, apparently now it's
just an unenforced comment (on extended asm). Not a problem, just a bit
of a surprise.
I think on many targets a clobber "cc" works because the backend
actually defines a register named "cc" to correspond to the flags.
Therefore the normal handling of clobbering named hard registers
catches this case as well.

This doesn't work on i386 because there the flags register is called
"flags" in the back end.

Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
***@de.ibm.com
Richard Henderson
2016-02-01 20:40:10 UTC
Permalink
Post by Ulrich Weigand
I think on many targets a clobber "cc" works because the backend
actually defines a register named "cc" to correspond to the flags.
Therefore the normal handling of clobbering named hard registers
catches this case as well.
Yes. C.f. Sparc ADDITIONAL_REGISTER_NAMES.
Post by Ulrich Weigand
This doesn't work on i386 because there the flags register is called
"flags" in the back end.
Once upon a time i386 used cc0. A survey of existing asm showed that almost no
one clobbered "cc", and that in the process of changing i386 from cc0 to an
explicit flags register we would break almost everything that used asm.

The only solution that scaled was to force a clobber of the flags register.

That was 1999. I think you'll buy nothing but pain in trying to change this now.


r~
David Wohlferd
2016-02-01 22:31:01 UTC
Permalink
Post by Richard Henderson
Post by Ulrich Weigand
I think on many targets a clobber "cc" works because the backend
actually defines a register named "cc" to correspond to the flags.
Therefore the normal handling of clobbering named hard registers
catches this case as well.
Yes. C.f. Sparc ADDITIONAL_REGISTER_NAMES.
Post by Ulrich Weigand
This doesn't work on i386 because there the flags register is called
"flags" in the back end.
Once upon a time i386 used cc0. A survey of existing asm showed that
almost no one clobbered "cc", and that in the process of changing i386
from cc0 to an explicit flags register we would break almost
everything that used asm.
The only solution that scaled was to force a clobber of the flags register.
That was 1999. I think you'll buy nothing but pain in trying to change this now.
I expect you are right. After experimenting, the cases where this might
buy you any benefit are just too uncommon, and the 'benefit' is just too
small.

The one place where any of this would (sort of) be useful is checking
for the "cc" clobber conflicting with the output parameters. This
didn't used to be a thing, but now that i386 can 'output' flags, it is.
The compiler currently accepts both of these and they both produce the
same code:

asm("": "=@ccc"(x) : : );
asm("": "=@ccc"(x) : : "cc");

I assert (pr69095) that the second one should give an error (docs:
"Clobber descriptions may not in any way overlap with an input or output
operand"). Creating a check for this was more challenging than I
expected. I kept assuming that there 'had' to be existing code to
handle cc and I could tie into it if I could only figure out where it was.

But now that I have this written, I'm still vacillating about whether it
is useful. It seems like I could achieve the same result by adding
"Using @cc overrides the "cc" clobber" to the docs. But hey, it also
checks for duplicate "memory" and "cc" clobbers, so there's that...

dw

David Wohlferd
2016-02-01 22:22:13 UTC
Permalink
Post by Ulrich Weigand
I think on many targets a clobber "cc" works because the backend
actually defines a register named "cc" to correspond to the flags.
Therefore the normal handling of clobbering named hard registers
catches this case as well.
This doesn't work on i386 because there the flags register is called
"flags" in the back end.
Doh! Of course. This makes perfect sense. Thanks.

dw
Continue reading on narkive:
Loading...