Hello, I am not sure whether this is a clang issue, an LLVM issue, or both; but clang chokes when parsing expanded macros from the glibc /usr/include/bits/fenvinline.h with an error like: ./boost/math/tools/config.hpp:279:10: error: invalid input constraint 'i#*X' in asm feclearexcept(FE_ALL_EXCEPT); ^ /usr/include/bits/fenvinline.h:56:11: note: expanded from macro 'feclearexcept' : : "i#*X"(__builtin_ffs (__excepts))); \ ^ 1 error generated. There is a comment in the file which reads: /* The weird 'i#*X' constraints on the following suppress a gcc warning when __excepts is not a constant. Otherwise, they mean the same as just plain 'i'. */ For example, one of the full macros is: /* Inline definition for feclearexcept. */ # define feclearexcept(__excepts) \ ((__builtin_constant_p (__excepts) \ && ((__excepts) & ((__excepts)-1)) == 0 \ && (__excepts) != FE_INVALID) \ ? ((__excepts) !0 \ ? (__extension__ ({ __asm__ __volatile__ \ ("mtfsb0 %s0" \ : : "i#*X"(__builtin_ffs (__excepts))); \ 0; })) \ : 0) \ : (feclearexcept) (__excepts)) Does anyone know what that "weird" asm constraint actually means? (and where I should add support for it?) Thanks again, Hal -- Hal Finkel Postdoctoral Appointee Leadership Computing Facility Argonne National Laboratory
On Fri, 2012-04-27 at 14:54 -0500, Hal Finkel wrote:> There is a comment in the file which reads: > > /* The weird 'i#*X' constraints on the following suppress a gcc > warning when __excepts is not a constant. Otherwise, they mean the > same as just plain 'i'. */[sinp]> ("mtfsb0 %s0" : : "i#*X"(__builtin_ffs (__excepts)));[snip]> Does anyone know what that "weird" asm constraint actually means?The "i" and "X" constraints are documented here: http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Simple-Constraints.html `i' An immediate integer operand (one with constant value) is allowed. This includes symbolic constants whose values will be known only at assembly time or later. `X' Any operand whatsoever is allowed. The # and * constraint modifiers are documented here: http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Modifiers.html `#' Says that all following characters, up to the next comma, are to be ignored as a constraint. They are significant only for choosing register preferences. `*' Says that the following character should be ignored when choosing register preferences. `*' has no effect on the meaning of the constraint as a constraint, and no effect on reloading. For more info about PowerPC specific constraints, you'll want to look here: http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Machine-Constraints.html I'll note that the "s" in the %s0 means to only print the low 5 bits of operand 0. I think that may only be documented in the src: gcc/config/rs6000/rs6000.c:print_operand() Peter
Peter, Thanks! Do you happen to know where this needs to be changed in clang or LLVM. The code that actually interprets the constraints, generically, is in CodeGen/SelectionDAG/TargetLowering.cpp, is clang relying on that code, or is there some frontend code in clang itself that is failing to initially interpret the string? If it is the code in TargetLowering, then I don't see any support there for '*' or '#'. -Hal On Fri, 27 Apr 2012 19:33:58 -0500 Peter Bergner <bergner at vnet.ibm.com> wrote:> On Fri, 2012-04-27 at 14:54 -0500, Hal Finkel wrote: > > There is a comment in the file which reads: > > > > /* The weird 'i#*X' constraints on the following suppress a gcc > > warning when __excepts is not a constant. Otherwise, they mean > > the same as just plain 'i'. */ > [sinp] > > ("mtfsb0 %s0" : : "i#*X"(__builtin_ffs (__excepts))); > [snip] > > Does anyone know what that "weird" asm constraint actually means? > > > The "i" and "X" constraints are documented here: > > http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Simple-Constraints.html > > `i' > An immediate integer operand (one with constant value) is allowed. > This includes symbolic constants whose values will be known only > at assembly time or later. > > `X' > Any operand whatsoever is allowed. > > > The # and * constraint modifiers are documented here: > > http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Modifiers.html > > `#' > Says that all following characters, up to the next comma, are to > be ignored as a constraint. They are significant only for choosing > register preferences. > > `*' > Says that the following character should be ignored when choosing > register preferences. `*' has no effect on the meaning of the > constraint as a constraint, and no effect on reloading. > > For more info about PowerPC specific constraints, you'll want to look > here: > > http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Machine-Constraints.html > > > I'll note that the "s" in the %s0 means to only print the low 5 bits > of operand 0. I think that may only be documented in the src: > > gcc/config/rs6000/rs6000.c:print_operand() > > > Peter > > >-- Hal Finkel Postdoctoral Appointee Leadership Computing Facility Argonne National Laboratory
Peter, Could you please comment on: http://llvm.org/bugs/show_bug.cgi?id=12757 Specifically, gcc seems to allow this: int __flt_rounds() { unsigned long fpscr; __asm__ volatile("mffs %0" : "=f"(fpscr)); return fpscr; } My reading of this is that gcc allocates a floating-point register to hold the result of the mffs instruction, and then bit casts (and truncates?) the result into the unsigned long variable. Is this correct, and if so, is this a general gcc feature, or something PowerPC specific? Thanks again, Hal On Fri, 27 Apr 2012 19:33:58 -0500 Peter Bergner <bergner at vnet.ibm.com> wrote:> On Fri, 2012-04-27 at 14:54 -0500, Hal Finkel wrote: > > There is a comment in the file which reads: > > > > /* The weird 'i#*X' constraints on the following suppress a gcc > > warning when __excepts is not a constant. Otherwise, they mean > > the same as just plain 'i'. */ > [sinp] > > ("mtfsb0 %s0" : : "i#*X"(__builtin_ffs (__excepts))); > [snip] > > Does anyone know what that "weird" asm constraint actually means? > > > The "i" and "X" constraints are documented here: > > http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Simple-Constraints.html > > `i' > An immediate integer operand (one with constant value) is allowed. > This includes symbolic constants whose values will be known only > at assembly time or later. > > `X' > Any operand whatsoever is allowed. > > > The # and * constraint modifiers are documented here: > > http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Modifiers.html > > `#' > Says that all following characters, up to the next comma, are to > be ignored as a constraint. They are significant only for choosing > register preferences. > > `*' > Says that the following character should be ignored when choosing > register preferences. `*' has no effect on the meaning of the > constraint as a constraint, and no effect on reloading. > > For more info about PowerPC specific constraints, you'll want to look > here: > > http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Machine-Constraints.html > > > I'll note that the "s" in the %s0 means to only print the low 5 bits > of operand 0. I think that may only be documented in the src: > > gcc/config/rs6000/rs6000.c:print_operand() > > > Peter > > >-- Hal Finkel Postdoctoral Appointee Leadership Computing Facility Argonne National Laboratory