This patch adds support for the X asm constraint.
To do this, we lower the constraint to either a "w" or "r" constraint
depending on the operand type (both constraints are supported on ARM).
Fixes PR26493
Differential D19061
[ARM] Add support for the X asm constraint sbaranga on Apr 13 2016, 8:30 AM. Authored by
Details This patch adds support for the X asm constraint. To do this, we lower the constraint to either a "w" or "r" constraint Fixes PR26493
Diff Detail Event TimelineComment Actions Hi Silviu, The documentation on the X constraint is... lacking. All it says is "Any operand whatsoever is allowed.". Sigh... So, before we get support for it, I'd like to see a few examples from user code on how people expect it to work (probably the best we can do for now). Also, you don't seem to be testing much. I think you need to have better instructions (adds, movs, loads) to make sure we're testing the whole range of the X constraint. I'm guessing *any* operand is a bit vague, but does it support immediates, as well as registers, expressions? Maybe it'd be easier to create a bug, block PR27197 with it, and explain the expected behaviour, with reproducible C files and command lines. cheers,
Comment Actions Hi Renato, Our definition is "Allows an operand of any kind, no constraint whatsoever. Typically useful to pass a label for an asm branch or call." (LangRef.rst). FWIW, our approach is similar to the X86 one.
The PR (https://llvm.org/bugs/show_bug.cgi?id=26493) text has some good pointers:
I'll add more tests. I think the types of the operands in these instructions are more important than the instructions themselves.
The only use case of this that I'm aware of is the one from http://www.ethernut.de/en/documents/arm-inline-asm.html. Cheers,
Comment Actions Do'h! I missed the PR reference, my apologies. Though, wrt the blog post, I think it's a very lean source for such a generic case like this. I suggest you try to use the constraint on GCC and come up with a general description for its behaviour, what's allowed and what's not. Maybe even talk to a few GCC engineers once you have a better idea, and then be able to accurately describe what we want to implement. Without that, it'll be hard to review the patch, and adding a hack to make your specific use case pass wouldn't be very constructive, either. :) cheers,
Comment Actions Sure! Cheers,
Comment Actions Decaying this to "w" or "r" would potentially pessimize code generation, and might well break use cases. The whole point of "X" is to prevent the compiler from having to reload an operand you don't actually care about using in the output assembly (a scratch, or in that blog post, a hidden dependency). As GCC isn't going to put any effort in to forcing the form of the operand, I'd expect most uses that actually try to print out an "X" constrained register to be using it as a shorthand for getting constants or labels out. There are normally more expressive constraints if that is what you need. Comment Actions Thanks, James! The current implementation will only perform the lowering part (and force this to a register by converting to "r" or "w") if the operand is not a basic block, function, or integer constant - so this should cover some of those use cases. It is true that GCC would be more efficient in some cases (one example would be FP constants), but we would still fit into the definition of "no constraint whatsoever" and therefore correct - which is an improvement from the current situation, where we'll simply crash on this constraint. We can still improve our handling of this constraint, but that would be something that is target independent and outside the scope of this patch. Thanks, Comment Actions I agree bad codegen trumps ICE crashes, but James mentioned it "might well break use cases". I'm interested in those... James, do you have some pointers on the expected usage of this constraint in the wild? The more the merrier! cheers, Comment Actions A Debian grep gets a few examples out from x86 mmx headers (and a couple for other architectures) https://codesearch.debian.net/results/%22%3DX%22/page_0 I'm making no promises as to how correct those uses are (http://sources.debian.net/src/php7.0/7.0.5-3/Zend/zend_multiply.h/?hl=56#L56 looks pretty fragile!), but I don't know of any better sources for real world code. I was only guessing this would break somebody's use case (because it is so liberal at the moment), rather than having one in particular in mind. Comment Actions Hey, I didn't know about this code search, nice! Silviu, it'd be good to get a few examples from that search result page and at least understand what's going on, and maybe prepare some better error messages than seg faults.
Crap. That example can go wrong in so many ways... The complete lack of type safety makes that macro a nightmare for compilers... sigh... I think we can retain our current approach that, whatever makes sense, passes, and what doesn't breaks with an error message in the lines of "stupid user". --renato Comment Actions Yeah, I'm currently working through a list of additional use cases to see what works and why other things don't work.
You'll at least get an assembler error, which is much nicer. Cheers, Comment Actions Added further regression tests. Only use a 'w' constraint if we know that we have at least VFPv2. Comment Actions Hi Silviu, I'm ok with this approach, since it's simple and seems to cover the cases pretty well. I'm guessing that the error message when the prediction goes wrong is "invalid constraint for asm operand", which is *much* better than a segfault. Also, confusion around macros are really the user's fault for writing such an egregious code in the first place. It'd be good if James could have a final look, but I'm ok with the change. cheers,
Comment Actions
I think this will be fine. Missing the constants and labels might come back to bite you (I found an example of s390 using the "X" constraint in the kernel [ arch/s390/include/asm/jump_label.h ] to get at a label for hotpatching), but the break is no worse than you have at the moment (and that's s390, I didn't see anything scary in arch/arm or arch/arm64). If you're happy to be more restrictive than GCC here, then I think think the patch is fine. Please heavily comment the testcases to reflect that they are not representative of the way the "X" constraint should be used in the real world, and you may want to add further comments to the lowering function to make it clear that it is tighter than neccessary. Comment Actions We're always happy to be more restrictive than GCC. :)
Indeed, please do! Also, if you could add the asm() statement that generated each example and a short explanation where the match is binding to, it'd be most helpful, given that you can't match the parameter in some cases. With the additional comments in the test, LGTM. Thanks!
Comment Actions Thanks! Yes, I think being more restrictive than GCC should be fine at least for now. Comment Actions Add more comments for the regresion tests (explaining what's the Also add some additional comments in the lowering function |
What about VFP?