Hello, On Wed, 18 Mar 2020, J.W. Jagersma via Gcc-patches wrote:
> > Well, it's both: on the exception path the compiler has to assume that the > > the value wasn't changed (so that former defines are regarded as dead) or > > that it already has changed (so that the effects the throwing > > "instruction" had on the result (if any) aren't lost). The easiest for > > this is to regard the result place as also being an input. > > The way I see it, there are two options: either you use the outputs > when an exception is thrown, or you don't. Assuming by "use the outputs" you mean "transform them implicitely to in-out operands", not "the source code uses the output operands after the asm on except and no-except paths". > The first option is more or less what my first patch did, but it was > incomplete. Changing each output to in+out would make that work > correctly. Right. > The second is what I have implemented now, each output is assigned via > a temporary which is then assigned back to the variable bound to this > output. On exception, this temporary is discarded. However this is > not possible for asms that write directly to memory, so those cases are > treated like option #1. Right again, somewhat. Except that the determination of which outputs are going into memory is a fuzzy notion until reload/LRA (which is very late in the compile pipeline). You can infer some things from the constraint letters, but gimple might still put things into memory (e.g. when the output place is address taken), even though the constraint only allows a register (in which case reloads will be generated), or place something into a register, even though the constraint only allows memory (again, reloads will be generated). Some of these reloads will be done early in the gimple pipeline to help optimizations (they basically look like the insns that you generate for copy-out), some of them will be generated only very late. > I think the second option is easier on optimization since any previous > assignments can be removed from the normal code path, and registers > don't need to be loaded with known-valid values before the asm. True (easier to optimizations) but immaterial (see below). > The first option is more consistent since all outputs are treated the > same, but more dangerous, as the asm may write incomplete values before > throwing. You have to assume that the author of the asm and its surrounding code is written by a knowledgable person, so if the asm possibly writes partially to outputs and then throws, then the output must not be accessed on the exception path. If the asm does not write partially, then the author can access it. So, what can or cannot be accessed on the exception path really is an inherent property of the contents of the asm. Now, your second case tries to create additional guarantees: it makes it so that for some operands the user can depend on certain behaviour, namely that the old value before the asm was entered is available on the except path. As you can't ensure this for all operands (those in memory are the problem) you want to tighten the definition to only include the operands where you can guarantee it, but this is fairly brittle, as above, because some decisions are taken very late. There's another case to consider: assume I'm writing an asm that writes meaningful values to an output before and after a potential exception is thrown, ala this: asm (" mov %2, %0 xyz %2, %1 mov $0, %0" : "=r" (status), "+r" (a) : "r" (b)); Assume 'xyz' can fault depending on input. The intention above would be that on the exception path 'status' would contain a meaningful value (here the value of input b, and on the non-except path would contain zero. Your proposal of copyin/out for register values would make the above impossible. (Basically you wouldn't be able to output any reliable information out of the asm in the except path). Given that, and the complication of determining what the safe-for-copy-out operands really are, and the fact that being easier on optimizations in connection with asms and -fnon-call-exceptions isn't a high priority it seems best to opt for the option that is guaranteed to work correctly in most cases, and in fact allows more freedom in using the asm. Ciao, Michael.