[Bug inline-asm/68095] "cc" clobber with Flag Output Operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68095 --- Comment #8 from David --- I doubt this patch is ever going anywhere. Now that v6 has shipped, producing an error for both using and clobbering flags would "break backward compatibility." On the plus side it would probably have caught your ice. You may want to file the ice as a separate bug. Is there a bug for the !cc clobber thing? I'd like to see that.
[Bug inline-asm/68095] "cc" clobber with Flag Output Operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68095 jbeulich at novell dot com changed: What|Removed |Added CC||jbeulich at novell dot com --- Comment #7 from jbeulich at novell dot com --- I don't think duplicate clobber specifications should be an error. Otherwise you'd be limiting (or complicating) the use in (perhaps multiple nested levels of) macros. And the traditional x86 behavior of always clobbering CC and FPSR isn't really set in stone: As previously proposed (https://gcc.gnu.org/ml/gcc-patches/2014-10/msg03251.html) an "inverse" clobber could be used to suppress that behavior. I'm in the process of updating that patch for re-submission. Finally I'd like to note that for me in plain 6.1.0 void test(void) { int v; asm ("" : "=@ccz" (v) :: "cc"); asm ("" : "=@ccz" (v) :: "flags"); } causes an internal compiler error due to expand_asm_stmt()'s initial conflict checking (3rd pass) being insufficient for the final check (when about to store the clobbers) to not trigger. A possible x86-specific approach might be to detect and report the conflict in ix86_md_asm_adjust() and remove the bad clobber there. But a generic approach would seem better, yet I have no idea how that would need to be done.
[Bug inline-asm/68095] "cc" clobber with Flag Output Operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68095 --- Comment #6 from David --- Created attachment 37621 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37621=edit Patch for missing clobber validations I have created a patch (attached) that does the check I am describing. And while I was at it, I added a few other validations for clobber conditions. The patch includes testcases, but in short, these lines (which currently produce no messages) would all give errors: __asm__ volatile("":::"eax","eax"); __asm__ volatile("":::"memory", "memory"); __asm__ volatile("":::"cc", "cc"); __asm__ volatile("":"=@ccc"(c)::"cc");
[Bug inline-asm/68095] "cc" clobber with Flag Output Operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68095 --- Comment #5 from David --- > the target code adds a cc clobber always. Agreed. On i386, there is no way to say that an extended asm doesn't clobber "cc", so it only serves as a comment on that specific platform. > There is no conflict. I believe we may be talking about two different things. From the point of view of -da and -S, no conflicting code is generated. The output is correct and functions as expected. But looking at the definition of a clobber: - "values changed by the AssemblerTemplate, beyond those listed as outputs." - "Clobber descriptions may not in any way overlap with an input or output operand." It's hard to reconcile those statements with this code (which the compiler currently accepts): asm("bt $0, %1" : "@ccc" (vout) : "r" (vin) : "cc"); Looking at -da output, it looks like "cc" generates "clobber reg:CC", while @cc generates "set reg:CC". It makes no sense to ever generate both, which is what this C statement implies. I believe the correct way to write this (which the compiler also accepts and generates identical code) is: asm("bt $0, %1" : "@ccc" (vout) : "r" (vin)); Silently ignoring the user's attempt to simultaneously use and clobber cc is a logical guess about what the user really wants. But I'm saying the compiler should instead treat that the same way it treats simultaneously clobbering and using other things. For example: asm volatile ("" : "=a"(a) :: "eax") generates an "impossible constraints" error. If I have not convinced you to generate an error for the simultaneously use, can I at least write a doc patch for this to help clarify things for users? Something that points out that there is no way to disable "cc" for i386, and provides a sample for using @cc?
[Bug inline-asm/68095] "cc" clobber with Flag Output Operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68095 --- Comment #3 from David --- > "=@ccc"(r) does not output to the "cc" register, it > outputs to a general register. Actually, I don't believe it does. In v5, you *did* have to use "setc %0" with a general register AND it generated an extra "cmp" instruction (very irritating). But this code: int main() { int x; do { asm volatile("setc" : "=@ccc"(x) : : "cc"); } while (!x); } Compiled with -O2, now outputs: .L2: /APP setc /NO_APP jnc .L2 No general register required. It really is just using the flags. So it still looks to me like we are both clobbering flags (implying that they are changed but not output) and outputting them. Allowing both at once seems bad. > The "cc" clobber is not deprecated, not on other targets anyway. As I look at final_scan_insn() in final.c, it appears to always call CC_STATUS_INIT for both basic and extended asm. And while not all platforms may implement CC_STATUS_INIT, my assumption was that if the platform supported the "cc" clobber, this was where the implementation was. If there is no way to NOT clobber, then "cc" becomes an unenforced comment, rather than a directive to change the behavior of the compiler. If that's true, updating the docs to say so seems reasonable.
[Bug inline-asm/68095] "cc" clobber with Flag Output Operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68095 --- Comment #4 from Segher Boessenkool --- Let me put it differently. At the C level, your asm statement outputs to an integer register. Internally, the asm outputs to a condition reg, and the C statement is expanded to also do a move from that condition reg to the integer register. This move is then later optimised away in your example. On "cc0" targets, every asm has an implicit "cc" clobber. x86 is not a cc0 target (that is ancient technology and one day it will be gone completely, hopefully). However, it used to be a cc0 target long ago, and to ease transition of old user code, the target code adds a cc clobber always. If you look at the generated RTL (with -da, say), you will see that the cc output overrides the cc clobber. There is no conflict.
[Bug inline-asm/68095] "cc" clobber with Flag Output Operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68095 Segher Boessenkool changed: What|Removed |Added CC||segher at gcc dot gnu.org --- Comment #2 from Segher Boessenkool --- "=@ccc"(r) does not output to the "cc" register, it outputs to a general register. It clobbers the "cc" register. Mentioning that more than once ("=@ccc", the clobber in the asm, and it is default for the x86 target) is no problem and has clear semantics. The "cc" clobber is not deprecated, not on other targets anyway. Even on x86 it still serves to mark those asms that really clobber the flags register, which can be helpful to the reader.
[Bug inline-asm/68095] "cc" clobber with Flag Output Operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68095 --- Comment #1 from David --- On further reflection, perhaps the best solution is even simpler. It is my understanding that the "cc" clobber is redundant. Internally, the flags are clobbered whether you set this or not. And I can't see how this behavior can ever change now that it has been like this for so long. As a result, perhaps the solution is to just change the docs for the "cc" clobber to say that it is meaningless. Maybe something like: "cc" This clobber is only kept for historical reasons. It no longer has any effect on the generation of code.